Mercurial > dovecot > core-2.2
changeset 17112:9735c6fb7e39
liblib: Added str_unescape_next()
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 15 Jan 2014 16:44:04 -0500 |
parents | bdec18a1aa40 |
children | a217a938f9ae |
files | src/lib/strescape.c src/lib/strescape.h src/lib/test-strescape.c |
diffstat | 3 files changed, 41 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib/strescape.c Wed Jan 15 15:57:50 2014 -0500 +++ b/src/lib/strescape.c Wed Jan 15 16:44:04 2014 -0500 @@ -77,6 +77,30 @@ 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++) {
--- a/src/lib/strescape.h Wed Jan 15 15:57:50 2014 -0500 +++ b/src/lib/strescape.h Wed Jan 15 16:44:04 2014 -0500 @@ -12,6 +12,11 @@ /* 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);
--- a/src/lib/test-strescape.c Wed Jan 15 15:57:50 2014 -0500 +++ b/src/lib/test-strescape.c Wed Jan 15 16:44:04 2014 -0500 @@ -25,7 +25,7 @@ { "\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 @@ } 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)),