annotate src/lib/strescape.c @ 22636:96e51a11c0aa

lib: Implement t_strsplit_tabescaped_inplace() This is a more efficient version of t_strsplit_tabescaped(), which modifies the input string instead of duplicating it.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Sat, 04 Nov 2017 01:39:38 +0200
parents 82d8656bb3ad
children cb108f786fb4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
21390
2e2563132d5f Updated copyright notices to include the year 2017.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 20600
diff changeset
1 /* Copyright (c) 2003-2017 Dovecot authors, see the included COPYING file */
896
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "lib.h"
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
4 #include "str.h"
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
5 #include "strescape.h"
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
6
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
7 const char *str_escape(const char *str)
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
8 {
1329
ae229b7acb4c Mailbox names are now sent through imap-quoter instead of just escaping it.
Timo Sirainen <tss@iki.fi>
parents: 1216
diff changeset
9 const char *p;
ae229b7acb4c Mailbox names are now sent through imap-quoter instead of just escaping it.
Timo Sirainen <tss@iki.fi>
parents: 1216
diff changeset
10 string_t *ret;
896
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
11
1329
ae229b7acb4c Mailbox names are now sent through imap-quoter instead of just escaping it.
Timo Sirainen <tss@iki.fi>
parents: 1216
diff changeset
12 /* see if we need to quote it */
ae229b7acb4c Mailbox names are now sent through imap-quoter instead of just escaping it.
Timo Sirainen <tss@iki.fi>
parents: 1216
diff changeset
13 for (p = str; *p != '\0'; p++) {
ae229b7acb4c Mailbox names are now sent through imap-quoter instead of just escaping it.
Timo Sirainen <tss@iki.fi>
parents: 1216
diff changeset
14 if (IS_ESCAPED_CHAR(*p))
ae229b7acb4c Mailbox names are now sent through imap-quoter instead of just escaping it.
Timo Sirainen <tss@iki.fi>
parents: 1216
diff changeset
15 break;
896
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
16 }
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
17
1329
ae229b7acb4c Mailbox names are now sent through imap-quoter instead of just escaping it.
Timo Sirainen <tss@iki.fi>
parents: 1216
diff changeset
18 if (*p == '\0')
896
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
19 return str;
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
20
1329
ae229b7acb4c Mailbox names are now sent through imap-quoter instead of just escaping it.
Timo Sirainen <tss@iki.fi>
parents: 1216
diff changeset
21 /* quote */
ae229b7acb4c Mailbox names are now sent through imap-quoter instead of just escaping it.
Timo Sirainen <tss@iki.fi>
parents: 1216
diff changeset
22 ret = t_str_new((size_t) (p - str) + 128);
ae229b7acb4c Mailbox names are now sent through imap-quoter instead of just escaping it.
Timo Sirainen <tss@iki.fi>
parents: 1216
diff changeset
23 str_append_n(ret, str, (size_t) (p - str));
ae229b7acb4c Mailbox names are now sent through imap-quoter instead of just escaping it.
Timo Sirainen <tss@iki.fi>
parents: 1216
diff changeset
24
ae229b7acb4c Mailbox names are now sent through imap-quoter instead of just escaping it.
Timo Sirainen <tss@iki.fi>
parents: 1216
diff changeset
25 for (; *p != '\0'; p++) {
ae229b7acb4c Mailbox names are now sent through imap-quoter instead of just escaping it.
Timo Sirainen <tss@iki.fi>
parents: 1216
diff changeset
26 if (IS_ESCAPED_CHAR(*p))
ae229b7acb4c Mailbox names are now sent through imap-quoter instead of just escaping it.
Timo Sirainen <tss@iki.fi>
parents: 1216
diff changeset
27 str_append_c(ret, '\\');
ae229b7acb4c Mailbox names are now sent through imap-quoter instead of just escaping it.
Timo Sirainen <tss@iki.fi>
parents: 1216
diff changeset
28 str_append_c(ret, *p);
896
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
29 }
1329
ae229b7acb4c Mailbox names are now sent through imap-quoter instead of just escaping it.
Timo Sirainen <tss@iki.fi>
parents: 1216
diff changeset
30 return str_c(ret);
896
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
31 }
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
32
903
fd8888f6f037 Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents: 898
diff changeset
33 void str_append_unescaped(string_t *dest, const void *src, size_t src_size)
896
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
34 {
898
0d5be52d7131 Use unsigned char* when accessing non-NUL terminating strings. Compiler
Timo Sirainen <tss@iki.fi>
parents: 896
diff changeset
35 const unsigned char *src_c = src;
896
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
36 size_t start = 0, i = 0;
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
37
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
38 while (i < src_size) {
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
39 for (; i < src_size; i++) {
898
0d5be52d7131 Use unsigned char* when accessing non-NUL terminating strings. Compiler
Timo Sirainen <tss@iki.fi>
parents: 896
diff changeset
40 if (src_c[i] == '\\')
896
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
41 break;
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
42 }
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
43
898
0d5be52d7131 Use unsigned char* when accessing non-NUL terminating strings. Compiler
Timo Sirainen <tss@iki.fi>
parents: 896
diff changeset
44 str_append_n(dest, src_c + start, i-start);
896
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
45
9483
464116e1d0ae str_append_unescaped() didn't unescape \\ correctly.
Timo Sirainen <tss@iki.fi>
parents: 9232
diff changeset
46 if (i < src_size) {
464116e1d0ae str_append_unescaped() didn't unescape \\ correctly.
Timo Sirainen <tss@iki.fi>
parents: 9232
diff changeset
47 if (++i == src_size)
464116e1d0ae str_append_unescaped() didn't unescape \\ correctly.
Timo Sirainen <tss@iki.fi>
parents: 9232
diff changeset
48 break;
464116e1d0ae str_append_unescaped() didn't unescape \\ correctly.
Timo Sirainen <tss@iki.fi>
parents: 9232
diff changeset
49 str_append_c(dest, src_c[i++]);
464116e1d0ae str_append_unescaped() didn't unescape \\ correctly.
Timo Sirainen <tss@iki.fi>
parents: 9232
diff changeset
50 }
896
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
51 start = i;
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
52 }
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
53 }
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
54
1216
3784730cfcd8 str_unescape(): return char*
Timo Sirainen <tss@iki.fi>
parents: 903
diff changeset
55 char *str_unescape(char *str)
896
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
56 {
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
57 /* @UNSAFE */
1216
3784730cfcd8 str_unescape(): return char*
Timo Sirainen <tss@iki.fi>
parents: 903
diff changeset
58 char *dest, *start = str;
896
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
59
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
60 while (*str != '\\') {
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
61 if (*str == '\0')
1216
3784730cfcd8 str_unescape(): return char*
Timo Sirainen <tss@iki.fi>
parents: 903
diff changeset
62 return start;
896
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
63 str++;
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
64 }
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
65
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
66 for (dest = str; *str != '\0'; str++) {
9484
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
67 if (*str == '\\') {
1651
43fdcf8d9a0d unescaping was broken
Timo Sirainen <tss@iki.fi>
parents: 1329
diff changeset
68 str++;
9484
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
69 if (*str == '\0')
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
70 break;
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
71 }
1651
43fdcf8d9a0d unescaping was broken
Timo Sirainen <tss@iki.fi>
parents: 1329
diff changeset
72
43fdcf8d9a0d unescaping was broken
Timo Sirainen <tss@iki.fi>
parents: 1329
diff changeset
73 *dest++ = *str;
896
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
74 }
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
75
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
76 *dest = '\0';
1216
3784730cfcd8 str_unescape(): return char*
Timo Sirainen <tss@iki.fi>
parents: 903
diff changeset
77 return start;
896
21ffcce83c70 Rewrote rfc822-tokenize.c to work one token at a time so it won't uselessly
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
78 }
9232
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
79
17112
9735c6fb7e39 liblib: Added str_unescape_next()
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
80 int str_unescape_next(const char **str, const char **unescaped_r)
9735c6fb7e39 liblib: Added str_unescape_next()
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
81 {
9735c6fb7e39 liblib: Added str_unescape_next()
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
82 const char *p;
9735c6fb7e39 liblib: Added str_unescape_next()
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
83 char *escaped;
9735c6fb7e39 liblib: Added str_unescape_next()
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
84 bool esc_found = FALSE;
9735c6fb7e39 liblib: Added str_unescape_next()
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
85
9735c6fb7e39 liblib: Added str_unescape_next()
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
86 for (p = *str; *p != '\0'; p++) {
9735c6fb7e39 liblib: Added str_unescape_next()
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
87 if (*p == '"')
9735c6fb7e39 liblib: Added str_unescape_next()
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
88 break;
9735c6fb7e39 liblib: Added str_unescape_next()
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
89 else if (*p == '\\') {
9735c6fb7e39 liblib: Added str_unescape_next()
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
90 if (p[1] == '\0')
9735c6fb7e39 liblib: Added str_unescape_next()
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
91 return -1;
9735c6fb7e39 liblib: Added str_unescape_next()
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
92 esc_found = TRUE;
9735c6fb7e39 liblib: Added str_unescape_next()
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
93 p++;
9735c6fb7e39 liblib: Added str_unescape_next()
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
94 }
9735c6fb7e39 liblib: Added str_unescape_next()
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
95 }
9735c6fb7e39 liblib: Added str_unescape_next()
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
96 if (*p != '"')
9735c6fb7e39 liblib: Added str_unescape_next()
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
97 return -1;
9735c6fb7e39 liblib: Added str_unescape_next()
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
98 escaped = p_strdup_until(unsafe_data_stack_pool, *str, p);
9735c6fb7e39 liblib: Added str_unescape_next()
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
99 *str = p+1;
9735c6fb7e39 liblib: Added str_unescape_next()
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
100 *unescaped_r = !esc_found ? escaped : str_unescape(escaped);
9735c6fb7e39 liblib: Added str_unescape_next()
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
101 return 0;
9735c6fb7e39 liblib: Added str_unescape_next()
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
102 }
9735c6fb7e39 liblib: Added str_unescape_next()
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
103
20600
9af7c7196540 lib: Add binary-safe tabescape
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20339
diff changeset
104 void str_append_tabescaped_n(string_t *dest, const unsigned char *src, size_t src_size)
9232
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
105 {
20600
9af7c7196540 lib: Add binary-safe tabescape
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20339
diff changeset
106 for (size_t i = 0; i < src_size; i++) {
9af7c7196540 lib: Add binary-safe tabescape
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20339
diff changeset
107 switch (src[i]) {
9af7c7196540 lib: Add binary-safe tabescape
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20339
diff changeset
108 case '\000':
9af7c7196540 lib: Add binary-safe tabescape
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20339
diff changeset
109 str_append_c(dest, '\001');
9af7c7196540 lib: Add binary-safe tabescape
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20339
diff changeset
110 str_append_c(dest, '0');
9af7c7196540 lib: Add binary-safe tabescape
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20339
diff changeset
111 break;
9232
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
112 case '\001':
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
113 str_append_c(dest, '\001');
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
114 str_append_c(dest, '1');
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
115 break;
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
116 case '\t':
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
117 str_append_c(dest, '\001');
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
118 str_append_c(dest, 't');
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
119 break;
9484
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
120 case '\r':
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
121 str_append_c(dest, '\001');
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
122 str_append_c(dest, 'r');
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
123 break;
9232
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
124 case '\n':
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
125 str_append_c(dest, '\001');
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
126 str_append_c(dest, 'n');
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
127 break;
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
128 default:
20600
9af7c7196540 lib: Add binary-safe tabescape
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20339
diff changeset
129 str_append_c(dest, src[i]);
9232
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
130 break;
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
131 }
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
132 }
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
133 }
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
134
20600
9af7c7196540 lib: Add binary-safe tabescape
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20339
diff changeset
135 void str_append_tabescaped(string_t *dest, const char *src) {
9af7c7196540 lib: Add binary-safe tabescape
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20339
diff changeset
136 str_append_tabescaped_n(dest, (const unsigned char*)src, strlen(src));
9af7c7196540 lib: Add binary-safe tabescape
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20339
diff changeset
137 }
9af7c7196540 lib: Add binary-safe tabescape
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20339
diff changeset
138
9af7c7196540 lib: Add binary-safe tabescape
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20339
diff changeset
139
9232
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
140 const char *str_tabescape(const char *str)
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
141 {
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
142 string_t *tmp;
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
143 const char *p;
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
144
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
145 for (p = str; *p != '\0'; p++) {
9484
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
146 if (*p <= '\r') {
9232
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
147 tmp = t_str_new(128);
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
148 str_append_n(tmp, str, p-str);
15068
002e0a120c2a Renamed str_tabescape_write() to str_append_tabescaped()
Timo Sirainen <tss@iki.fi>
parents: 14133
diff changeset
149 str_append_tabescaped(tmp, p);
9232
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
150 return str_c(tmp);
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
151 }
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
152 }
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
153 return str;
2dcf2f313329 Added str_tabescape*() to write escaped strings to Dovecot's IPC protocols.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
154 }
9484
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
155
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
156 void str_append_tabunescaped(string_t *dest, const void *src, size_t src_size)
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
157 {
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
158 const unsigned char *src_c = src;
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
159 size_t start = 0, i = 0;
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
160
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
161 while (i < src_size) {
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
162 for (; i < src_size; i++) {
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
163 if (src_c[i] == '\001')
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
164 break;
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
165 }
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
166
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
167 str_append_n(dest, src_c + start, i-start);
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
168
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
169 if (i < src_size) {
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
170 i++;
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
171 if (i < src_size) {
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
172 switch (src_c[i]) {
20600
9af7c7196540 lib: Add binary-safe tabescape
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20339
diff changeset
173 case '0':
9af7c7196540 lib: Add binary-safe tabescape
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20339
diff changeset
174 str_append_c(dest, '\000');
9af7c7196540 lib: Add binary-safe tabescape
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20339
diff changeset
175 break;
9484
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
176 case '1':
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
177 str_append_c(dest, '\001');
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
178 break;
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
179 case 't':
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
180 str_append_c(dest, '\t');
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
181 break;
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
182 case 'r':
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
183 str_append_c(dest, '\r');
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
184 break;
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
185 case 'n':
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
186 str_append_c(dest, '\n');
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
187 break;
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
188 default:
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
189 str_append_c(dest, src_c[i]);
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
190 break;
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
191 }
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
192 i++;
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
193 }
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
194 }
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
195 start = i;
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
196 }
5a6fe52a0cfc Added str_append_tabunescaped(). str_tabescape*() now escapes also CR. Added unit tests.
Timo Sirainen <tss@iki.fi>
parents: 9483
diff changeset
197 }
9516
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
198
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
199 char *str_tabunescape(char *str)
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
200 {
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
201 /* @UNSAFE */
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
202 char *dest, *start = str;
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
203
22634
bac4edd0ee25 lib: str_tabunescape() - optimize initial escape char lookup
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
204 str = strchr(str, '\001');
bac4edd0ee25 lib: str_tabunescape() - optimize initial escape char lookup
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
205 if (str == NULL) {
bac4edd0ee25 lib: str_tabunescape() - optimize initial escape char lookup
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
206 /* no unescaping needed */
bac4edd0ee25 lib: str_tabunescape() - optimize initial escape char lookup
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
207 return start;
9516
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
208 }
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
209
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
210 for (dest = str; *str != '\0'; str++) {
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
211 if (*str != '\001')
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
212 *dest++ = *str;
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
213 else {
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
214 str++;
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
215 if (*str == '\0')
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
216 break;
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
217 switch (*str) {
20600
9af7c7196540 lib: Add binary-safe tabescape
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20339
diff changeset
218 case '0':
9af7c7196540 lib: Add binary-safe tabescape
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20339
diff changeset
219 *dest++ = '\000';
9af7c7196540 lib: Add binary-safe tabescape
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20339
diff changeset
220 break;
9516
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
221 case '1':
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
222 *dest++ = '\001';
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
223 break;
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
224 case 't':
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
225 *dest++ = '\t';
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
226 break;
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
227 case 'r':
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
228 *dest++ = '\r';
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
229 break;
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
230 case 'n':
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
231 *dest++ = '\n';
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
232 break;
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
233 default:
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
234 *dest++ = *str;
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
235 break;
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
236 }
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
237 }
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
238 }
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
239
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
240 *dest = '\0';
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
241 return start;
aad42b172e1a Added str_tabunescape().
Timo Sirainen <tss@iki.fi>
parents: 9484
diff changeset
242 }
13083
e07d2e37053d liblib: Added [tp]_strsplit_tabescaped()
Timo Sirainen <tss@iki.fi>
parents: 12782
diff changeset
243
20339
327fcf6d2205 lib: Added t_str_tabunescape()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
244 const char *t_str_tabunescape(const char *str)
327fcf6d2205 lib: Added t_str_tabunescape()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
245 {
327fcf6d2205 lib: Added t_str_tabunescape()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
246 if (strchr(str, '\001') == NULL)
327fcf6d2205 lib: Added t_str_tabunescape()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
247 return str;
327fcf6d2205 lib: Added t_str_tabunescape()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
248 else
327fcf6d2205 lib: Added t_str_tabunescape()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
249 return str_tabunescape(t_strdup_noconst(str));
327fcf6d2205 lib: Added t_str_tabunescape()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
250 }
327fcf6d2205 lib: Added t_str_tabunescape()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
251
22636
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
252 const char *const *t_strsplit_tabescaped_inplace(char *data)
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
253 {
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
254 /* @UNSAFE */
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
255 char **array;
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
256 unsigned int count, new_alloc_count, alloc_count;
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
257
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
258 if (*data == '\0')
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
259 return t_new(const char *, 1);
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
260
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
261 alloc_count = 32;
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
262 array = t_malloc(sizeof(char *) * alloc_count);
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
263
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
264 array[0] = data; count = 1;
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
265 bool need_unescape = FALSE;
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
266 while ((data = strpbrk(data, "\t\001")) != NULL) {
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
267 /* separator or escape char found */
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
268 if (*data == '\001') {
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
269 need_unescape = TRUE;
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
270 data++;
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
271 continue;
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
272 }
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
273 if (count+1 >= alloc_count) {
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
274 new_alloc_count = nearest_power(alloc_count+1);
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
275 array = p_realloc(unsafe_data_stack_pool, array,
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
276 sizeof(char *) * alloc_count,
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
277 sizeof(char *) *
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
278 new_alloc_count);
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
279 alloc_count = new_alloc_count;
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
280 }
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
281 *data++ = '\0';
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
282 if (need_unescape) {
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
283 str_tabunescape(array[count-1]);
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
284 need_unescape = FALSE;
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
285 }
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
286 array[count++] = data;
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
287 }
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
288 if (need_unescape)
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
289 str_tabunescape(array[count-1]);
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
290 i_assert(count < alloc_count);
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
291 array[count] = NULL;
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
292
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
293 return (const char *const *)array;
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
294 }
96e51a11c0aa lib: Implement t_strsplit_tabescaped_inplace()
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22635
diff changeset
295
13083
e07d2e37053d liblib: Added [tp]_strsplit_tabescaped()
Timo Sirainen <tss@iki.fi>
parents: 12782
diff changeset
296 char **p_strsplit_tabescaped(pool_t pool, const char *str)
e07d2e37053d liblib: Added [tp]_strsplit_tabescaped()
Timo Sirainen <tss@iki.fi>
parents: 12782
diff changeset
297 {
e07d2e37053d liblib: Added [tp]_strsplit_tabescaped()
Timo Sirainen <tss@iki.fi>
parents: 12782
diff changeset
298 char **args;
e07d2e37053d liblib: Added [tp]_strsplit_tabescaped()
Timo Sirainen <tss@iki.fi>
parents: 12782
diff changeset
299 unsigned int i;
e07d2e37053d liblib: Added [tp]_strsplit_tabescaped()
Timo Sirainen <tss@iki.fi>
parents: 12782
diff changeset
300
e07d2e37053d liblib: Added [tp]_strsplit_tabescaped()
Timo Sirainen <tss@iki.fi>
parents: 12782
diff changeset
301 args = p_strsplit(pool, str, "\t");
e07d2e37053d liblib: Added [tp]_strsplit_tabescaped()
Timo Sirainen <tss@iki.fi>
parents: 12782
diff changeset
302 for (i = 0; args[i] != NULL; i++)
e07d2e37053d liblib: Added [tp]_strsplit_tabescaped()
Timo Sirainen <tss@iki.fi>
parents: 12782
diff changeset
303 args[i] = str_tabunescape(args[i]);
e07d2e37053d liblib: Added [tp]_strsplit_tabescaped()
Timo Sirainen <tss@iki.fi>
parents: 12782
diff changeset
304 return args;
e07d2e37053d liblib: Added [tp]_strsplit_tabescaped()
Timo Sirainen <tss@iki.fi>
parents: 12782
diff changeset
305 }
e07d2e37053d liblib: Added [tp]_strsplit_tabescaped()
Timo Sirainen <tss@iki.fi>
parents: 12782
diff changeset
306
e07d2e37053d liblib: Added [tp]_strsplit_tabescaped()
Timo Sirainen <tss@iki.fi>
parents: 12782
diff changeset
307 const char *const *t_strsplit_tabescaped(const char *str)
e07d2e37053d liblib: Added [tp]_strsplit_tabescaped()
Timo Sirainen <tss@iki.fi>
parents: 12782
diff changeset
308 {
22635
82d8656bb3ad lib: t_strsplit_tabescaped() - don't create unnecessary data stack mempool
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22634
diff changeset
309 return (void *)p_strsplit_tabescaped(unsafe_data_stack_pool, str);
13083
e07d2e37053d liblib: Added [tp]_strsplit_tabescaped()
Timo Sirainen <tss@iki.fi>
parents: 12782
diff changeset
310 }