"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/lib/strescape.c" between
dovecot-2.3.16.tar.gz and dovecot-2.3.17.tar.gz

About: Dovecot is an IMAP and POP3 server, written with security primarily in mind.

strescape.c  (dovecot-2.3.16):strescape.c  (dovecot-2.3.17)
skipping to change at line 106 skipping to change at line 106
if (*p != '"') if (*p != '"')
return -1; return -1;
escaped = p_strdup_until(unsafe_data_stack_pool, *str, p); escaped = p_strdup_until(unsafe_data_stack_pool, *str, p);
*str = p+1; *str = p+1;
*unescaped_r = !esc_found ? escaped : str_unescape(escaped); *unescaped_r = !esc_found ? escaped : str_unescape(escaped);
return 0; return 0;
} }
void str_append_tabescaped_n(string_t *dest, const unsigned char *src, size_t sr c_size) void str_append_tabescaped_n(string_t *dest, const unsigned char *src, size_t sr c_size)
{ {
size_t prev_pos = 0;
char esc[2] = { '\001', '\0' };
for (size_t i = 0; i < src_size; i++) { for (size_t i = 0; i < src_size; i++) {
switch (src[i]) { switch (src[i]) {
case '\000': case '\000':
str_append_c(dest, '\001'); esc[1] = '0';
str_append_c(dest, '0');
break; break;
case '\001': case '\001':
str_append_c(dest, '\001'); esc[1] = '1';
str_append_c(dest, '1');
break; break;
case '\t': case '\t':
str_append_c(dest, '\001'); esc[1] = 't';
str_append_c(dest, 't');
break; break;
case '\r': case '\r':
str_append_c(dest, '\001'); esc[1] = 'r';
str_append_c(dest, 'r');
break; break;
case '\n': case '\n':
str_append_c(dest, '\001'); esc[1] = 'n';
str_append_c(dest, 'n');
break; break;
default: default:
str_append_c(dest, src[i]); continue;
break;
} }
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) void str_append_tabescaped(string_t *dest, const char *src)
{ {
str_append_tabescaped_n(dest, (const unsigned char*)src, strlen(src)); size_t pos, prev_pos = 0;
char esc[2] = { '\001', '\0' };
for (;;) {
pos = prev_pos + strcspn(src + prev_pos, "\001\t\r\n");
str_append_data(dest, src + prev_pos, pos - prev_pos);
prev_pos = pos + 1;
switch (src[pos]) {
case '\000':
/* end of src string reached */
return;
case '\001':
esc[1] = '1';
break;
case '\t':
esc[1] = 't';
break;
case '\r':
esc[1] = 'r';
break;
case '\n':
esc[1] = 'n';
break;
default:
i_unreached();
}
str_append_data(dest, esc, 2);
}
} }
const char *str_tabescape(const char *str) const char *str_tabescape(const char *str)
{ {
string_t *tmp; string_t *tmp;
const char *p; const char *p;
for (p = str; *p != '\0'; p++) { if ((p = strpbrk(str, "\001\t\r\n")) != NULL) {
if (*p <= '\r') { tmp = t_str_new(128);
tmp = t_str_new(128); str_append_data(tmp, str, p-str);
str_append_data(tmp, str, p-str); str_append_tabescaped(tmp, p);
str_append_tabescaped(tmp, p); return str_c(tmp);
return str_c(tmp);
}
} }
return str; return str;
} }
void str_append_tabunescaped(string_t *dest, const void *src, size_t src_size) void str_append_tabunescaped(string_t *dest, const void *src, size_t src_size)
{ {
const unsigned char *src_c = src; const unsigned char *src_c = src;
size_t start = 0, i = 0; size_t start = 0, i = 0;
while (i < src_size) { while (i < src_size) {
skipping to change at line 199 skipping to change at line 226
str_append_c(dest, src_c[i]); str_append_c(dest, src_c[i]);
break; break;
} }
i++; i++;
} }
} }
start = i; start = i;
} }
} }
char *str_tabunescape(char *str) static char *str_tabunescape_from(char *str, char *src)
{ {
/* @UNSAFE */ /* @UNSAFE */
char *dest, *start = str; char *dest, *p;
str = strchr(str, '\001'); dest = src;
if (str == NULL) { for (;;) {
/* no unescaping needed */ switch (src[1]) {
return start; case '\0':
} /* truncated input */
*dest = '\0';
return str;
case '0':
*dest++ = '\000';
break;
case '1':
*dest++ = '\001';
break;
case 't':
*dest++ = '\t';
break;
case 'r':
*dest++ = '\r';
break;
case 'n':
*dest++ = '\n';
break;
default:
*dest++ = src[1];
break;
}
src += 2;
for (dest = str; *str != '\0'; str++) { p = strchr(src, '\001');
if (*str != '\001') if (p == NULL) {
*dest++ = *str; memmove(dest, src, strlen(src)+1);
else { break;
str++;
if (*str == '\0')
break;
switch (*str) {
case '0':
*dest++ = '\000';
break;
case '1':
*dest++ = '\001';
break;
case 't':
*dest++ = '\t';
break;
case 'r':
*dest++ = '\r';
break;
case 'n':
*dest++ = '\n';
break;
default:
*dest++ = *str;
break;
}
} }
size_t copy_len = p - src;
memmove(dest, src, copy_len);
dest += copy_len;
src = p;
} }
return str;
}
*dest = '\0'; char *str_tabunescape(char *str)
return start; {
char *src = strchr(str, '\001');
if (src == NULL) {
/* no unescaping needed */
return str;
}
return str_tabunescape_from(str, src);
} }
const char *t_str_tabunescape(const char *str) const char *t_str_tabunescape(const char *str)
{ {
if (strchr(str, '\001') == NULL) const char *p;
p = strchr(str, '\001');
if (p == NULL)
return str; return str;
else
return str_tabunescape(t_strdup_noconst(str)); char *dest = t_strdup_noconst(str);
return str_tabunescape_from(dest, dest + (p - str));
} }
const char *const *t_strsplit_tabescaped_inplace(char *data) static char **p_strsplit_tabescaped_inplace(pool_t pool, char *data)
{ {
/* @UNSAFE */ /* @UNSAFE */
char **array; char **array;
unsigned int count, new_alloc_count, alloc_count; unsigned int count, new_alloc_count, alloc_count;
if (*data == '\0') if (*data == '\0')
return t_new(const char *, 1); return p_new(pool, char *, 1);
alloc_count = 32; alloc_count = 32;
array = t_malloc_no0(sizeof(char *) * alloc_count); array = pool == unsafe_data_stack_pool ?
t_malloc_no0(sizeof(char *) * alloc_count) :
p_malloc(pool, sizeof(char *) * alloc_count);
array[0] = data; count = 1; array[0] = data; count = 1;
bool need_unescape = FALSE; char *need_unescape = NULL;
while ((data = strpbrk(data, "\t\001")) != NULL) { while ((data = strpbrk(data, "\t\001")) != NULL) {
/* separator or escape char found */ /* separator or escape char found */
if (*data == '\001') { if (*data == '\001') {
need_unescape = TRUE; if (need_unescape == NULL)
need_unescape = data;
data++; data++;
continue; continue;
} }
if (count+1 >= alloc_count) { if (count+1 >= alloc_count) {
new_alloc_count = nearest_power(alloc_count+1); new_alloc_count = nearest_power(alloc_count+1);
array = p_realloc(unsafe_data_stack_pool, array, array = p_realloc(pool, array,
sizeof(char *) * alloc_count, sizeof(char *) * alloc_count,
sizeof(char *) * sizeof(char *) *
new_alloc_count); new_alloc_count);
alloc_count = new_alloc_count; alloc_count = new_alloc_count;
} }
*data++ = '\0'; *data++ = '\0';
if (need_unescape) { if (need_unescape != NULL) {
str_tabunescape(array[count-1]); str_tabunescape_from(array[count-1], need_unescape);
need_unescape = FALSE; need_unescape = NULL;
} }
array[count++] = data; array[count++] = data;
} }
if (need_unescape) if (need_unescape != NULL)
str_tabunescape(array[count-1]); str_tabunescape_from(array[count-1], need_unescape);
i_assert(count < alloc_count); i_assert(count < alloc_count);
array[count] = NULL; array[count] = NULL;
return (const char *const *)array; return array;
} }
char **p_strsplit_tabescaped(pool_t pool, const char *str) const char *const *t_strsplit_tabescaped_inplace(char *data)
{ {
char **args; char *const *escaped =
unsigned int i; p_strsplit_tabescaped_inplace(unsafe_data_stack_pool, data);
return (const char *const *)escaped;
}
args = p_strsplit(pool, str, "\t"); char **p_strsplit_tabescaped(pool_t pool, const char *str)
for (i = 0; args[i] != NULL; i++) {
args[i] = str_tabunescape(args[i]); return p_strsplit_tabescaped_inplace(pool, p_strdup(pool, str));
return args;
} }
const char *const *t_strsplit_tabescaped(const char *str) const char *const *t_strsplit_tabescaped(const char *str)
{ {
return (void *)p_strsplit_tabescaped(unsafe_data_stack_pool, str); return t_strsplit_tabescaped_inplace(t_strdup_noconst(str));
} }
 End of changes. 33 change blocks. 
79 lines changed or deleted 126 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)