Permalink
Browse files

fixed ngx_escape_uri issues: + and / should also be escaped.

  • Loading branch information...
agentzh committed Nov 5, 2010
1 parent e1db1c8 commit f8b54c14c8796a18a6a62e610406edf541ad62b5
Showing with 169 additions and 2 deletions.
  1. +156 −2 src/ngx_http_set_escape_uri.c
  2. +13 −0 test/t/escape-uri.t
@@ -4,6 +4,11 @@
#include "ngx_http_set_escape_uri.h"
#include "ngx_string.h"
+
+static uintptr_t ngx_escape_uri_patched(u_char *dst, u_char *src,
+ size_t size, ngx_uint_t type);
+
+
ngx_int_t
ngx_http_set_misc_escape_uri(ngx_http_request_t *r,
ngx_str_t *res, ngx_http_variable_value_t *v)
@@ -21,7 +26,7 @@ ngx_http_set_misc_escape_uri(ngx_http_request_t *r,
src = v->data;
dd("before escape:%.*s", v->len, v->data);
- escape = 2 * ngx_escape_uri(NULL, src, v->len, NGX_ESCAPE_URI);
+ escape = 2 * ngx_escape_uri_patched(NULL, src, v->len, NGX_ESCAPE_URI);
/* len = v->len + 2 * ngx_escape_uri(NULL, src, v->len, NGX_ESCAPE_URI); */
len = escape + v->len;
dd("escaped string len:%zu", len);
@@ -37,7 +42,7 @@ ngx_http_set_misc_escape_uri(ngx_http_request_t *r,
dd("escape == 0");
} else {
- ngx_escape_uri(dst, src, v->len, NGX_ESCAPE_URI);
+ ngx_escape_uri_patched(dst, src, v->len, NGX_ESCAPE_URI);
}
res->data = dst;
@@ -48,3 +53,152 @@ ngx_http_set_misc_escape_uri(ngx_http_request_t *r,
return NGX_OK;
}
+
+static uintptr_t
+ngx_escape_uri_patched(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
+{
+ ngx_uint_t n;
+ uint32_t *escape;
+ static u_char hex[] = "0123456789abcdef";
+
+ /* " ", "#", "%", "?", %00-%1F, %7F-%FF */
+
+ static uint32_t uri[] = {
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+
+ /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
+ 0x80008829, /* 1000 0000 0000 0000 1000 1000 0010 1001 */
+
+ /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
+ 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
+
+ /* ~}| {zyx wvut srqp onml kjih gfed cba` */
+ 0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */
+
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ };
+
+ /* " ", "#", "%", "+", "?", %00-%1F, %7F-%FF */
+
+ static uint32_t args[] = {
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+
+ /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
+ 0x80000829, /* 1000 0000 0000 0000 0000 1000 0010 1001 */
+
+ /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
+ 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
+
+ /* ~}| {zyx wvut srqp onml kjih gfed cba` */
+ 0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */
+
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ };
+
+ /* " ", "#", """, "%", "'", %00-%1F, %7F-%FF */
+
+ static uint32_t html[] = {
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+
+ /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
+ 0x000000ad, /* 0000 0000 0000 0000 0000 0000 1010 1101 */
+
+ /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
+ 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
+
+ /* ~}| {zyx wvut srqp onml kjih gfed cba` */
+ 0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */
+
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ };
+
+ /* " ", """, "%", "'", %00-%1F, %7F-%FF */
+
+ static uint32_t refresh[] = {
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+
+ /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
+ 0x00000085, /* 0000 0000 0000 0000 0000 0000 1000 0101 */
+
+ /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
+ 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
+
+ /* ~}| {zyx wvut srqp onml kjih gfed cba` */
+ 0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */
+
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ };
+
+ /* " ", "%", %00-%1F */
+
+ static uint32_t memcached[] = {
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+
+ /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
+ 0x00000021, /* 0000 0000 0000 0000 0000 0000 0010 0001 */
+
+ /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
+ 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
+
+ /* ~}| {zyx wvut srqp onml kjih gfed cba` */
+ 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
+
+ 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
+ 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
+ 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
+ 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
+ };
+
+ /* mail_auth is the same as memcached */
+
+ static uint32_t *map[] =
+ { uri, args, html, refresh, memcached, memcached };
+
+
+ escape = map[type];
+
+ if (dst == NULL) {
+
+ /* find the number of the characters to be escaped */
+
+ n = 0;
+
+ while (size) {
+ if (escape[*src >> 5] & (1 << (*src & 0x1f))) {
+ n++;
+ }
+ src++;
+ size--;
+ }
+
+ return (uintptr_t) n;
+ }
+
+ while (size) {
+ if (escape[*src >> 5] & (1 << (*src & 0x1f))) {
+ *dst++ = '%';
+ *dst++ = hex[*src >> 4];
+ *dst++ = hex[*src & 0xf];
+ src++;
+
+ } else {
+ *dst++ = *src++;
+ }
+ size--;
+ }
+
+ return (uintptr_t) dst;
+}
+
View
@@ -112,3 +112,16 @@ GET /foo
welcometotheworldofnginx
+
+=== TEST 8: fixed ngx_escape_uri issues: + and / should also be escaped
+--- config
+ location /foo {
+ set $foo '+/';
+ set_escape_uri $foo;
+ echo $foo;
+ }
+--- request
+GET /foo
+--- response_body
+%2b%2f
+

0 comments on commit f8b54c1

Please sign in to comment.