From: Timo Sirainen Date: Wed, 15 Jan 2014 21:44:04 +0000 (-0500) Subject: liblib: Added str_unescape_next() X-Git-Tag: 2.2.11~29 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6b35ba747072480bfc86ed7cc69df1d418e2ae20;p=thirdparty%2Fdovecot%2Fcore.git liblib: Added str_unescape_next() --- diff --git a/src/lib/strescape.c b/src/lib/strescape.c index 7763c9c83e..499b48c454 100644 --- a/src/lib/strescape.c +++ b/src/lib/strescape.c @@ -77,6 +77,30 @@ char *str_unescape(char *str) return start; } +int str_unescape_next(const char **str, const char **unescaped_r) +{ + const char *p; + char *escaped; + bool esc_found = FALSE; + + for (p = *str; *p != '\0'; p++) { + if (*p == '"') + break; + else if (*p == '\\') { + if (p[1] == '\0') + return -1; + esc_found = TRUE; + p++; + } + } + if (*p != '"') + return -1; + escaped = p_strdup_until(unsafe_data_stack_pool, *str, p); + *str = p+1; + *unescaped_r = !esc_found ? escaped : str_unescape(escaped); + return 0; +} + void str_append_tabescaped(string_t *dest, const char *src) { for (; *src != '\0'; src++) { diff --git a/src/lib/strescape.h b/src/lib/strescape.h index a878318f2e..9569b94fd4 100644 --- a/src/lib/strescape.h +++ b/src/lib/strescape.h @@ -12,6 +12,11 @@ void str_append_unescaped(string_t *dest, const void *src, size_t src_size); /* remove all '\' characters */ char *str_unescape(char *str); +/* Remove all '\' chars from str until '"' is reached and return the unescaped + string. *str is updated to point to the character after the '"'. Returns 0 + if ok, -1 if '"' wasn't found. */ +int str_unescape_next(const char **str, const char **unescaped_r); + /* For Dovecot's internal protocols: Escape \001, \t, \r and \n characters using \001. */ const char *str_tabescape(const char *str); diff --git a/src/lib/test-strescape.c b/src/lib/test-strescape.c index 080bf6afa0..4f0132af9f 100644 --- a/src/lib/test-strescape.c +++ b/src/lib/test-strescape.c @@ -25,7 +25,7 @@ void test_strescape(void) { "\001\001\t\t\r\r\n\n", "\0011\0011\001t\001t\001r\001r\001n\001n" } }; unsigned char buf[1 << CHAR_BIT]; - const char *escaped, *tabstr; + const char *escaped, *tabstr, *unesc_str; string_t *str; unsigned int i; @@ -57,6 +57,17 @@ void test_strescape(void) } test_end(); + test_begin("str_unescape_next"); + escaped = "foo\"bar\\\"b\\\\az\"plop"; + test_assert(str_unescape_next(&escaped, &unesc_str) == 0); + test_assert(strcmp(unesc_str, "foo") == 0); + test_assert(str_unescape_next(&escaped, &unesc_str) == 0); + test_assert(strcmp(unesc_str, "bar\"b\\az") == 0); + test_assert(str_unescape_next(&escaped, &unesc_str) == -1); + escaped = "foo\\"; + test_assert(str_unescape_next(&escaped, &unesc_str) == -1); + test_end(); + test_begin("str_tabescape"); for (i = 0; i < N_ELEMENTS(tabesc); i++) { test_assert(strcmp(str_tabunescape(t_strdup_noconst(tabesc[i].output)),