Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: add option arg raw for unescape_uri, get_uri_args, get_post_args, decode_args #1315

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 43 additions & 27 deletions src/ngx_http_lua_args.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,25 @@ ngx_http_lua_ngx_req_get_uri_args(lua_State *L)
int retval;
int n;
int max;
int raw = 0;

n = lua_gettop(L);

if (n != 0 && n != 1) {
return luaL_error(L, "expecting 0 or 1 arguments but seen %d", n);
if (n != 0 && n != 1 && n != 2) {
return luaL_error(L, "expecting 0 or 1 or 2 arguments but seen %d", n);
}

if (n == 1) {
max = luaL_checkinteger(L, 1);
lua_pop(L, 1);
if (n >= 1) {
if (lua_isnil(L, 1)) {
max = NGX_HTTP_LUA_MAX_ARGS;

} else {
max = luaL_checkinteger(L, 1);
}

if (n == 2) {
raw = lua_toboolean(L, 2);
}

} else {
max = NGX_HTTP_LUA_MAX_ARGS;
Expand Down Expand Up @@ -130,7 +139,7 @@ ngx_http_lua_ngx_req_get_uri_args(lua_State *L)

last = buf + r->args.len;

retval = ngx_http_lua_parse_args(L, buf, last, max);
retval = ngx_http_lua_parse_args(L, buf, last, max, raw);

ngx_pfree(r->pool, buf);

Expand All @@ -150,16 +159,25 @@ ngx_http_lua_ngx_req_get_post_args(lua_State *L)
u_char *last;
int n;
int max;
int raw = 0;

n = lua_gettop(L);

if (n != 0 && n != 1) {
return luaL_error(L, "expecting 0 or 1 arguments but seen %d", n);
if (n != 0 && n != 1 && n != 2) {
return luaL_error(L, "expecting 0 or 1 or 2 arguments but seen %d", n);
}

if (n == 1) {
max = luaL_checkinteger(L, 1);
lua_pop(L, 1);
if (n >= 1) {
if (lua_isnil(L, 1)) {
max = NGX_HTTP_LUA_MAX_ARGS;

} else {
max = luaL_checkinteger(L, 1);
}

if (n == 2) {
raw = lua_toboolean(L, 2);
}

} else {
max = NGX_HTTP_LUA_MAX_ARGS;
Expand Down Expand Up @@ -224,7 +242,7 @@ ngx_http_lua_ngx_req_get_post_args(lua_State *L)

last = buf + len;

retval = ngx_http_lua_parse_args(L, buf, last, max);
retval = ngx_http_lua_parse_args(L, buf, last, max, raw);

ngx_pfree(r->pool, buf);

Expand All @@ -233,30 +251,31 @@ ngx_http_lua_ngx_req_get_post_args(lua_State *L)


int
ngx_http_lua_parse_args(lua_State *L, u_char *buf, u_char *last, int max)
ngx_http_lua_parse_args(lua_State *L, u_char *buf, u_char *last,
int max, int raw)
{
u_char *p, *q;
u_char *src, *dst;
unsigned parsing_value;
size_t len;
int count = 0;
int top;
ngx_uint_t type;

top = lua_gettop(L);

p = buf;

parsing_value = 0;
q = p;

type = raw ? NGX_UNESCAPE_URI_COMPONENT_RAW : NGX_UNESCAPE_URI_COMPONENT;
while (p != last) {
if (*p == '=' && ! parsing_value) {
/* key data is between p and q */

src = q; dst = q;

ngx_http_lua_unescape_uri(&dst, &src, p - q,
NGX_UNESCAPE_URI_COMPONENT);
ngx_http_lua_unescape_uri(&dst, &src, p - q, type);

dd("pushing key %.*s", (int) (dst - q), q);

Expand All @@ -273,8 +292,7 @@ ngx_http_lua_parse_args(lua_State *L, u_char *buf, u_char *last, int max)
/* reached the end of a key or a value, just save it */
src = q; dst = q;

ngx_http_lua_unescape_uri(&dst, &src, p - q,
NGX_UNESCAPE_URI_COMPONENT);
ngx_http_lua_unescape_uri(&dst, &src, p - q, type);

dd("pushing key or value %.*s", (int) (dst - q), q);

Expand Down Expand Up @@ -326,8 +344,7 @@ ngx_http_lua_parse_args(lua_State *L, u_char *buf, u_char *last, int max)
if (p != q || parsing_value) {
src = q; dst = q;

ngx_http_lua_unescape_uri(&dst, &src, p - q,
NGX_UNESCAPE_URI_COMPONENT);
ngx_http_lua_unescape_uri(&dst, &src, p - q, type);

dd("pushing key or value %.*s", (int) (dst - q), q);

Expand Down Expand Up @@ -439,9 +456,10 @@ ngx_http_lua_ffi_req_get_uri_args_count(ngx_http_request_t *r, int max,

int
ngx_http_lua_ffi_req_get_uri_args(ngx_http_request_t *r, u_char *buf,
ngx_http_lua_ffi_table_elt_t *out, int count)
ngx_http_lua_ffi_table_elt_t *out, int count, int raw)
{
int i, parsing_value = 0;
ngx_uint_t type;
u_char *last, *p, *q;
u_char *src, *dst;

Expand All @@ -455,15 +473,15 @@ ngx_http_lua_ffi_req_get_uri_args(ngx_http_request_t *r, u_char *buf,
last = buf + r->args.len;
p = buf;
q = p;
type = raw ? NGX_UNESCAPE_URI_COMPONENT_RAW : NGX_UNESCAPE_URI_COMPONENT;

while (p != last) {
if (*p == '=' && !parsing_value) {
/* key data is between p and q */

src = q; dst = q;

ngx_http_lua_unescape_uri(&dst, &src, p - q,
NGX_UNESCAPE_URI_COMPONENT);
ngx_http_lua_unescape_uri(&dst, &src, p - q, type);

dd("saving key %.*s", (int) (dst - q), q);

Expand All @@ -480,8 +498,7 @@ ngx_http_lua_ffi_req_get_uri_args(ngx_http_request_t *r, u_char *buf,
/* reached the end of a key or a value, just save it */
src = q; dst = q;

ngx_http_lua_unescape_uri(&dst, &src, p - q,
NGX_UNESCAPE_URI_COMPONENT);
ngx_http_lua_unescape_uri(&dst, &src, p - q, type);

dd("pushing key or value %.*s", (int) (dst - q), q);

Expand Down Expand Up @@ -525,8 +542,7 @@ ngx_http_lua_ffi_req_get_uri_args(ngx_http_request_t *r, u_char *buf,
if (p != q || parsing_value) {
src = q; dst = q;

ngx_http_lua_unescape_uri(&dst, &src, p - q,
NGX_UNESCAPE_URI_COMPONENT);
ngx_http_lua_unescape_uri(&dst, &src, p - q, type);

dd("pushing key or value %.*s", (int) (dst - q), q);

Expand Down
3 changes: 2 additions & 1 deletion src/ngx_http_lua_args.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@


void ngx_http_lua_inject_req_args_api(lua_State *L);
int ngx_http_lua_parse_args(lua_State *L, u_char *buf, u_char *last, int max);
int ngx_http_lua_parse_args(lua_State *L, u_char *buf, u_char *last,
int max, int raw);


#endif /* _NGX_HTTP_LUA_ARGS_H_INCLUDED_ */
Expand Down
46 changes: 34 additions & 12 deletions src/ngx_http_lua_string.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,17 +143,24 @@ static int
ngx_http_lua_ngx_unescape_uri(lua_State *L)
{
size_t len, dlen;
ngx_uint_t type = NGX_UNESCAPE_URI_COMPONENT;
int n;
u_char *p;
u_char *src, *dst;

if (lua_gettop(L) != 1) {
return luaL_error(L, "expecting one argument");
n = lua_gettop(L);

if (n != 1 && n != 2) {
return luaL_error(L, "expecting 1 or 2 arguments, but got %d", n);
}

if (lua_isnil(L, 1)) {
lua_pushliteral(L, "");
return 1;
}
if (n == 2 && lua_toboolean(L, 2)) {
type = NGX_UNESCAPE_URI_COMPONENT_RAW;
}

src = (u_char *) luaL_checklstring(L, 1, &len);

Expand All @@ -164,7 +171,7 @@ ngx_http_lua_ngx_unescape_uri(lua_State *L)

dst = p;

ngx_http_lua_unescape_uri(&dst, &src, len, NGX_UNESCAPE_URI_COMPONENT);
ngx_http_lua_unescape_uri(&dst, &src, len, type);

lua_pushlstring(L, (char *) p, dst - p);

Expand Down Expand Up @@ -602,17 +609,29 @@ ngx_http_lua_ngx_decode_args(lua_State *L)
size_t len = 0;
int n;
int max;
int raw = 0;

n = lua_gettop(L);

if (n != 1 && n != 2) {
return luaL_error(L, "expecting 1 or 2 arguments but seen %d", n);
if (n != 1 && n != 2 && n!= 3) {
return luaL_error(L, "expecting 1 or 2 or 3 arguments but seen %d", n);
}

buf = (u_char *) luaL_checklstring(L, 1, &len);

if (n == 2) {
max = luaL_checkint(L, 2);
if (n >= 2) {
if (lua_isnil(L, 2)) {
max = NGX_HTTP_LUA_MAX_ARGS;

} else {
max = luaL_checkinteger(L, 2);
}

if (n == 3) {
raw = lua_toboolean(L, 3);
lua_pop(L, 1);
}

lua_pop(L, 1);

} else {
Expand All @@ -624,7 +643,7 @@ ngx_http_lua_ngx_decode_args(lua_State *L)

lua_createtable(L, 0, 4);

return ngx_http_lua_parse_args(L, tmp, tmp + len, max);
return ngx_http_lua_parse_args(L, tmp, tmp + len, max, raw);
}


Expand Down Expand Up @@ -738,12 +757,15 @@ ngx_http_lua_ffi_decode_base64(const u_char *src, size_t slen, u_char *dst,


size_t
ngx_http_lua_ffi_unescape_uri(const u_char *src, size_t len, u_char *dst)
ngx_http_lua_ffi_unescape_uri(const u_char *src, size_t len,
u_char *dst, int raw)
{
u_char *p = dst;
u_char *p = dst;
ngx_uint_t type;

type = raw ? NGX_UNESCAPE_URI_COMPONENT_RAW : NGX_UNESCAPE_URI_COMPONENT;

ngx_http_lua_unescape_uri(&p, (u_char **) &src, len,
NGX_UNESCAPE_URI_COMPONENT);
ngx_http_lua_unescape_uri(&p, (u_char **) &src, len, type);
return p - dst;
}

Expand Down
4 changes: 2 additions & 2 deletions src/ngx_http_lua_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -1968,7 +1968,7 @@ ngx_http_lua_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
}


/* XXX we also decode '+' to ' ' */
/* XXX we also decode '+' to ' ' when type not NGX_UNESCAPE_URI_COMPONENT_RAW */
void
ngx_http_lua_unescape_uri(u_char **dst, u_char **src, size_t size,
ngx_uint_t type)
Expand Down Expand Up @@ -2004,7 +2004,7 @@ ngx_http_lua_unescape_uri(u_char **dst, u_char **src, size_t size,
break;
}

if (ch == '+') {
if (ch == '+' && !(type & NGX_UNESCAPE_URI_COMPONENT_RAW)) {
*d++ = ' ';
break;
}
Expand Down
1 change: 1 addition & 0 deletions src/ngx_http_lua_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#ifndef NGX_UNESCAPE_URI_COMPONENT
#define NGX_UNESCAPE_URI_COMPONENT 0
#define NGX_UNESCAPE_URI_COMPONENT_RAW 4
#endif


Expand Down
25 changes: 25 additions & 0 deletions t/006-escape.t
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,28 @@ GET /lua
%2C%24%40%7C%60
--- no_error_log
[error]



=== TEST 15: unescape uri raw is not set
--- config
location /unescape {
content_by_lua "ngx.say(ngx.unescape_uri('a+%e4%bd%a0'))";
}
--- request
GET /unescape
--- response_body
a 你



=== TEST 16: unescape uri raw is true
--- config
location /unescape {
content_by_lua "ngx.say(ngx.unescape_uri('a+%e4%bd%a0', true))";
}
--- request
GET /unescape
--- response_body
a+你

Loading