Project

General

Profile

Bug #2999

url-normalize-required expands %2B in query strings

Added by int-e 9 months ago. Updated 8 months ago.

Status:
Fixed
Priority:
Normal
Category:
core
Target version:
ASK QUESTIONS IN Forums:

Description

When the url-normalize-required option is enabled in server.http-parseopts, %2B (an URL-encoded plus sign) gets expanded to a plus sign in query strings, making it impossible to pass plus signs to CGI programs, which treat plus signs as spaces.

I expected that URL-encoded plus signs in query strings are preserved by URL normalization.

As a workaround, url-normalize-required can be disabled.

Version: lighttpd-1.4.53

#1

Updated by gstrauss 9 months ago

  • Status changed from New to Patch Pending
  • Target version changed from 1.4.x to 1.4.55

Thanks for your report. Yes, that looks like a bug. The following patch should fix it.

diff --git a/src/burl.c b/src/burl.c
--- a/src/burl.c
+++ b/src/burl.c
@@ -139,7 +139,9 @@ static int burl_normalize_basic_required_fix (buffer *b, buffer *t, int i, int q
         else if (s[i]=='%' && li_cton(s[i+1], n1) && li_cton(s[i+2], n2)) {
             const unsigned int x = (n1 << 4) | n2;
             if (!encoded_chars_http_uri_reqd[x]
-                && (qs < 0 ? (x!='/'&&x!='?') : (x!='&'&&x!='='&&x!=';'))) {
+                && (qs < 0
+                    ? (x != '/' && x != '?')
+                    : (x != '&' && x != '=' && x != ';' && x != '+'))) {
                 p[j] = x;
             }
             else {
@@ -177,7 +179,9 @@ static int burl_normalize_basic_required (buffer *b, buffer *t)
         }
         else if (s[i]=='%' && li_cton(s[i+1], n1) && li_cton(s[i+2], n2)
                  && (encoded_chars_http_uri_reqd[(x = (n1 << 4) | n2)]
-                     ||(qs < 0 ? (x=='/'||x=='?') : (x=='&'||x=='='||x==';')))){
+                     || (qs < 0
+                         ? (x == '/' || x == '?')
+                         : (x == '&' || x == '=' || x == ';' || x == '+')))) {
             if (li_utf8_invalid_byte(x)) qs = -2;
             if (s[i+1] >= 'a') b->ptr[i+1] &= 0xdf; /* uppercase hex */
             if (s[i+2] >= 'a') b->ptr[i+2] &= 0xdf; /* uppercase hex */
diff --git a/src/t/test_burl.c b/src/t/test_burl.c
--- a/src/t/test_burl.c
+++ b/src/t/test_burl.c
@@ -78,6 +78,8 @@ static void test_burl_normalize (void) {
     run_burl_normalize(psrc, ptmp, flags, __LINE__, CONST_STR_LEN("/%2B"), CONST_STR_LEN("/+"));
     run_burl_normalize(psrc, ptmp, flags, __LINE__, CONST_STR_LEN("/%3a"), CONST_STR_LEN("/:"));
     run_burl_normalize(psrc, ptmp, flags, __LINE__, CONST_STR_LEN("/%3A"), CONST_STR_LEN("/:"));
+    run_burl_normalize(psrc, ptmp, flags, __LINE__, CONST_STR_LEN("/%2b?x=%2b"), CONST_STR_LEN("/+?x=%2B"));
+    run_burl_normalize(psrc, ptmp, flags, __LINE__, CONST_STR_LEN("/%2B?x=%2B"), CONST_STR_LEN("/+?x=%2B"));
     run_burl_normalize(psrc, ptmp, flags, __LINE__, CONST_STR_LEN("/~test%20รค_"), CONST_STR_LEN("/~test%20%C3%A4_"));
     run_burl_normalize(psrc, ptmp, flags, __LINE__, CONST_STR_LEN("/\375"), "", (size_t)-2);
     run_burl_normalize(psrc, ptmp, flags, __LINE__, CONST_STR_LEN("/\376"), "", (size_t)-2);

#2

Updated by gstrauss 8 months ago

  • Status changed from Patch Pending to Fixed
  • % Done changed from 0 to 100

Also available in: Atom