You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by yl...@apache.org on 2023/03/13 21:17:52 UTC

svn commit: r1908359 - /httpd/httpd/trunk/modules/mappers/mod_rewrite.c

Author: ylavic
Date: Mon Mar 13 21:17:52 2023
New Revision: 1908359

URL: http://svn.apache.org/viewvc?rev=1908359&view=rev
Log:
mod_rewrite: Follow up to r1908347: Use [B, BNE=...] rather than [B=...,BNEG].

Replaces BNEG with BNE= for a more flexible syntax.


Modified:
    httpd/httpd/trunk/modules/mappers/mod_rewrite.c

Modified: httpd/httpd/trunk/modules/mappers/mod_rewrite.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/mappers/mod_rewrite.c?rev=1908359&r1=1908358&r2=1908359&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/mappers/mod_rewrite.c (original)
+++ httpd/httpd/trunk/modules/mappers/mod_rewrite.c Mon Mar 13 21:17:52 2023
@@ -177,7 +177,6 @@ static const char* really_last_key = "re
 #define RULEFLAG_QSLAST             (1<<19)
 #define RULEFLAG_QSNONE             (1<<20) /* programattic only */
 #define RULEFLAG_ESCAPECTLS         (1<<21)
-#define RULEFLAG_ESCAPENEG          (1<<22)
 
 /* return code of the rewrite rule
  * the result may be escaped - or not
@@ -328,7 +327,8 @@ typedef struct {
     data_item *cookie;               /* added cookies                         */
     int        skip;                 /* number of next rules to skip          */
     int        maxrounds;            /* limit on number of loops with N flag  */
-    char       *escapes;             /* specific backref escapes              */
+    const char *escapes;             /* specific backref escapes              */
+    const char *noescapes;           /* specific backref chars not to escape  */
 } rewriterule_entry;
 
 typedef struct {
@@ -429,7 +429,9 @@ static apr_global_mutex_t *rewrite_mapr_
 static const char *rewritemap_mutex_type = "rewrite-map";
 
 /* Optional functions imported from mod_ssl when loaded: */
-static char *escape_backref(apr_pool_t *p, const char *path, const char *escapeme, int flags);
+static char *escape_backref(apr_pool_t *p, const char *path,
+                            const char *escapeme, const char *noescapeme,
+                            int flags);
 
 /*
  * +-------------------------------------------------------+
@@ -688,19 +690,21 @@ static APR_INLINE unsigned char *c2x(uns
  * Escapes a backreference in a similar way as php's urlencode does.
  * Based on ap_os_escape_path in server/util.c
  */
-static char *escape_backref(apr_pool_t *p, const char *path, const char *escapeme, int flags)
+static char *escape_backref(apr_pool_t *p, const char *path,
+                            const char *escapeme, const char *noescapeme,
+                            int flags)
 {
     char *copy = apr_palloc(p, 3 * strlen(path) + 1);
     const unsigned char *s = (const unsigned char *)path;
     unsigned char *d = (unsigned char *)copy;
     int noplus = (flags & RULEFLAG_ESCAPENOPLUS) != 0;
     int ctls = (flags & RULEFLAG_ESCAPECTLS) != 0;
-    int neg = (flags & RULEFLAG_ESCAPENEG) != 0;
     unsigned char c;
 
     while ((c = *s)) {
-        if ((ctls ? !TEST_CHAR(c, T_VCHAR_OBSTEXT) : !escapeme)
-            || (escapeme && ((ap_strchr_c(escapeme, c) != NULL) ^ neg))) {
+        if (((ctls ? !TEST_CHAR(c, T_VCHAR_OBSTEXT) : !escapeme)
+             || (escapeme && ap_strchr_c(escapeme, c)))
+            && (!noescapeme || !ap_strchr_c(noescapeme, c))) {
             if (apr_isalnum(c) || c == '_') {
                 *d++ = c;
             }
@@ -2491,7 +2495,8 @@ static char *do_expand(char *input, rewr
                     /* escape the backreference */
                     char *tmp2, *tmp;
                     tmp = apr_pstrmemdup(pool, bri->source + bri->regmatch[n].rm_so, span);
-                    tmp2 = escape_backref(pool, tmp, entry->escapes, entry->flags);
+                    tmp2 = escape_backref(pool, tmp, entry->escapes, entry->noescapes,
+                                          entry->flags);
                     rewritelog(ctx->r, 5, ctx->perdir, "escaping backreference '%s' to '%s'",
                             tmp, tmp2);
 
@@ -3583,8 +3588,13 @@ static const char *cmd_rewriterule_setfl
                 cfg->escapes = val;
             }
         }
-        else if (!strcasecmp(key, "NEG")) { 
-            cfg->flags |= RULEFLAG_ESCAPENEG;
+        else if (!strcasecmp(key, "NE")) {
+            if (val && *val) {
+                cfg->noescapes = val;
+            }
+            else {
+                return "flag 'BNE' wants a list of characters (i.e. [BNE=...])";
+            }
         }
         else if (!strcasecmp(key, "NP") || !strcasecmp(key, "ackrefernoplus")) { 
             cfg->flags |= RULEFLAG_ESCAPENOPLUS;
@@ -3854,7 +3864,6 @@ static const char *cmd_rewriterule(cmd_p
                 err, a1, a2, a3);
     }
 
-    /* arg3: optional flags field */
     newrule->forced_mimetype     = NULL;
     newrule->forced_handler      = NULL;
     newrule->forced_responsecode = HTTP_MOVED_TEMPORARILY;
@@ -3863,6 +3872,9 @@ static const char *cmd_rewriterule(cmd_p
     newrule->cookie = NULL;
     newrule->skip   = 0;
     newrule->maxrounds = REWRITE_MAX_ROUNDS;
+    newrule->escapes = newrule->noescapes = NULL;
+
+    /* arg3: optional flags field */
     if (a3 != NULL) {
         if ((err = cmd_parseflagfield(cmd->pool, newrule, a3,
                                       cmd_rewriterule_setflag)) != NULL) {



Re: svn commit: r1908359 - /httpd/httpd/trunk/modules/mappers/mod_rewrite.c

Posted by Yann Ylavic <yl...@gmail.com>.
On Wed, Mar 15, 2023 at 9:41 PM Eric Covener <co...@gmail.com> wrote:
>
> This is looking very useful compared to B/B= and int:escape, anything
> outstanding? I'd like to backport it.

Nothing on my side, +1

Regards;
Yann.

Re: svn commit: r1908359 - /httpd/httpd/trunk/modules/mappers/mod_rewrite.c

Posted by Eric Covener <co...@gmail.com>.
This is looking very useful compared to B/B= and int:escape, anything
outstanding? I'd like to backport it.


On Mon, Mar 13, 2023 at 5:17 PM <yl...@apache.org> wrote:
>
> Author: ylavic
> Date: Mon Mar 13 21:17:52 2023
> New Revision: 1908359
>
> URL: http://svn.apache.org/viewvc?rev=1908359&view=rev
> Log:
> mod_rewrite: Follow up to r1908347: Use [B, BNE=...] rather than [B=...,BNEG].
>
> Replaces BNEG with BNE= for a more flexible syntax.
>
>
> Modified:
>     httpd/httpd/trunk/modules/mappers/mod_rewrite.c
>
> Modified: httpd/httpd/trunk/modules/mappers/mod_rewrite.c
> URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/mappers/mod_rewrite.c?rev=1908359&r1=1908358&r2=1908359&view=diff
> ==============================================================================
> --- httpd/httpd/trunk/modules/mappers/mod_rewrite.c (original)
> +++ httpd/httpd/trunk/modules/mappers/mod_rewrite.c Mon Mar 13 21:17:52 2023
> @@ -177,7 +177,6 @@ static const char* really_last_key = "re
>  #define RULEFLAG_QSLAST             (1<<19)
>  #define RULEFLAG_QSNONE             (1<<20) /* programattic only */
>  #define RULEFLAG_ESCAPECTLS         (1<<21)
> -#define RULEFLAG_ESCAPENEG          (1<<22)
>
>  /* return code of the rewrite rule
>   * the result may be escaped - or not
> @@ -328,7 +327,8 @@ typedef struct {
>      data_item *cookie;               /* added cookies                         */
>      int        skip;                 /* number of next rules to skip          */
>      int        maxrounds;            /* limit on number of loops with N flag  */
> -    char       *escapes;             /* specific backref escapes              */
> +    const char *escapes;             /* specific backref escapes              */
> +    const char *noescapes;           /* specific backref chars not to escape  */
>  } rewriterule_entry;
>
>  typedef struct {
> @@ -429,7 +429,9 @@ static apr_global_mutex_t *rewrite_mapr_
>  static const char *rewritemap_mutex_type = "rewrite-map";
>
>  /* Optional functions imported from mod_ssl when loaded: */
> -static char *escape_backref(apr_pool_t *p, const char *path, const char *escapeme, int flags);
> +static char *escape_backref(apr_pool_t *p, const char *path,
> +                            const char *escapeme, const char *noescapeme,
> +                            int flags);
>
>  /*
>   * +-------------------------------------------------------+
> @@ -688,19 +690,21 @@ static APR_INLINE unsigned char *c2x(uns
>   * Escapes a backreference in a similar way as php's urlencode does.
>   * Based on ap_os_escape_path in server/util.c
>   */
> -static char *escape_backref(apr_pool_t *p, const char *path, const char *escapeme, int flags)
> +static char *escape_backref(apr_pool_t *p, const char *path,
> +                            const char *escapeme, const char *noescapeme,
> +                            int flags)
>  {
>      char *copy = apr_palloc(p, 3 * strlen(path) + 1);
>      const unsigned char *s = (const unsigned char *)path;
>      unsigned char *d = (unsigned char *)copy;
>      int noplus = (flags & RULEFLAG_ESCAPENOPLUS) != 0;
>      int ctls = (flags & RULEFLAG_ESCAPECTLS) != 0;
> -    int neg = (flags & RULEFLAG_ESCAPENEG) != 0;
>      unsigned char c;
>
>      while ((c = *s)) {
> -        if ((ctls ? !TEST_CHAR(c, T_VCHAR_OBSTEXT) : !escapeme)
> -            || (escapeme && ((ap_strchr_c(escapeme, c) != NULL) ^ neg))) {
> +        if (((ctls ? !TEST_CHAR(c, T_VCHAR_OBSTEXT) : !escapeme)
> +             || (escapeme && ap_strchr_c(escapeme, c)))
> +            && (!noescapeme || !ap_strchr_c(noescapeme, c))) {
>              if (apr_isalnum(c) || c == '_') {
>                  *d++ = c;
>              }
> @@ -2491,7 +2495,8 @@ static char *do_expand(char *input, rewr
>                      /* escape the backreference */
>                      char *tmp2, *tmp;
>                      tmp = apr_pstrmemdup(pool, bri->source + bri->regmatch[n].rm_so, span);
> -                    tmp2 = escape_backref(pool, tmp, entry->escapes, entry->flags);
> +                    tmp2 = escape_backref(pool, tmp, entry->escapes, entry->noescapes,
> +                                          entry->flags);
>                      rewritelog(ctx->r, 5, ctx->perdir, "escaping backreference '%s' to '%s'",
>                              tmp, tmp2);
>
> @@ -3583,8 +3588,13 @@ static const char *cmd_rewriterule_setfl
>                  cfg->escapes = val;
>              }
>          }
> -        else if (!strcasecmp(key, "NEG")) {
> -            cfg->flags |= RULEFLAG_ESCAPENEG;
> +        else if (!strcasecmp(key, "NE")) {
> +            if (val && *val) {
> +                cfg->noescapes = val;
> +            }
> +            else {
> +                return "flag 'BNE' wants a list of characters (i.e. [BNE=...])";
> +            }
>          }
>          else if (!strcasecmp(key, "NP") || !strcasecmp(key, "ackrefernoplus")) {
>              cfg->flags |= RULEFLAG_ESCAPENOPLUS;
> @@ -3854,7 +3864,6 @@ static const char *cmd_rewriterule(cmd_p
>                  err, a1, a2, a3);
>      }
>
> -    /* arg3: optional flags field */
>      newrule->forced_mimetype     = NULL;
>      newrule->forced_handler      = NULL;
>      newrule->forced_responsecode = HTTP_MOVED_TEMPORARILY;
> @@ -3863,6 +3872,9 @@ static const char *cmd_rewriterule(cmd_p
>      newrule->cookie = NULL;
>      newrule->skip   = 0;
>      newrule->maxrounds = REWRITE_MAX_ROUNDS;
> +    newrule->escapes = newrule->noescapes = NULL;
> +
> +    /* arg3: optional flags field */
>      if (a3 != NULL) {
>          if ((err = cmd_parseflagfield(cmd->pool, newrule, a3,
>                                        cmd_rewriterule_setflag)) != NULL) {
>
>


-- 
Eric Covener
covener@gmail.com