]>
Commit | Line | Data |
---|---|---|
1 | diff -uNr apache_1.3.11.orig/src/modules/standard/mod_rewrite.c apache_1.3.11/src/modules/standard/mod_rewrite.c | |
2 | --- apache_1.3.11.orig/src/modules/standard/mod_rewrite.c Sun Jan 16 19:06:30 2000 | |
3 | +++ apache_1.3.11/src/modules/standard/mod_rewrite.c Thu Oct 5 14:50:43 2000 | |
4 | @@ -1745,7 +1745,6 @@ | |
5 | char *output; | |
6 | const char *vary; | |
7 | char newuri[MAX_STRING_LEN]; | |
8 | - char env[MAX_STRING_LEN]; | |
9 | regex_t *regexp; | |
10 | regmatch_t regmatch[MAX_NMATCH]; | |
11 | backrefinfo *briRR = NULL; | |
12 | @@ -1913,20 +1912,7 @@ | |
13 | * (`RewriteRule <pat> - [E=...]') | |
14 | */ | |
15 | if (strcmp(output, "-") == 0) { | |
16 | - for (i = 0; p->env[i] != NULL; i++) { | |
17 | - /* 1. take the string */ | |
18 | - ap_cpystrn(env, p->env[i], sizeof(env)); | |
19 | - /* 2. expand $N (i.e. backrefs to RewriteRule pattern) */ | |
20 | - expand_backref_inbuffer(r->pool, env, sizeof(env), briRR, '$'); | |
21 | - /* 3. expand %N (i.e. backrefs to latest RewriteCond pattern) */ | |
22 | - expand_backref_inbuffer(r->pool, env, sizeof(env), briRC, '%'); | |
23 | - /* 4. expand %{...} (i.e. variables) */ | |
24 | - expand_variables_inbuffer(r, env, sizeof(env)); | |
25 | - /* 5. expand ${...} (RewriteMap lookups) */ | |
26 | - expand_map_lookups(r, env, sizeof(env)); | |
27 | - /* and add the variable to Apache's structures */ | |
28 | - add_env_variable(r, env); | |
29 | - } | |
30 | + do_expand_env(r, p->env, briRR, briRC); | |
31 | if (p->forced_mimetype != NULL) { | |
32 | if (perdir == NULL) { | |
33 | /* In the per-server context we can force the MIME-type | |
34 | @@ -1961,17 +1947,7 @@ | |
35 | * that there is something to replace, so we create the | |
36 | * substitution URL string in `newuri'. | |
37 | */ | |
38 | - /* 1. take the output string */ | |
39 | - ap_cpystrn(newuri, output, sizeof(newuri)); | |
40 | - /* 2. expand $N (i.e. backrefs to RewriteRule pattern) */ | |
41 | - expand_backref_inbuffer(r->pool, newuri, sizeof(newuri), briRR, '$'); | |
42 | - /* 3. expand %N (i.e. backrefs to latest RewriteCond pattern) */ | |
43 | - expand_backref_inbuffer(r->pool, newuri, sizeof(newuri), briRC, '%'); | |
44 | - /* 4. expand %{...} (i.e. variables) */ | |
45 | - expand_variables_inbuffer(r, newuri, sizeof(newuri)); | |
46 | - /* 5. expand ${...} (RewriteMap lookups) */ | |
47 | - expand_map_lookups(r, newuri, sizeof(newuri)); | |
48 | - /* and log the result... */ | |
49 | + do_expand(r, output, newuri, sizeof(newuri), briRR, briRC); | |
50 | if (perdir == NULL) { | |
51 | rewritelog(r, 2, "rewrite %s -> %s", uri, newuri); | |
52 | } | |
53 | @@ -1983,20 +1959,7 @@ | |
54 | * Additionally do expansion for the environment variable | |
55 | * strings (`RewriteRule .. .. [E=<string>]'). | |
56 | */ | |
57 | - for (i = 0; p->env[i] != NULL; i++) { | |
58 | - /* 1. take the string */ | |
59 | - ap_cpystrn(env, p->env[i], sizeof(env)); | |
60 | - /* 2. expand $N (i.e. backrefs to RewriteRule pattern) */ | |
61 | - expand_backref_inbuffer(r->pool, env, sizeof(env), briRR, '$'); | |
62 | - /* 3. expand %N (i.e. backrefs to latest RewriteCond pattern) */ | |
63 | - expand_backref_inbuffer(r->pool, env, sizeof(env), briRC, '%'); | |
64 | - /* 4. expand %{...} (i.e. variables) */ | |
65 | - expand_variables_inbuffer(r, env, sizeof(env)); | |
66 | - /* 5. expand ${...} (RewriteMap lookups) */ | |
67 | - expand_map_lookups(r, env, sizeof(env)); | |
68 | - /* and add the variable to Apache's structures */ | |
69 | - add_env_variable(r, env); | |
70 | - } | |
71 | + do_expand_env(r, p->env, briRR, briRC); | |
72 | ||
73 | /* | |
74 | * Now replace API's knowledge of the current URI: | |
75 | @@ -2163,16 +2126,7 @@ | |
76 | * Construct the string we match against | |
77 | */ | |
78 | ||
79 | - /* 1. take the string */ | |
80 | - ap_cpystrn(input, p->input, sizeof(input)); | |
81 | - /* 2. expand $N (i.e. backrefs to RewriteRule pattern) */ | |
82 | - expand_backref_inbuffer(r->pool, input, sizeof(input), briRR, '$'); | |
83 | - /* 3. expand %N (i.e. backrefs to latest RewriteCond pattern) */ | |
84 | - expand_backref_inbuffer(r->pool, input, sizeof(input), briRC, '%'); | |
85 | - /* 4. expand %{...} (i.e. variables) */ | |
86 | - expand_variables_inbuffer(r, input, sizeof(input)); | |
87 | - /* 5. expand ${...} (RewriteMap lookups) */ | |
88 | - expand_map_lookups(r, input, sizeof(input)); | |
89 | + do_expand(r, p->input, input, sizeof(input), briRR, briRC); | |
90 | ||
91 | /* | |
92 | * Apply the patterns | |
93 | @@ -2314,6 +2268,139 @@ | |
94 | ** +-------------------------------------------------------+ | |
95 | */ | |
96 | ||
97 | + | |
98 | +/* | |
99 | +** | |
100 | +** perform all the expansions on the input string | |
101 | +** leaving the result in the supplied buffer | |
102 | +** | |
103 | +*/ | |
104 | + | |
105 | +static void do_expand(request_rec *r, char *input, char *buffer, int nbuf, | |
106 | + backrefinfo *briRR, backrefinfo *briRC) | |
107 | +{ | |
108 | + char *inp, *outp; | |
109 | + size_t span, space; | |
110 | + | |
111 | + /* | |
112 | + * for security reasons this expansion must be perfomed in a | |
113 | + * single pass, otherwise an attacker can arrange for the result | |
114 | + * of an earlier expansion to include expansion specifiers that | |
115 | + * are interpreted by a later expansion, producing results that | |
116 | + * were not intended by the administrator. | |
117 | + */ | |
118 | + | |
119 | + inp = input; | |
120 | + outp = buffer; | |
121 | + space = nbuf - 1; /* room for '\0' */ | |
122 | + | |
123 | + for (;;) { | |
124 | + span = strcspn(inp, "$%"); | |
125 | + if (span > space) { | |
126 | + span = space; | |
127 | + } | |
128 | + memcpy(outp, inp, span); | |
129 | + inp += span; | |
130 | + outp += span; | |
131 | + space -= span; | |
132 | + if (space == 0 || *inp == '\0') { | |
133 | + break; | |
134 | + } | |
135 | + /* now we have a '$' or a '%' */ | |
136 | + if (inp[1] == '{') { | |
137 | + char *endp; | |
138 | + endp = strchr(inp, '}'); | |
139 | + if (endp == NULL) { | |
140 | + goto skip; | |
141 | + } | |
142 | + *endp = '\0'; | |
143 | + if (inp[0] == '$') { | |
144 | + /* ${...} map lookup expansion */ | |
145 | + char *key, *dflt, *result; | |
146 | + key = strchr(inp, ':'); | |
147 | + if (key == NULL) { | |
148 | + goto skip; | |
149 | + } | |
150 | + *key++ = '\0'; | |
151 | + dflt = strchr(key, '|'); | |
152 | + if (dflt) { | |
153 | + *dflt++ = '\0'; | |
154 | + } | |
155 | + result = lookup_map(r, inp+2, key); | |
156 | + if (result == NULL) { | |
157 | + result = dflt ? dflt : ""; | |
158 | + } | |
159 | + span = ap_cpystrn(outp, result, space) - outp; | |
160 | + key[-1] = ':'; | |
161 | + if (dflt) { | |
162 | + dflt[-1] = '|'; | |
163 | + } | |
164 | + } | |
165 | + else if (inp[0] == '%') { | |
166 | + /* %{...} variable lookup expansion */ | |
167 | + span = ap_cpystrn(outp, lookup_variable(r, inp+2), space) - outp; | |
168 | + } | |
169 | + else { | |
170 | + span = 0; | |
171 | + } | |
172 | + *endp = '}'; | |
173 | + inp = endp+1; | |
174 | + outp += span; | |
175 | + space -= span; | |
176 | + continue; | |
177 | + } | |
178 | + else if (ap_isdigit(inp[1])) { | |
179 | + int n = inp[1] - '0'; | |
180 | + backrefinfo *bri = NULL; | |
181 | + if (inp[0] == '$') { | |
182 | + /* $N RewriteRule regexp backref expansion */ | |
183 | + bri = briRR; | |
184 | + } | |
185 | + else if (inp[0] == '%') { | |
186 | + /* %N RewriteCond regexp backref expansion */ | |
187 | + bri = briRC; | |
188 | + } | |
189 | + /* see ap_pregsub() in src/main/util.c */ | |
190 | + if (bri && n <= bri->nsub && | |
191 | + bri->regmatch[n].rm_eo > bri->regmatch[n].rm_so) { | |
192 | + span = bri->regmatch[n].rm_eo - bri->regmatch[n].rm_so; | |
193 | + if (span > space) { | |
194 | + span = space; | |
195 | + } | |
196 | + memcpy(outp, bri->source + bri->regmatch[n].rm_so, span); | |
197 | + outp += span; | |
198 | + space -= span; | |
199 | + } | |
200 | + inp += 2; | |
201 | + continue; | |
202 | + } | |
203 | + skip: | |
204 | + *outp++ = *inp++; | |
205 | + space--; | |
206 | + } | |
207 | + *outp++ = '\0'; | |
208 | +} | |
209 | + | |
210 | + | |
211 | +/* | |
212 | +** | |
213 | +** perform all the expansions on the environment variables | |
214 | +** | |
215 | +*/ | |
216 | + | |
217 | +static void do_expand_env(request_rec *r, char *env[], | |
218 | + backrefinfo *briRR, backrefinfo *briRC) | |
219 | +{ | |
220 | + int i; | |
221 | + char buf[MAX_STRING_LEN]; | |
222 | + | |
223 | + for (i = 0; env[i] != NULL; i++) { | |
224 | + do_expand(r, env[i], buf, sizeof(buf), briRR, briRC); | |
225 | + add_env_variable(r, buf); | |
226 | + } | |
227 | +} | |
228 | + | |
229 | + | |
230 | /* | |
231 | ** | |
232 | ** split out a QUERY_STRING part from | |
233 | @@ -2484,51 +2571,6 @@ | |
234 | ||
235 | /* | |
236 | ** | |
237 | -** Expand the %0-%9 or $0-$9 regex backreferences | |
238 | -** | |
239 | -*/ | |
240 | - | |
241 | -static void expand_backref_inbuffer(pool *p, char *buf, int nbuf, | |
242 | - backrefinfo *bri, char c) | |
243 | -{ | |
244 | - register int i; | |
245 | - | |
246 | - /* protect existing $N and & backrefs and replace <c>N with $N backrefs */ | |
247 | - for (i = 0; buf[i] != '\0' && i < nbuf; i++) { | |
248 | - if (buf[i] == '\\' && (buf[i+1] != '\0' && i < (nbuf-1))) { | |
249 | - i++; /* protect next */ | |
250 | - } | |
251 | - else if (buf[i] == '&') { | |
252 | - buf[i] = '\001'; | |
253 | - } | |
254 | - else if (c != '$' && buf[i] == '$' && (buf[i+1] >= '0' && buf[i+1] <= '9')) { | |
255 | - buf[i] = '\002'; | |
256 | - i++; /* speedup */ | |
257 | - } | |
258 | - else if (buf[i] == c && (buf[i+1] >= '0' && buf[i+1] <= '9')) { | |
259 | - buf[i] = '$'; | |
260 | - i++; /* speedup */ | |
261 | - } | |
262 | - } | |
263 | - | |
264 | - /* now apply the standard regex substitution function */ | |
265 | - ap_cpystrn(buf, ap_pregsub(p, buf, bri->source, | |
266 | - bri->nsub+1, bri->regmatch), nbuf); | |
267 | - | |
268 | - /* restore the original $N and & backrefs */ | |
269 | - for (i = 0; buf[i] != '\0' && i < nbuf; i++) { | |
270 | - if (buf[i] == '\001') { | |
271 | - buf[i] = '&'; | |
272 | - } | |
273 | - else if (buf[i] == '\002') { | |
274 | - buf[i] = '$'; | |
275 | - } | |
276 | - } | |
277 | -} | |
278 | - | |
279 | - | |
280 | -/* | |
281 | -** | |
282 | ** Expand tilde-paths (/~user) through | |
283 | ** Unix /etc/passwd database information | |
284 | ** | |
285 | @@ -2571,120 +2613,6 @@ | |
286 | } | |
287 | #endif | |
288 | ||
289 | -/* | |
290 | -** | |
291 | -** mapfile expansion support | |
292 | -** i.e. expansion of MAP lookup directives | |
293 | -** ${<mapname>:<key>} in RewriteRule rhs | |
294 | -** | |
295 | -*/ | |
296 | - | |
297 | -#define limit_length(n) (n > LONG_STRING_LEN-1 ? LONG_STRING_LEN-1 : n) | |
298 | - | |
299 | -static void expand_map_lookups(request_rec *r, char *uri, int uri_len) | |
300 | -{ | |
301 | - char newuri[MAX_STRING_LEN]; | |
302 | - char *cpI; | |
303 | - char *cpIE; | |
304 | - char *cpO; | |
305 | - char *cpT; | |
306 | - char *cpT2; | |
307 | - char mapname[LONG_STRING_LEN]; | |
308 | - char mapkey[LONG_STRING_LEN]; | |
309 | - char defaultvalue[LONG_STRING_LEN]; | |
310 | - int n; | |
311 | - | |
312 | - cpI = uri; | |
313 | - cpIE = cpI+strlen(cpI); | |
314 | - cpO = newuri; | |
315 | - while (cpI < cpIE) { | |
316 | - if (cpI+6 < cpIE && strncmp(cpI, "${", 2) == 0) { | |
317 | - /* missing delimiter -> take it as plain text */ | |
318 | - if ( strchr(cpI+2, ':') == NULL | |
319 | - || strchr(cpI+2, '}') == NULL) { | |
320 | - memcpy(cpO, cpI, 2); | |
321 | - cpO += 2; | |
322 | - cpI += 2; | |
323 | - continue; | |
324 | - } | |
325 | - cpI += 2; | |
326 | - | |
327 | - cpT = strchr(cpI, ':'); | |
328 | - n = cpT-cpI; | |
329 | - memcpy(mapname, cpI, limit_length(n)); | |
330 | - mapname[limit_length(n)] = '\0'; | |
331 | - cpI += n+1; | |
332 | - | |
333 | - cpT2 = strchr(cpI, '|'); | |
334 | - cpT = strchr(cpI, '}'); | |
335 | - if (cpT2 != NULL && cpT2 < cpT) { | |
336 | - n = cpT2-cpI; | |
337 | - memcpy(mapkey, cpI, limit_length(n)); | |
338 | - mapkey[limit_length(n)] = '\0'; | |
339 | - cpI += n+1; | |
340 | - | |
341 | - n = cpT-cpI; | |
342 | - memcpy(defaultvalue, cpI, limit_length(n)); | |
343 | - defaultvalue[limit_length(n)] = '\0'; | |
344 | - cpI += n+1; | |
345 | - } | |
346 | - else { | |
347 | - n = cpT-cpI; | |
348 | - memcpy(mapkey, cpI, limit_length(n)); | |
349 | - mapkey[limit_length(n)] = '\0'; | |
350 | - cpI += n+1; | |
351 | - | |
352 | - defaultvalue[0] = '\0'; | |
353 | - } | |
354 | - | |
355 | - cpT = lookup_map(r, mapname, mapkey); | |
356 | - if (cpT != NULL) { | |
357 | - n = strlen(cpT); | |
358 | - if (cpO + n >= newuri + sizeof(newuri)) { | |
359 | - ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, | |
360 | - r, "insufficient space in " | |
361 | - "expand_map_lookups, aborting"); | |
362 | - return; | |
363 | - } | |
364 | - memcpy(cpO, cpT, n); | |
365 | - cpO += n; | |
366 | - } | |
367 | - else { | |
368 | - n = strlen(defaultvalue); | |
369 | - if (cpO + n >= newuri + sizeof(newuri)) { | |
370 | - ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, | |
371 | - r, "insufficient space in " | |
372 | - "expand_map_lookups, aborting"); | |
373 | - return; | |
374 | - } | |
375 | - memcpy(cpO, defaultvalue, n); | |
376 | - cpO += n; | |
377 | - } | |
378 | - } | |
379 | - else { | |
380 | - cpT = strstr(cpI, "${"); | |
381 | - if (cpT == NULL) | |
382 | - cpT = cpI+strlen(cpI); | |
383 | - n = cpT-cpI; | |
384 | - if (cpO + n >= newuri + sizeof(newuri)) { | |
385 | - ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, | |
386 | - r, "insufficient space in " | |
387 | - "expand_map_lookups, aborting"); | |
388 | - return; | |
389 | - } | |
390 | - memcpy(cpO, cpI, n); | |
391 | - cpO += n; | |
392 | - cpI += n; | |
393 | - } | |
394 | - } | |
395 | - *cpO = '\0'; | |
396 | - ap_cpystrn(uri, newuri, uri_len); | |
397 | - return; | |
398 | -} | |
399 | - | |
400 | -#undef limit_length | |
401 | - | |
402 | - | |
403 | ||
404 | /* | |
405 | ** +-------------------------------------------------------+ | |
406 | @@ -3483,53 +3411,6 @@ | |
407 | */ | |
408 | ||
409 | ||
410 | -static void expand_variables_inbuffer(request_rec *r, char *buf, int buf_len) | |
411 | -{ | |
412 | - char *newbuf; | |
413 | - newbuf = expand_variables(r, buf); | |
414 | - if (strcmp(newbuf, buf) != 0) { | |
415 | - ap_cpystrn(buf, newbuf, buf_len); | |
416 | - } | |
417 | - return; | |
418 | -} | |
419 | - | |
420 | -static char *expand_variables(request_rec *r, char *str) | |
421 | -{ | |
422 | - char output[MAX_STRING_LEN]; | |
423 | - char input[MAX_STRING_LEN]; | |
424 | - char *cp; | |
425 | - char *cp2; | |
426 | - char *cp3; | |
427 | - int expanded; | |
428 | - char *outp; | |
429 | - char *endp; | |
430 | - | |
431 | - ap_cpystrn(input, str, sizeof(input)); | |
432 | - output[0] = '\0'; | |
433 | - outp = output; | |
434 | - endp = output + sizeof(output); | |
435 | - expanded = 0; | |
436 | - for (cp = input; cp < input+MAX_STRING_LEN; ) { | |
437 | - if ((cp2 = strstr(cp, "%{")) != NULL) { | |
438 | - if ((cp3 = strstr(cp2, "}")) != NULL) { | |
439 | - *cp2 = '\0'; | |
440 | - outp = ap_cpystrn(outp, cp, endp - outp); | |
441 | - | |
442 | - cp2 += 2; | |
443 | - *cp3 = '\0'; | |
444 | - outp = ap_cpystrn(outp, lookup_variable(r, cp2), endp - outp); | |
445 | - | |
446 | - cp = cp3+1; | |
447 | - expanded = 1; | |
448 | - continue; | |
449 | - } | |
450 | - } | |
451 | - outp = ap_cpystrn(outp, cp, endp - outp); | |
452 | - break; | |
453 | - } | |
454 | - return expanded ? ap_pstrdup(r->pool, output) : str; | |
455 | -} | |
456 | - | |
457 | static char *lookup_variable(request_rec *r, char *var) | |
458 | { | |
459 | const char *result; | |
460 | diff -uNr apache_1.3.11.orig/src/modules/standard/mod_rewrite.h apache_1.3.11/src/modules/standard/mod_rewrite.h | |
461 | --- apache_1.3.11.orig/src/modules/standard/mod_rewrite.h Thu Oct 21 22:45:38 1999 | |
462 | +++ apache_1.3.11/src/modules/standard/mod_rewrite.h Thu Oct 5 14:48:43 2000 | |
463 | @@ -420,14 +420,16 @@ | |
464 | char *perdir, backrefinfo *briRR, | |
465 | backrefinfo *briRC); | |
466 | ||
467 | +static void do_expand(request_rec *r, char *input, char *buffer, int nbuf, | |
468 | + backrefinfo *briRR, backrefinfo *briRC); | |
469 | +static void do_expand_env(request_rec *r, char *env[], | |
470 | + backrefinfo *briRR, backrefinfo *briRC); | |
471 | + | |
472 | /* URI transformation function */ | |
473 | static void splitout_queryargs(request_rec *r, int qsappend); | |
474 | static void fully_qualify_uri(request_rec *r); | |
475 | static void reduce_uri(request_rec *r); | |
476 | -static void expand_backref_inbuffer(pool *p, char *buf, int nbuf, | |
477 | - backrefinfo *bri, char c); | |
478 | static char *expand_tildepaths(request_rec *r, char *uri); | |
479 | -static void expand_map_lookups(request_rec *r, char *uri, int uri_len); | |
480 | ||
481 | /* rewrite map support functions */ | |
482 | static char *lookup_map(request_rec *r, char *name, char *key); | |
483 | @@ -466,8 +468,6 @@ | |
484 | static int rewritemap_program_child(void *cmd, child_info *pinfo); | |
485 | ||
486 | /* env variable support */ | |
487 | -static void expand_variables_inbuffer(request_rec *r, char *buf, int buf_len); | |
488 | -static char *expand_variables(request_rec *r, char *str); | |
489 | static char *lookup_variable(request_rec *r, char *var); | |
490 | static char *lookup_header(request_rec *r, const char *name); | |
491 |