Skip to content

Commit 3294b1d

Browse files
goechoagentzh
authored andcommitted
bugfix: ngx.encode_args() did not escape "|", ",", "$", "@", and "`".
now it is now consistent with what Google Chrome's JavaScript API function encodeURIComponent() does. See: https://tools.ietf.org/html/rfc2396. Signed-off-by: Yichun Zhang (agentzh) <agentzh@gmail.com>
1 parent 66f0731 commit 3294b1d

File tree

2 files changed

+52
-12
lines changed

2 files changed

+52
-12
lines changed

src/ngx_http_lua_util.c

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1840,6 +1840,26 @@ ngx_http_lua_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
18401840
/* ~}| {zyx wvut srqp onml kjih gfed cba` */
18411841
0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */
18421842

1843+
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
1844+
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
1845+
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
1846+
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
1847+
};
1848+
1849+
/* not ALPHA, DIGIT, "-", ".", "_", "~" */
1850+
1851+
static uint32_t uri_component[] = {
1852+
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
1853+
1854+
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
1855+
0xfc00987d, /* 1111 1100 0000 0000 1001 1000 0111 1101 */
1856+
1857+
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
1858+
0x78000001, /* 0111 1000 0000 0000 0000 0000 0000 0001 */
1859+
1860+
/* ~}| {zyx wvut srqp onml kjih gfed cba` */
1861+
0xb8000001, /* 1011 1000 0000 0000 0000 0000 0000 0001 */
1862+
18431863
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
18441864
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
18451865
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
@@ -1909,8 +1929,7 @@ ngx_http_lua_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
19091929
/* mail_auth is the same as memcached */
19101930

19111931
static uint32_t *map[] =
1912-
{ uri, args, html, refresh, memcached, memcached };
1913-
1932+
{ uri, args, uri_component, html, refresh, memcached, memcached };
19141933

19151934
escape = map[type];
19161935

@@ -2321,7 +2340,7 @@ ngx_http_lua_process_args_option(ngx_http_request_t *r, lua_State *L,
23212340
key = (u_char *) lua_tolstring(L, -2, &key_len);
23222341

23232342
key_escape = 2 * ngx_http_lua_escape_uri(NULL, key, key_len,
2324-
NGX_ESCAPE_URI);
2343+
NGX_ESCAPE_URI_COMPONENT);
23252344
total_escape += key_escape;
23262345

23272346
switch (lua_type(L, -1)) {
@@ -2330,7 +2349,7 @@ ngx_http_lua_process_args_option(ngx_http_request_t *r, lua_State *L,
23302349
value = (u_char *) lua_tolstring(L, -1, &value_len);
23312350

23322351
total_escape += 2 * ngx_http_lua_escape_uri(NULL, value, value_len,
2333-
NGX_ESCAPE_URI);
2352+
NGX_ESCAPE_URI_COMPONENT);
23342353

23352354
len += key_len + value_len + (sizeof("=") - 1);
23362355
n++;
@@ -2371,7 +2390,7 @@ ngx_http_lua_process_args_option(ngx_http_request_t *r, lua_State *L,
23712390
total_escape +=
23722391
2 * ngx_http_lua_escape_uri(NULL, value,
23732392
value_len,
2374-
NGX_ESCAPE_URI);
2393+
NGX_ESCAPE_URI_COMPONENT);
23752394

23762395
len += key_len + value_len + (sizeof("=") - 1);
23772396
}
@@ -2428,7 +2447,8 @@ ngx_http_lua_process_args_option(ngx_http_request_t *r, lua_State *L,
24282447

24292448
if (total_escape) {
24302449
p = (u_char *) ngx_http_lua_escape_uri(p, key, key_len,
2431-
NGX_ESCAPE_URI);
2450+
NGX_ESCAPE_URI_COMPONENT
2451+
);
24322452

24332453
} else {
24342454
dd("shortcut: no escape required");
@@ -2442,7 +2462,8 @@ ngx_http_lua_process_args_option(ngx_http_request_t *r, lua_State *L,
24422462

24432463
if (total_escape) {
24442464
p = (u_char *) ngx_http_lua_escape_uri(p, value, value_len,
2445-
NGX_ESCAPE_URI);
2465+
NGX_ESCAPE_URI_COMPONENT
2466+
);
24462467

24472468
} else {
24482469
p = ngx_copy(p, value, value_len);
@@ -2461,7 +2482,7 @@ ngx_http_lua_process_args_option(ngx_http_request_t *r, lua_State *L,
24612482
if (lua_toboolean(L, -1)) {
24622483
if (total_escape) {
24632484
p = (u_char *) ngx_http_lua_escape_uri(p, key, key_len,
2464-
NGX_ESCAPE_URI);
2485+
NGX_ESCAPE_URI_COMPONENT);
24652486

24662487
} else {
24672488
dd("shortcut: no escape required");
@@ -2489,7 +2510,7 @@ ngx_http_lua_process_args_option(ngx_http_request_t *r, lua_State *L,
24892510
if (total_escape) {
24902511
p = (u_char *) ngx_http_lua_escape_uri(p, key,
24912512
key_len,
2492-
NGX_ESCAPE_URI);
2513+
NGX_ESCAPE_URI_COMPONENT);
24932514

24942515
} else {
24952516
dd("shortcut: no escape required");
@@ -2508,7 +2529,8 @@ ngx_http_lua_process_args_option(ngx_http_request_t *r, lua_State *L,
25082529
p = (u_char *)
25092530
ngx_http_lua_escape_uri(p, key,
25102531
key_len,
2511-
NGX_ESCAPE_URI);
2532+
NGX_ESCAPE_URI_COMPONENT
2533+
);
25122534

25132535
} else {
25142536
dd("shortcut: no escape required");
@@ -2524,7 +2546,8 @@ ngx_http_lua_process_args_option(ngx_http_request_t *r, lua_State *L,
25242546
p = (u_char *)
25252547
ngx_http_lua_escape_uri(p, value,
25262548
value_len,
2527-
NGX_ESCAPE_URI);
2549+
NGX_ESCAPE_URI_COMPONENT
2550+
);
25282551

25292552
} else {
25302553
p = ngx_copy(p, value, value_len);

t/030-uri-args.t

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ log_level('warn');
99
repeat_each(2);
1010
#repeat_each(1);
1111

12-
plan tests => repeat_each() * (blocks() * 2 + 17);
12+
plan tests => repeat_each() * (blocks() * 2 + 18);
1313

1414
no_root_location();
1515

@@ -1389,3 +1389,20 @@ GET /lua
13891389
GET /foo?world
13901390
--- response_body_like
13911391
^HTTP/1.0 (a=3&b|b&a=3)$
1392+
1393+
1394+
1395+
=== TEST 57: ngx.encode_args (escaping)
1396+
--- config
1397+
location /lua {
1398+
content_by_lua_block {
1399+
local t = {bar = "-_.!~*'()", foo = ",$@|`"}
1400+
ngx.say("args: ", ngx.encode_args(t))
1401+
}
1402+
}
1403+
--- request
1404+
GET /lua
1405+
--- response_body
1406+
args: foo=%2C%24%40%7C%60&bar=-_.!~*'()
1407+
--- no_error_log
1408+
[error]

0 commit comments

Comments
 (0)