Relax chown requirements when check_owner is false
[hcoop/debian/exim4.git] / debian / patches / 82_quoted-or-r-2047-encoded.diff
1 From 5c6cf6a0d5cb7da39e7fde01dca1ff862c1fa1c8 Mon Sep 17 00:00:00 2001
2 From: Jeremy Harris <jgh146exb@wizmail.org>
3 Date: Sun, 14 Dec 2014 15:15:34 +0000
4 Subject: [PATCH] Account properly for quoted or 2047-encoded MIME parameters
5 while walking headers. Bug 1558
6
7 ---
8 src/mime.c | 103 ++++++++++++++++++++++------------------
9 test/log/4000 | 3 ++
10 test/mail/4000.userx | 38 +++++++++++++++
11 test/scripts/4000-scanning/4000 | 29 +++++++++++
12 test/stdout/4000 | 11 +++++
13 5 files changed, 137 insertions(+), 47 deletions(-)
14
15 diff --git a/src/mime.c b/src/mime.c
16 index ab701f2..a61e9f2 100644
17 --- a/src/mime.c
18 +++ b/src/mime.c
19 @@ -528,26 +528,24 @@ while(1)
20 */
21 if (context != NULL)
22 {
23 - while(fgets(CS header, MIME_MAX_HEADER_SIZE, f) != NULL)
24 + while(fgets(CS header, MIME_MAX_HEADER_SIZE, f))
25 {
26 /* boundary line must start with 2 dashes */
27 - if (Ustrncmp(header,"--",2) == 0)
28 - {
29 - if (Ustrncmp((header+2),context->boundary,Ustrlen(context->boundary)) == 0)
30 + if ( Ustrncmp(header, "--", 2) == 0
31 + && Ustrncmp(header+2, context->boundary, Ustrlen(context->boundary)) == 0)
32 + {
33 + /* found boundary */
34 + if (Ustrncmp((header+2+Ustrlen(context->boundary)), "--", 2) == 0)
35 {
36 - /* found boundary */
37 - if (Ustrncmp((header+2+Ustrlen(context->boundary)),"--",2) == 0)
38 - {
39 - /* END boundary found */
40 - debug_printf("End boundary found %s\n", context->boundary);
41 - return rc;
42 - }
43 - else
44 - debug_printf("Next part with boundary %s\n", context->boundary);
45 -
46 - /* can't use break here */
47 - goto DECODE_HEADERS;
48 + /* END boundary found */
49 + debug_printf("End boundary found %s\n", context->boundary);
50 + return rc;
51 }
52 + else
53 + debug_printf("Next part with boundary %s\n", context->boundary);
54 +
55 + /* can't use break here */
56 + goto DECODE_HEADERS;
57 }
58 }
59 /* Hit EOF or read error. Ugh. */
60 @@ -557,92 +555,103 @@ while(1)
61
62 DECODE_HEADERS:
63 /* parse headers, set up expansion variables */
64 - while (mime_get_header(f,header))
65 + while (mime_get_header(f, header))
66 {
67 int i;
68 /* loop through header list */
69 for (i = 0; i < mime_header_list_size; i++)
70 - {
71 - uschar *header_value = NULL;
72 - int header_value_len = 0;
73 -
74 - /* found an interesting header? */
75 - if (strncmpic(mime_header_list[i].name,header,mime_header_list[i].namelen) == 0)
76 - {
77 - uschar *p = header + mime_header_list[i].namelen;
78 - /* yes, grab the value (normalize to lower case)
79 - and copy to its corresponding expansion variable */
80 + if (strncmpic(mime_header_list[i].name,
81 + header, mime_header_list[i].namelen) == 0)
82 + { /* found an interesting header */
83 + uschar * header_value;
84 + int header_value_len;
85 + uschar * p = header + mime_header_list[i].namelen;
86 +
87 + /* grab the value (normalize to lower case)
88 + and copy to its corresponding expansion variable */
89 while(*p != ';')
90 {
91 *p = tolower(*p);
92 p++;
93 }
94 - header_value_len = (p - (header + mime_header_list[i].namelen));
95 - header_value = (uschar *)malloc(header_value_len+1);
96 - memset(header_value,0,header_value_len+1);
97 + header_value_len = p - (header + mime_header_list[i].namelen);
98 p = header + mime_header_list[i].namelen;
99 - Ustrncpy(header_value, p, header_value_len);
100 - debug_printf("Found %s MIME header, value is '%s'\n", mime_header_list[i].name, header_value);
101 + header_value = string_copyn(p, header_value_len);
102 + debug_printf("Found %s MIME header, value is '%s'\n",
103 + mime_header_list[i].name, header_value);
104 *((uschar **)(mime_header_list[i].value)) = header_value;
105
106 /* make p point to the next character after the closing ';' */
107 - p += (header_value_len+1);
108 + p += header_value_len+1;
109
110 - /* grab all param=value tags on the remaining line, check if they are interesting */
111 + /* grab all param=value tags on the remaining line,
112 + check if they are interesting */
113 NEXT_PARAM_SEARCH:
114 - while (*p != 0)
115 + while (*p)
116 {
117 mime_parameter * mp;
118 for (mp = mime_parameter_list;
119 mp < &mime_parameter_list[mime_parameter_list_size];
120 mp++)
121 {
122 - uschar *param_value = NULL;
123 - int param_value_len = 0;
124 + uschar * param_value = NULL;
125
126 /* found an interesting parameter? */
127 if (strncmpic(mp->name, p, mp->namelen) == 0)
128 {
129 - uschar *q = p + mp->namelen;
130 + uschar * q = p + mp->namelen;
131 + int plen = 0;
132 int size = 0;
133 int ptr = 0;
134
135 /* yes, grab the value and copy to its corresponding expansion variable */
136 while(*q && *q != ';') /* ; terminates */
137 - {
138 if (*q == '"')
139 {
140 q++; /* skip leading " */
141 - while(*q && *q != '"') /* which protects ; */
142 + plen++; /* and account for the skip */
143 + while(*q && *q != '"') /* " protects ; */
144 + {
145 param_value = string_cat(param_value, &size, &ptr, q++, 1);
146 - if (*q) q++; /* skip trailing " */
147 + plen++;
148 + }
149 + if (*q)
150 + {
151 + q++; /* skip trailing " */
152 + plen++;
153 + }
154 }
155 else
156 + {
157 param_value = string_cat(param_value, &size, &ptr, q++, 1);
158 - }
159 + plen++;
160 + }
161 +
162 if (param_value)
163 {
164 param_value[ptr++] = '\0';
165 - param_value_len = ptr;
166
167 param_value = rfc2047_decode(param_value,
168 - check_rfc2047_length, NULL, 32, &param_value_len, &q);
169 + check_rfc2047_length, NULL, 32, NULL, &q);
170 debug_printf("Found %s MIME parameter in %s header, "
171 "value is '%s'\n", mp->name, mime_header_list[i].name,
172 param_value);
173 }
174 *mp->value = param_value;
175 - p += (mp->namelen + param_value_len + 1);
176 + p += mp->namelen + plen + 1; /* name=, content, ; */
177 goto NEXT_PARAM_SEARCH;
178 }
179 }
180 /* There is something, but not one of our interesting parameters.
181 Advance to the next semicolon */
182 - while(*p != ';') p++;
183 + while(*p != ';')
184 + {
185 + if (*p == '"') while(*++p && *p != '"') ;
186 + p++;
187 + }
188 p++;
189 }
190 }
191 - }
192 }
193
194 /* set additional flag variables (easier access) */