From: Timo Sirainen Date: Thu, 11 Mar 2021 23:23:04 +0000 (+0200) Subject: lib: Optimize str_append_tabescaped_n() X-Git-Tag: 2.3.17~100 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1abeccbecaa45898b1e0d3676c974fe8b6ef5727;p=thirdparty%2Fdovecot%2Fcore.git lib: Optimize str_append_tabescaped_n() --- diff --git a/src/lib/strescape.c b/src/lib/strescape.c index 99894651ca..73489cad84 100644 --- a/src/lib/strescape.c +++ b/src/lib/strescape.c @@ -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) diff --git a/src/lib/test-strescape.c b/src/lib/test-strescape.c index b918062d1d..5b1323200a 100644 --- a/src/lib/test-strescape.c +++ b/src/lib/test-strescape.c @@ -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));