httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From minf...@apache.org
Subject svn commit: r998651 - in /httpd/httpd/trunk: CHANGES docs/manual/mod/mod_include.xml modules/filters/mod_include.c
Date Sun, 19 Sep 2010 13:02:54 GMT
Author: minfrin
Date: Sun Sep 19 13:02:54 2010
New Revision: 998651

URL: http://svn.apache.org/viewvc?rev=998651&view=rev
Log:
mod_include: Reinstate support for UTF-8 character sets by allowing a
variable being echoed or set to be decoded and then encoded as separate
steps. PR47686

Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/docs/manual/mod/mod_include.xml
    httpd/httpd/trunk/modules/filters/mod_include.c

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=998651&r1=998650&r2=998651&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Sun Sep 19 13:02:54 2010
@@ -2,6 +2,10 @@
 
 Changes with Apache 2.3.9
 
+  *) mod_include: Reinstate support for UTF-8 character sets by allowing a
+     variable being echoed or set to be decoded and then encoded as separate
+     steps. PR47686 [Graham Leggett]
+
   *) mod_cache: Add a discrete commit_entity() provider function within the
      mod_cache provider interface which is called to indicate to the
      provider that caching is complete, giving the provider the opportunity

Modified: httpd/httpd/trunk/docs/manual/mod/mod_include.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/mod_include.xml?rev=998651&r1=998650&r2=998651&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/mod_include.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/mod_include.xml Sun Sep 19 13:02:54 2010
@@ -180,13 +180,32 @@
       <dt><code>var</code></dt>
       <dd>The value is the name of the variable to print.</dd>
 
+      <dt><code>decoding</code></dt>
+      <dd><p>Specifies whether Apache should strip an encoding from
+      the variable before processing the variable further. The default
+      is <code>none</code>, where no decoding will be done. If set to
+      <code>url</code>, then URL decoding (also known as %-encoding;
+      this is appropriate for use within URLs in links, etc.) will be
+      performed. If set to <code>base64</code>, base64 will be decoded,
+      and if set to <code>entity</code>, HTML entity encoding will be
+      stripped. Decoding is done prior to any further encoding on the
+      variable. Multiple encodings can be stripped by specifying more
+      than one comma separated encoding. The decoding setting will
+      remain in effect until the next decoding attribute is encountered,
+      or the element ends.</p>
+
+      <p>The <code>decoding</code> attribute must <em>precede</em>
the
+      corresponding <code>var</code> attribute to be effective.</p>
+      </dd>
+        
       <dt><code>encoding</code></dt>
       <dd><p>Specifies how Apache should encode special characters
       contained in the variable before outputting them. If set
       to <code>none</code>, no encoding will be done. If set to
       <code>url</code>, then URL encoding (also known as %-encoding;
       this is appropriate for use within URLs in links, etc.) will be
-      performed. At the start of an <code>echo</code> element,
+      performed. If set to <code>base64</code>, base64 encoding will
+      be performed. At the start of an <code>echo</code> element,
       the default is set to <code>entity</code>, resulting in entity
       encoding (which is appropriate in the context of a block-level
       HTML element, <em>e.g.</em> a paragraph of text). This can be
@@ -195,10 +214,7 @@
       is encountered or the element ends, whichever comes first.</p>
 
       <p>The <code>encoding</code> attribute must <em>precede</em>
the
-      corresponding <code>var</code> attribute to be effective, and 
-      only special characters as defined in the ISO-8859-1 character
-      encoding will be encoded. This encoding process may not have the
-      desired result if a different character encoding is in use.</p>
+      corresponding <code>var</code> attribute to be effective.</p>
 
       <note type="warning">
         In order to avoid cross-site scripting issues, you should
@@ -383,6 +399,35 @@
 
       <dt><code>value</code></dt>
       <dd>The value to give a variable.</dd>
+
+      <dt><code>decoding</code></dt>
+      <dd><p>Specifies whether Apache should strip an encoding from
+      the variable before processing the variable further. The default
+      is <code>none</code>, where no decoding will be done. If set to
+      <code>url</code>, <code>base64</code> or <code>entity</code>,
+      URL decoding, base64 decoding or HTML entity decoding will be
+      performed respectively. More than one decoding can be specified
+      by separating with commas. The decoding setting will remain in
+      effect until the next decoding attribute is encountered, or the
+      element ends. The <code>decoding</code> attribute must
+      <em>precede</em> the corresponding <code>var</code> attribute
to
+      be effective.</p>
+      </dd>
+      
+      <dt><code>encoding</code></dt>
+      <dd><p>Specifies how Apache should encode special characters
+      contained in the variable before setting them. The default is
+      <code>none</code>, where no encoding will be done. If set to
+      <code>url</code>, <code>base64</code> or <code>entity</code>,
+      URL encoding, base64 encoding or HTML entity encoding will be
+      performed respectively. More than one encoding can be specified
+      by separating with commas. The encoding setting will remain in
+      effect until the next encoding attribute is encountered, or the
+      element ends. The <code>encoding</code> attribute must
+      <em>precede</em> the corresponding <code>var</code> attribute
+      to be effective. Encodings are applied after all decodings have
+      been stripped.</p>
+      </dd>
       </dl>
 
       <example><title>Example</title>

Modified: httpd/httpd/trunk/modules/filters/mod_include.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/filters/mod_include.c?rev=998651&r1=998650&r2=998651&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/filters/mod_include.c (original)
+++ httpd/httpd/trunk/modules/filters/mod_include.c Sun Sep 19 13:02:54 2010
@@ -1136,13 +1136,15 @@ static apr_status_t handle_include(inclu
 }
 
 /*
- * <!--#echo [encoding="..."] var="..." [encoding="..."] var="..." ... -->
+ * <!--#echo [decoding="..."] [encoding="..."] var="..." [decoding="..."]
+ *  [encoding="..."] var="..." ... -->
  */
 static apr_status_t handle_echo(include_ctx_t *ctx, ap_filter_t *f,
                                 apr_bucket_brigade *bb)
 {
-    enum {E_NONE, E_URL, E_ENTITY} encode;
+    const char *encoding = "entity", *decoding = "none";
     request_rec *r = f->r;
+    int error = 0;
 
     if (!ctx->argc) {
         ap_log_rerror(APLOG_MARK,
@@ -1161,8 +1163,6 @@ static apr_status_t handle_echo(include_
         return APR_SUCCESS;
     }
 
-    encode = E_ENTITY;
-
     while (1) {
         char *tag = NULL;
         char *tag_val = NULL;
@@ -1182,17 +1182,69 @@ static apr_status_t handle_echo(include_
                                   ctx);
 
             if (val) {
-                switch(encode) {
-                case E_NONE:
-                    echo_text = val;
-                    break;
-                case E_URL:
-                    echo_text = ap_escape_uri(ctx->dpool, val);
-                    break;
-                case E_ENTITY:
-                    /* PR#25202: escape anything non-ascii here */
-                    echo_text = ap_escape_html2(ctx->dpool, val, 1);
-                    break;
+                char *last = NULL;
+                char *e, *d, *token;
+
+                echo_text = val;
+
+                d = apr_pstrdup(ctx->pool, decoding);
+                token = apr_strtok(d, ", \t", &last);
+
+                while(token) {
+                    if (!strcasecmp(token, "none")) {
+                        /* do nothing */
+                    }
+                    else if (!strcasecmp(token, "url")) {
+                        char *buf = apr_pstrdup(ctx->pool, echo_text);
+                        ap_unescape_url(buf);
+                        echo_text = buf;
+                    }
+                    else if (!strcasecmp(token, "entity")) {
+                        char *buf = apr_pstrdup(ctx->pool, echo_text);
+                        decodehtml(buf);
+                        echo_text = buf;
+                    }
+                    else if (!strcasecmp(token, "base64")) {
+                        echo_text = ap_pbase64decode(ctx->dpool, echo_text);
+                    }
+                    else {
+                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "unknown value "
+                                      "\"%s\" to parameter \"decoding\" of tag echo in "
+                                      "%s", token, r->filename);
+                        SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
+                        error = 1;
+                        break;
+                    }
+                    token = apr_strtok(NULL, ", \t", &last);
+                }
+
+                e = apr_pstrdup(ctx->pool, encoding);
+                token = apr_strtok(e, ", \t", &last);
+
+                while(token) {
+                    if (!strcasecmp(token, "none")) {
+                        /* do nothing */
+                    }
+                    else if (!strcasecmp(token, "url")) {
+                        echo_text = ap_escape_uri(ctx->dpool, echo_text);
+                    }
+                    else if (!strcasecmp(token, "entity")) {
+                        echo_text = ap_escape_html2(ctx->dpool, echo_text, 0);
+                    }
+                    else if (!strcasecmp(token, "base64")) {
+                        char *buf;
+                        buf = ap_pbase64encode(ctx->dpool, (char *)echo_text);
+                        echo_text = buf;
+                    }
+                    else {
+                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "unknown value "
+                                      "\"%s\" to parameter \"encoding\" of tag echo in "
+                                      "%s", token, r->filename);
+                        SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
+                        error = 1;
+                        break;
+                    }
+                    token = apr_strtok(NULL, ", \t", &last);
                 }
 
                 e_len = strlen(echo_text);
@@ -1202,27 +1254,19 @@ static apr_status_t handle_echo(include_
                 e_len = ctx->intern->undefined_echo_len;
             }
 
+            if (error) {
+                break;
+            }
+
             APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_pool_create(
                                     apr_pmemdup(ctx->pool, echo_text, e_len),
                                     e_len, ctx->pool, f->c->bucket_alloc));
         }
+        else if (!strcmp(tag, "decoding")) {
+            decoding = tag_val;
+        }
         else if (!strcmp(tag, "encoding")) {
-            if (!strcasecmp(tag_val, "none")) {
-                encode = E_NONE;
-            }
-            else if (!strcasecmp(tag_val, "url")) {
-                encode = E_URL;
-            }
-            else if (!strcasecmp(tag_val, "entity")) {
-                encode = E_ENTITY;
-            }
-            else {
-                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "unknown value "
-                              "\"%s\" to parameter \"encoding\" of tag echo in "
-                              "%s", tag_val, r->filename);
-                SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
-                break;
-            }
+            encoding = tag_val;
         }
         else {
             ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "unknown parameter "
@@ -1690,10 +1734,12 @@ static apr_status_t handle_endif(include
 static apr_status_t handle_set(include_ctx_t *ctx, ap_filter_t *f,
                                apr_bucket_brigade *bb)
 {
+    const char *encoding = "none", *decoding = "none";
     char *var = NULL;
     request_rec *r = f->r;
     request_rec *sub = r->main;
     apr_pool_t *p = r->pool;
+    int error = 0;
 
     if (ctx->argc < 2) {
         ap_log_rerror(APLOG_MARK,
@@ -1724,16 +1770,23 @@ static apr_status_t handle_set(include_c
         char *tag = NULL;
         char *tag_val = NULL;
 
-        ap_ssi_get_tag_and_value(ctx, &tag, &tag_val, SSI_VALUE_DECODED);
+        ap_ssi_get_tag_and_value(ctx, &tag, &tag_val, SSI_VALUE_RAW);
 
         if (!tag || !tag_val) {
             break;
         }
 
         if (!strcmp(tag, "var")) {
+            decodehtml(tag_val);
             var = ap_ssi_parse_string(ctx, tag_val, NULL, 0,
                                       SSI_EXPAND_DROP_NAME);
         }
+        else if (!strcmp(tag, "decoding")) {
+            decoding = tag_val;
+        }
+        else if (!strcmp(tag, "encoding")) {
+            encoding = tag_val;
+        }
         else if (!strcmp(tag, "value")) {
             char *parsed_string;
 
@@ -1747,6 +1800,77 @@ static apr_status_t handle_set(include_c
 
             parsed_string = ap_ssi_parse_string(ctx, tag_val, NULL, 0,
                                                 SSI_EXPAND_DROP_NAME);
+
+            if (parsed_string) {
+                char *last = NULL;
+                char *e, *d, *token;
+
+                d = apr_pstrdup(ctx->pool, decoding);
+                token = apr_strtok(d, ", \t", &last);
+
+                while(token) {
+                    if (!strcasecmp(token, "none")) {
+                        /* do nothing */
+                    }
+                    else if (!strcasecmp(token, "url")) {
+                        char *buf = apr_pstrdup(ctx->pool, parsed_string);
+                        ap_unescape_url(buf);
+                        parsed_string = buf;
+                    }
+                    else if (!strcasecmp(token, "entity")) {
+                        char *buf = apr_pstrdup(ctx->pool, parsed_string);
+                        decodehtml(buf);
+                        parsed_string = buf;
+                    }
+                    else if (!strcasecmp(token, "base64")) {
+                        parsed_string = ap_pbase64decode(ctx->dpool, parsed_string);
+                    }
+                    else {
+                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "unknown value "
+                                      "\"%s\" to parameter \"decoding\" of tag set in "
+                                      "%s", token, r->filename);
+                        SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
+                        error = 1;
+                        break;
+                    }
+                    token = apr_strtok(NULL, ", \t", &last);
+                }
+
+                e = apr_pstrdup(ctx->pool, encoding);
+                token = apr_strtok(e, ", \t", &last);
+
+                while(token) {
+                    if (!strcasecmp(token, "none")) {
+                        /* do nothing */
+                    }
+                    else if (!strcasecmp(token, "url")) {
+                        parsed_string = ap_escape_uri(ctx->dpool, parsed_string);
+                    }
+                    else if (!strcasecmp(token, "entity")) {
+                        parsed_string = ap_escape_html2(ctx->dpool, parsed_string, 0);
+                    }
+                    else if (!strcasecmp(token, "base64")) {
+                        char *buf;
+                        buf = ap_pbase64encode(ctx->dpool, (char *)parsed_string);
+                        parsed_string = buf;
+                    }
+                    else {
+                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "unknown value "
+                                      "\"%s\" to parameter \"encoding\" of tag set in "
+                                      "%s", token, r->filename);
+                        SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
+                        error = 1;
+                        break;
+                    }
+                    token = apr_strtok(NULL, ", \t", &last);
+                }
+
+            }
+
+            if (error) {
+                break;
+            }
+
             apr_table_setn(r->subprocess_env, apr_pstrdup(p, var),
                            apr_pstrdup(p, parsed_string));
         }



Mime
View raw message