comparison src/lib-imap/imap-envelope.c @ 264:483f4afe5da2 HEAD

\r\n chars are now always stripped from headers before placing them in envelope.
author Timo Sirainen <tss@iki.fi>
date Mon, 16 Sep 2002 17:16:52 +0300
parents 70646fbf2c35
children 6f4eeb6a0a0d
comparison
equal deleted inserted replaced
263:30ee462a6457 264:483f4afe5da2
14 14
15 char *in_reply_to, *message_id; 15 char *in_reply_to, *message_id;
16 }; 16 };
17 17
18 #define IS_BREAK_CHAR(c) \ 18 #define IS_BREAK_CHAR(c) \
19 ((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\n' || \ 19 ((c) == ' ' || (c) == '\t' || \
20 (c) == ',' || (c) == ':' || (c) == ';' || (c) == '@' || \ 20 (c) == ',' || (c) == ':' || (c) == ';' || (c) == '@' || \
21 (c) == '<' || (c) == '>' || (c) == '(' || (c) == ')' || \ 21 (c) == '<' || (c) == '>' || (c) == '(' || (c) == ')' || \
22 (c) == '[' || (c) == ']' || (c) == '=') 22 (c) == '[' || (c) == ']' || (c) == '=')
23 23
24 static size_t next_token_quoted(const char *value, size_t len, int *need_qp) 24 #define IS_BREAK_OR_CRLF_CHAR(c) \
25 (IS_BREAK_CHAR(c) || (c) == '\r' || (c) == '\n')
26
27 static size_t next_token_quoted(const char *value, size_t len,
28 int *need_qp, int *quoted)
25 { 29 {
26 size_t i; 30 size_t i;
27 31
28 i_assert(value[0] == '"');
29
30 *need_qp = FALSE; 32 *need_qp = FALSE;
31 33 *quoted = TRUE;
32 for (i = 1; i < len; i++) { 34
35 for (i = *quoted ? 0 : 1; i < len; i++) {
33 if ((unsigned char)value[i] & 0x80) 36 if ((unsigned char)value[i] & 0x80)
34 *need_qp = TRUE; 37 *need_qp = TRUE;
35 38
36 if (value[i] == '"') { 39 if (value[i] == '"' || value[i] == '\r' || value[i] == '\n') {
37 i++; 40 i++;
41 *quoted = value[i] == '"';
38 break; 42 break;
39 } 43 }
40 } 44 }
41 45
42 return i; 46 return i;
43 } 47 }
44 48
45 static size_t next_token(const char *value, size_t len, int *need_qp, int qp_on) 49 static size_t next_token(const char *value, size_t len,
50 int *need_qp, int *quoted, int qp_on)
46 { 51 {
47 size_t i = 0; 52 size_t i = 0;
48 53
49 if (value[0] == '"') 54 if (value[0] == '"' || *quoted)
50 return next_token_quoted(value, len, need_qp); 55 return next_token_quoted(value, len, need_qp, quoted);
51 56
52 *need_qp = FALSE; 57 *need_qp = FALSE;
53 58
54 if (qp_on) { 59 if (qp_on) {
55 /* skip spaces, so we don't end up QP'ing word at a time */ 60 /* skip spaces, so we don't end up QP'ing word at a time */
60 65
61 if (i == len) 66 if (i == len)
62 return i; 67 return i;
63 } 68 }
64 69
65 if (IS_BREAK_CHAR(value[i])) { 70 if (IS_BREAK_OR_CRLF_CHAR(value[i])) {
66 /* return all break-chars in one token */ 71 /* return all break-chars in one token */
67 for (i++; i < len; i++) { 72 for (i++; i < len; i++) {
68 if (!IS_BREAK_CHAR(value[i])) 73 if (!IS_BREAK_CHAR(value[i]))
69 break; 74 break;
70 } 75 }
75 /* then stop at break-char */ 80 /* then stop at break-char */
76 for (; i < len; i++) { 81 for (; i < len; i++) {
77 if ((unsigned char)value[i] & 0x80) 82 if ((unsigned char)value[i] & 0x80)
78 *need_qp = TRUE; 83 *need_qp = TRUE;
79 84
80 if (IS_BREAK_CHAR(value[i])) 85 if (IS_BREAK_OR_CRLF_CHAR(value[i]))
81 break; 86 break;
82 } 87 }
83 88
84 return i; 89 return i;
85 } 90 }
124 /* does two things: 1) escape '\' and '"' characters, 2) 8bit text -> QP */ 129 /* does two things: 1) escape '\' and '"' characters, 2) 8bit text -> QP */
125 static TempString *get_quoted_str(const char *value, size_t value_len) 130 static TempString *get_quoted_str(const char *value, size_t value_len)
126 { 131 {
127 TempString *str; 132 TempString *str;
128 size_t token_len; 133 size_t token_len;
129 int qp, need_qp; 134 int qp, need_qp, quoted;
130 135
131 str = t_string_new(value_len * 2); 136 str = t_string_new(value_len * 2);
132 qp = FALSE; 137 qp = FALSE;
138 quoted = FALSE;
133 139
134 t_string_append_c(str, '"'); 140 t_string_append_c(str, '"');
135 while (value_len > 0) { 141 while (value_len > 0) {
136 token_len = next_token(value, value_len, &need_qp, qp); 142 token_len = next_token(value, value_len, &need_qp, &quoted, qp);
137 i_assert(token_len > 0 && token_len <= value_len); 143 i_assert(token_len > 0 && token_len <= value_len);
138 144
139 /* header may be split to multiple lines, we don't want them */ 145 /* header may be split to multiple lines, we don't want them */
140 while (token_len > 0 && (value[0] == '\r' || 146 while (token_len > 0 && (value[0] == '\r' ||
141 value[0] == '\n')) { 147 value[0] == '\n')) {