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

2023-03-16 Thread Yann Ylavic
On Wed, Mar 15, 2023 at 9:41 PM Eric Covener  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

2023-03-15 Thread Eric Covener
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  wrote:
>
> Author: ylavic
> Date: Mon Mar 13 21:17:52 2023
> New Revision: 1908359
>
> URL: http://svn.apache.org/viewvc?rev=1908359=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=1908358=1908359=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
>  */
>  intskip; /* number of next rules to skip 
>  */
>  intmaxrounds;/* 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 |=