You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by mi...@apache.org on 2011/10/29 13:13:37 UTC

svn commit: r1194870 - in /httpd/httpd/trunk: CHANGES docs/manual/mod/mod_include.xml include/ap_mmn.h include/httpd.h modules/filters/mod_include.c server/gen_test_char.c server/util.c

Author: minfrin
Date: Sat Oct 29 11:13:37 2011
New Revision: 1194870

URL: http://svn.apache.org/viewvc?rev=1194870&view=rev
Log:
mod_include: Add support for application/x-www-form-urlencoded encoding
and decoding.

Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/docs/manual/mod/mod_include.xml
    httpd/httpd/trunk/include/ap_mmn.h
    httpd/httpd/trunk/include/httpd.h
    httpd/httpd/trunk/modules/filters/mod_include.c
    httpd/httpd/trunk/server/gen_test_char.c
    httpd/httpd/trunk/server/util.c

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1194870&r1=1194869&r2=1194870&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Sat Oct 29 11:13:37 2011
@@ -12,6 +12,9 @@ Changes with Apache 2.3.15
      PR 51714. [Stefan Fritsch, Jim Jagielski, Ruediger Pluem, Eric Covener,
      <lowprio20 gmail.com>]
 
+  *) mod_include: Add support for application/x-www-form-urlencoded encoding
+     and decoding. [Graham Leggett]
+
   *) rotatelogs: Add -c option to force logfile creation in every rotation 
      interval, even if empty.  [Jan Kaluža <jkaluza redhat.com>]
  

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=1194870&r1=1194869&r2=1194870&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/mod_include.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/mod_include.xml Sat Oct 29 11:13:37 2011
@@ -186,13 +186,15 @@
       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>
+      performed. If set to <code>urlencoded</code>,
+      application/x-www-form-urlencoded compatible encoding (found in
+      query strings) will be stripped. 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>
@@ -204,14 +206,17 @@
       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. 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
-      changed by adding an <code>encoding</code> attribute, which will
-      remain in effect until the next <code>encoding</code> attribute
-      is encountered or the element ends, whichever comes first.</p>
+      performed. If set to <code>urlencoded</code>,
+      application/x-www-form-urlencoded compatible encoding will be
+      performed instead, and should be used with query strings. 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 changed by adding
+      an <code>encoding</code> attribute, which will remain in effect
+      until the next <code>encoding</code> attribute 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.</p>
@@ -425,29 +430,32 @@
       <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>
+      <code>url</code>, <code>urlencoded</code>, <code>base64</code>
+      or <code>entity</code>, URL decoding,
+      application/x-www-form-urlencoded 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>
+      <code>url</code>, <code>urlencoding</code>, <code>base64</code>
+      or <code>entity</code>, URL encoding,
+      application/x-www-form-urlencoded 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>
 

Modified: httpd/httpd/trunk/include/ap_mmn.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/ap_mmn.h?rev=1194870&r1=1194869&r2=1194870&view=diff
==============================================================================
--- httpd/httpd/trunk/include/ap_mmn.h (original)
+++ httpd/httpd/trunk/include/ap_mmn.h Sat Oct 29 11:13:37 2011
@@ -362,6 +362,8 @@
  *                         proxy_dir_conf
  * 20111025.0 (2.3.15-dev) Add return value and maxlen to ap_varbuf_regsub(),
  *                         add ap_pregsub_ex()
+ * 20111025.1 (2.3.15-dev) Add ap_escape_urlencoded(), ap_escape_urlencoded_buffer()
+ *                         and ap_unescape_urlencoded().
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
@@ -369,7 +371,7 @@
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
 #define MODULE_MAGIC_NUMBER_MAJOR 20111025
 #endif
-#define MODULE_MAGIC_NUMBER_MINOR 0                   /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 1                   /* 0...n */
 
 /**
  * Determine if the server's current MODULE_MAGIC_NUMBER is at least a

Modified: httpd/httpd/trunk/include/httpd.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/httpd.h?rev=1194870&r1=1194869&r2=1194870&view=diff
==============================================================================
--- httpd/httpd/trunk/include/httpd.h (original)
+++ httpd/httpd/trunk/include/httpd.h Sat Oct 29 11:13:37 2011
@@ -1540,6 +1540,13 @@ AP_DECLARE(int) ap_unescape_url(char *ur
 AP_DECLARE(int) ap_unescape_url_keep2f(char *url, int decode_slashes);
 
 /**
+ * Unescape an application/x-www-form-urlencoded string
+ * @param query The query to unescape
+ * @return 0 on success, non-zero otherwise
+ */
+AP_DECLARE(int) ap_unescape_urlencoded(char *query);
+
+/**
  * Convert all double slashes to single slashes
  * @param name The string to convert
  */
@@ -1582,6 +1589,22 @@ AP_DECLARE(char *) ap_os_escape_path(apr
 #define ap_escape_uri(ppool,path) ap_os_escape_path(ppool,path,1)
 
 /**
+ * Escape a string as application/x-www-form-urlencoded
+ * @param p The pool to allocate from
+ * @param s The path to convert
+ * @return The converted URL
+ */
+AP_DECLARE(char *) ap_escape_urlencoded(apr_pool_t *p, const char *s);
+
+/**
+ * Escape a string as application/x-www-form-urlencoded, to a preallocated buffer
+ * @param c The preallocated buffer to write to
+ * @param s The path to convert
+ * @return The converted URL (c)
+ */
+AP_DECLARE(char *) ap_escape_urlencoded_buffer(char *c, const char *s);
+
+/**
  * Escape an html string
  * @param p The pool to allocate from
  * @param s The html to escape

Modified: httpd/httpd/trunk/modules/filters/mod_include.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/filters/mod_include.c?rev=1194870&r1=1194869&r2=1194870&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/filters/mod_include.c (original)
+++ httpd/httpd/trunk/modules/filters/mod_include.c Sat Oct 29 11:13:37 2011
@@ -1957,6 +1957,11 @@ static apr_status_t handle_echo(include_
                         ap_unescape_url(buf);
                         echo_text = buf;
                     }
+                    else if (!strcasecmp(token, "urlencoded")) {
+                        char *buf = apr_pstrdup(ctx->pool, echo_text);
+                        ap_unescape_urlencoded(buf);
+                        echo_text = buf;
+                    }
                     else if (!strcasecmp(token, "entity")) {
                         char *buf = apr_pstrdup(ctx->pool, echo_text);
                         decodehtml(buf);
@@ -1986,6 +1991,9 @@ static apr_status_t handle_echo(include_
                     else if (!strcasecmp(token, "url")) {
                         echo_text = ap_escape_uri(ctx->dpool, echo_text);
                     }
+                    else if (!strcasecmp(token, "urlencoded")) {
+                        echo_text = ap_escape_urlencoded(ctx->dpool, echo_text);
+                    }
                     else if (!strcasecmp(token, "entity")) {
                         echo_text = ap_escape_html2(ctx->dpool, echo_text, 0);
                     }
@@ -2576,6 +2584,11 @@ static apr_status_t handle_set(include_c
                         ap_unescape_url(buf);
                         parsed_string = buf;
                     }
+                    else if (!strcasecmp(token, "urlencoded")) {
+                        char *buf = apr_pstrdup(ctx->pool, parsed_string);
+                        ap_unescape_urlencoded(buf);
+                        parsed_string = buf;
+                    }
                     else if (!strcasecmp(token, "entity")) {
                         char *buf = apr_pstrdup(ctx->pool, parsed_string);
                         decodehtml(buf);
@@ -2605,6 +2618,9 @@ static apr_status_t handle_set(include_c
                     else if (!strcasecmp(token, "url")) {
                         parsed_string = ap_escape_uri(ctx->dpool, parsed_string);
                     }
+                    else if (!strcasecmp(token, "urlencoded")) {
+                        parsed_string = ap_escape_urlencoded(ctx->dpool, parsed_string);
+                    }
                     else if (!strcasecmp(token, "entity")) {
                         parsed_string = ap_escape_html2(ctx->dpool, parsed_string, 0);
                     }

Modified: httpd/httpd/trunk/server/gen_test_char.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/gen_test_char.c?rev=1194870&r1=1194869&r2=1194870&view=diff
==============================================================================
--- httpd/httpd/trunk/server/gen_test_char.c (original)
+++ httpd/httpd/trunk/server/gen_test_char.c Sat Oct 29 11:13:37 2011
@@ -51,6 +51,7 @@
 #define T_HTTP_TOKEN_STOP     (0x08)
 #define T_ESCAPE_LOGITEM      (0x10)
 #define T_ESCAPE_FORENSIC     (0x20)
+#define T_ESCAPE_URLENCODED   (0x40)
 
 int main(int argc, char *argv[])
 {
@@ -65,6 +66,7 @@ int main(int argc, char *argv[])
            "#define T_HTTP_TOKEN_STOP      (%u)\n"
            "#define T_ESCAPE_LOGITEM       (%u)\n"
            "#define T_ESCAPE_FORENSIC      (%u)\n"
+           "#define T_ESCAPE_URLENCODED    (%u)\n"
            "\n"
            "static const unsigned char test_char_table[256] = {",
            T_ESCAPE_SHELL_CMD,
@@ -72,7 +74,8 @@ int main(int argc, char *argv[])
            T_OS_ESCAPE_PATH,
            T_HTTP_TOKEN_STOP,
            T_ESCAPE_LOGITEM,
-           T_ESCAPE_FORENSIC);
+           T_ESCAPE_FORENSIC,
+           T_ESCAPE_URLENCODED);
 
     for (c = 0; c < 256; ++c) {
         flags = 0;
@@ -108,6 +111,10 @@ int main(int argc, char *argv[])
             flags |= T_OS_ESCAPE_PATH;
         }
 
+        if (!apr_isalnum(c) && !strchr(".-*_ ", c)) {
+            flags |= T_ESCAPE_URLENCODED;
+        }
+
         /* these are the "tspecials" (RFC2068) or "separators" (RFC2616) */
         if (c && (apr_iscntrl(c) || strchr(" \t()<>@,;:\\\"/[]?={}", c))) {
             flags |= T_HTTP_TOKEN_STOP;

Modified: httpd/httpd/trunk/server/util.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/util.c?rev=1194870&r1=1194869&r2=1194870&view=diff
==============================================================================
--- httpd/httpd/trunk/server/util.c (original)
+++ httpd/httpd/trunk/server/util.c Sat Oct 29 11:13:37 2011
@@ -1621,6 +1621,23 @@ AP_DECLARE(int) ap_unescape_url_reserved
 }
 #endif
 
+AP_DECLARE(int) ap_unescape_urlencoded(char *query)
+{
+    char *slider;
+
+    /* replace plus with a space */
+    if (query) {
+        for (slider = query; *slider; slider++) {
+            if (*slider == '+') {
+                *slider = ' ';
+            }
+        }
+    }
+
+    /* unescape everything else */
+    return unescape_url(query, NULL, NULL);
+}
+
 AP_DECLARE(char *) ap_construct_server(apr_pool_t *p, const char *hostname,
                                        apr_port_t port, const request_rec *r)
 {
@@ -1729,6 +1746,33 @@ AP_DECLARE(char *) ap_os_escape_path(apr
     return copy;
 }
 
+AP_DECLARE(char *) ap_escape_urlencoded_buffer(char *copy, const char *buffer)
+{
+    const unsigned char *s = (const unsigned char *)buffer;
+    unsigned char *d = (unsigned char *)copy;
+    unsigned c;
+
+    while ((c = *s)) {
+        if (TEST_CHAR(c, T_ESCAPE_URLENCODED)) {
+            d = c2x(c, '%', d);
+        }
+        else if (c == ' ') {
+            *d++ = '+';
+        }
+        else {
+            *d++ = c;
+        }
+        ++s;
+    }
+    *d = '\0';
+    return copy;
+}
+
+AP_DECLARE(char *) ap_escape_urlencoded(apr_pool_t *p, const char *buffer)
+{
+    return ap_escape_urlencoded_buffer(apr_palloc(p, 3 * strlen(buffer) + 1), buffer);
+}
+
 /* ap_escape_uri is now a macro for os_escape_path */
 
 AP_DECLARE(char *) ap_escape_html2(apr_pool_t *p, const char *s, int toasc)