--- lighttpd-1.4.8.orig/src/mod_redirect.c 2005-08-15 10:18:32.000000000 -0700 +++ lighttpd-1.4.8/src/mod_redirect.c 2006-01-06 00:13:14.766313576 -0800 @@ -214,27 +214,66 @@ start = 0; end = pattern_len; for (k = 0; k < pattern_len; k++) { - if ((pattern[k] == '$' || pattern[k] == '%') && - isdigit((unsigned char)pattern[k + 1])) { - /* got one */ - - size_t num = pattern[k + 1] - '0'; - - end = k; - - buffer_append_string_len(p->location, pattern + start, end - start); - - if (pattern[k] == '$') { - /* n is always > 0 */ - if (num < (size_t)n) { - buffer_append_string(p->location, list[num]); + if ((pattern[k] == '$' || pattern[k] == '%')) { + /* Support normal backreferences, url-encoded backreferences, + * and ignored values %%, etc + */ + if (isdigit((unsigned char)pattern[k + 1])) { + /* got one */ + + size_t num = pattern[k + 1] - '0'; + + end = k; + + buffer_append_string_len(p->location, pattern + start, end - start); + + if (pattern[k] == '$') { + /* n is always > 0 */ + if (num < (size_t)n) { + buffer_append_string(p->location, list[num]); + } + } else { + config_append_cond_match_buffer(con, p->conf.context, p->location, num); } - } else { - config_append_cond_match_buffer(con, p->conf.context, p->location, num); - } - - k++; - start = k + 1; + + k++; + start = k + 1; + } else if (pattern[k + 1] == '$' || pattern[k + 1] == '%') { + end = k; + buffer_append_string_len(p->location, pattern + start, end - start); + /* Drop one of the two */ + k++; + buffer_append_string_len(p->location, pattern + k, 2); + + k++; + start = k + 1; + } else if (pattern[k + 1] == '!' && isdigit((unsigned char)pattern[k + 2])) { + /* got one */ + size_t num = 0; + num = pattern[k + 2] - '0'; + + end = k; + + buffer_append_string_len(p->location, pattern + start, end - start); + + if (pattern[k] == '$') { + /* n is always > 0 */ + if (num < (size_t)n) { + buffer_append_string_encoded(p->location, list[num], + strlen(list[num]), ENCODING_REL_URI_PART); + } + k++; + } else if (pattern[k] == '%') { /* Subst and escape */ + buffer *mbuf = buffer_init(); + config_append_cond_match_buffer(con, p->conf.context, mbuf, num); + buffer_append_string_encoded(p->location, mbuf->ptr, + mbuf->used - 1, ENCODING_REL_URI_PART); + k++; + } + + k++; + start = k + 1; + } } }