]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: Optimize str_append_tabescaped_n()
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Thu, 11 Mar 2021 23:23:04 +0000 (01:23 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Tue, 21 Sep 2021 07:12:53 +0000 (07:12 +0000)
src/lib/strescape.c
src/lib/test-strescape.c

index 99894651ca90025e50ee7abca56cf72ab0d3f4b4..73489cad8457306a584661644f9c364c651a79e1 100644 (file)
@@ -103,33 +103,34 @@ int str_unescape_next(const char **str, const char **unescaped_r)
 
 void str_append_tabescaped_n(string_t *dest, const unsigned char *src, size_t src_size)
 {
+       size_t prev_pos = 0;
+       char esc[2] = { '\001', '\0' };
+
        for (size_t i = 0; i < src_size; i++) {
                switch (src[i]) {
                case '\000':
-                       str_append_c(dest, '\001');
-                       str_append_c(dest, '0');
+                       esc[1] = '0';
                        break;
                case '\001':
-                       str_append_c(dest, '\001');
-                       str_append_c(dest, '1');
+                       esc[1] = '1';
                        break;
                case '\t':
-                       str_append_c(dest, '\001');
-                       str_append_c(dest, 't');
+                       esc[1] = 't';
                        break;
                case '\r':
-                       str_append_c(dest, '\001');
-                       str_append_c(dest, 'r');
+                       esc[1] = 'r';
                        break;
                case '\n':
-                       str_append_c(dest, '\001');
-                       str_append_c(dest, 'n');
+                       esc[1] = 'n';
                        break;
                default:
-                       str_append_c(dest, src[i]);
-                       break;
+                       continue;
                }
+               str_append_data(dest, src + prev_pos, i - prev_pos);
+               str_append_data(dest, esc, 2);
+               prev_pos = i + 1;
        }
+       str_append_data(dest, src + prev_pos, src_size - prev_pos);
 }
 
 void str_append_tabescaped(string_t *dest, const char *src)
index b918062d1d817f398497b068cb9e94ae0d8c50d7..5b1323200a6f8b9008c46026d33da309aec6f714 100644 (file)
@@ -10,6 +10,7 @@ struct strinput {
 };
 
 static const char tabescaped_input[] = "\0011\001t\001r\001nplip\001n";
+static const char tabescaped_input_with_nul[] = "\0011\001t\001r\001nplip\001n\0010";
 static const char tabunescaped_input[] = "\001\t\r\nplip\n";
 
 static const char *wrong_tabescaped_input = "a\001\001b\001\nc\0011\001t\001r\001nplip\001n";
@@ -133,6 +134,12 @@ static void test_tabescape(void)
        str_append_tabescaped(str, tabunescaped_input);
        test_assert(strcmp(str_c(str), tabescaped_input) == 0);
 
+       /* test escaping the trailing NUL as well */
+       str_truncate(str, 0);
+       str_append_tabescaped_n(str, (const unsigned char *)tabunescaped_input,
+                               strlen(tabunescaped_input)+1);
+       test_assert_strcmp(str_c(str), tabescaped_input_with_nul);
+
        /* unescaping */
        str_truncate(str, 0);
        str_append_tabunescaped(str, tabescaped_input, strlen(tabescaped_input));