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++) {
/* 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);
{ "\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;
}
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)),