]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
*) mod_rewrite: Improve safe question mark detection
authorEric Covener <covener@apache.org>
Fri, 27 Sep 2024 13:11:05 +0000 (13:11 +0000)
committerEric Covener <covener@apache.org>
Fri, 27 Sep 2024 13:11:05 +0000 (13:11 +0000)
     Trunk version of patch:
        https://svn.apache.org/r1920566
     Backport version for 2.4.x of patch:
      Trunk version of patch works
      svn merge -c 1920566 ^/httpd/httpd/trunk .
     +1: rpluem, covener, jorton

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1920982 13f79535-47bb-0310-9956-ffa450edef68

modules/mappers/mod_rewrite.c

index ef3e52fb79431f1d526a15d40b1cf88a4ecdfb13..0bf4404923832f416b6986e4be2a031d76701aca 100644 (file)
@@ -2442,21 +2442,19 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry,
             *unsafe_qmark = 0;
 
             /* keep tracking only if interested in the last qmark */
-            if (entry && (entry->flags & RULEFLAG_QSLAST)) {
-                do {
-                    span++;
-                    span += strcspn(input + span, EXPAND_SPECIALS "?");
-                } while (input[span] == '?');
-            }
-            else {
+            if (!entry || !(entry->flags & RULEFLAG_QSLAST)) {
                 unsafe_qmark = NULL;
-                span += strcspn(input + span, EXPAND_SPECIALS);
             }
+
+            /* find the next real special char, any (last) qmark up to
+             * there is safe too
+             */
+            span += strcspn(input + span, EXPAND_SPECIALS);
         }
     }
 
-    /* fast exit */
-    if (inputlen == span) {
+    /* fast path (no specials) */
+    if (span >= inputlen) {
         return apr_pstrmemdup(pool, input, inputlen);
     }
 
@@ -2637,16 +2635,14 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry,
                 *unsafe_qmark = 0;
 
                 /* keep tracking only if interested in the last qmark */
-                if (entry && (entry->flags & RULEFLAG_QSLAST)) {
-                    do {
-                        span++;
-                        span += strcspn(p + span, EXPAND_SPECIALS "?");
-                    } while (p[span] == '?');
-                }
-                else {
+                if (!entry || !(entry->flags & RULEFLAG_QSLAST)) {
                     unsafe_qmark = NULL;
-                    span += strcspn(p + span, EXPAND_SPECIALS);
                 }
+
+                /* find the next real special char, any (last) qmark up to
+                 * there is safe too
+                 */
+                span += strcspn(p + span, EXPAND_SPECIALS);
             }
         }
         if (span > 0) {