MCPcopy Create free account
hub / github.com/apache/httpd / do_expand

Function do_expand

modules/mappers/mod_rewrite.c:2429–2689  ·  view source on GitHub ↗

perform all the expansions on the input string * putting the result into a new string * * for security reasons this expansion must be performed in a * single pass, otherwise an attacker can arrange for the result * of an earlier expansion to include expansion specifiers that * are interpreted by a later expansion, producing results that * were not intended by the administrator. * * unsafe

Source from the content-addressed store, hash-verified

2427 * to -1 and remains so if no qmark is found.
2428 */
2429static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry,
2430 int *unsafe_qmark)
2431{
2432#define EXPAND_SPECIALS "\\$%"
2433 result_list *result, *current;
2434 result_list sresult[SMALL_EXPANSION];
2435 unsigned spc = 0;
2436 apr_size_t span, inputlen, outlen;
2437 char *p, *c;
2438 apr_pool_t *pool = ctx->r->pool;
2439
2440 inputlen = strlen(input);
2441 if (!unsafe_qmark) {
2442 span = strcspn(input, EXPAND_SPECIALS);
2443 }
2444 else {
2445 span = strcspn(input, EXPAND_SPECIALS "?");
2446 if (input[span] == '?') {
2447 /* this qmark is not from an expansion thus safe */
2448 *unsafe_qmark = 0;
2449
2450 /* keep tracking only if interested in the last qmark */
2451 if (!entry || !(entry->flags & RULEFLAG_QSLAST)) {
2452 unsafe_qmark = NULL;
2453 }
2454
2455 /* find the next real special char, any (last) qmark up to
2456 * there is safe too
2457 */
2458 span += strcspn(input + span, EXPAND_SPECIALS);
2459 }
2460 }
2461
2462 /* fast path (no specials) */
2463 if (span >= inputlen) {
2464 return apr_pstrmemdup(pool, input, inputlen);
2465 }
2466
2467 /* well, actually something to do */
2468 result = current = &(sresult[spc++]);
2469
2470 p = input + span;
2471 current->next = NULL;
2472 current->string = input;
2473 current->len = span;
2474 outlen = span;
2475
2476 /* loop for specials */
2477 do {
2478 int expanded = 0;
2479
2480 /* prepare next entry */
2481 if (current->len) {
2482 current->next = (spc < SMALL_EXPANSION)
2483 ? &(sresult[spc++])
2484 : (result_list *)apr_palloc(pool,
2485 sizeof(result_list));
2486 current = current->next;

Callers 5

do_expand_envFunction · 0.85
do_expand_cookieFunction · 0.85
apply_rewrite_condFunction · 0.85
force_type_handlerFunction · 0.85
apply_rewrite_ruleFunction · 0.85

Calls 5

find_closing_curlyFunction · 0.85
lookup_variableFunction · 0.85
find_char_in_curliesFunction · 0.85
lookup_mapFunction · 0.85
escape_backrefFunction · 0.85

Tested by

no test coverage detected