]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
liblib: Added str_unescape_next()
authorTimo Sirainen <tss@iki.fi>
Wed, 15 Jan 2014 21:44:04 +0000 (16:44 -0500)
committerTimo Sirainen <tss@iki.fi>
Wed, 15 Jan 2014 21:44:04 +0000 (16:44 -0500)
src/lib/strescape.c
src/lib/strescape.h
src/lib/test-strescape.c

index 7763c9c83e15e665e22a64d7212291e410736542..499b48c454ed77320e43e91c0777db429702f181 100644 (file)
@@ -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++) {
index a878318f2ee027c1566fe2704c1ce2bd93a14e11..9569b94fd45e560311cae5b9a4ba77c12bd4f314 100644 (file)
@@ -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);
index 080bf6afa049d47701ce730a1695e495d2971355..4f0132af9f68e6244cc751640b62472060b18096 100644 (file)
@@ -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)),