Skip to content

Commit e7e00ea

Browse files
authored
Merge pull request #79 from tarantool/51-html-escaping
Check ptr to string before use it
2 parents 8909e39 + 16c761a commit e7e00ea

File tree

2 files changed

+39
-5
lines changed

2 files changed

+39
-5
lines changed

http/lib.c

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,37 @@ tpl_term(int type, const char *str, size_t len, void *data)
9191
}
9292
}
9393

94+
/**
95+
* This function exists because lua_tostring does not use
96+
* __tostring metamethod, and this metamethod has to be used
97+
* if we want to print Lua userdata correctly.
98+
*/
99+
static const char *
100+
luaT_tolstring(lua_State *L, int idx, size_t *len)
101+
{
102+
if (!luaL_callmeta(L, idx, "__tostring")) {
103+
switch (lua_type(L, idx)) {
104+
case LUA_TNUMBER:
105+
case LUA_TSTRING:
106+
lua_pushvalue(L, idx);
107+
break;
108+
case LUA_TBOOLEAN: {
109+
int val = lua_toboolean(L, idx);
110+
lua_pushstring(L, val ? "true" : "false");
111+
break;
112+
}
113+
case LUA_TNIL:
114+
lua_pushliteral(L, "nil");
115+
break;
116+
default:
117+
lua_pushfstring(L, "%s: %p", luaL_typename(L, idx),
118+
lua_topointer(L, idx));
119+
}
120+
}
121+
122+
return lua_tolstring(L, -1, len);
123+
}
124+
94125
static int
95126
lbox_httpd_escape_html(struct lua_State *L)
96127
{
@@ -109,11 +140,8 @@ lbox_httpd_escape_html(struct lua_State *L)
109140
}
110141

111142
for (i = 1; i <= top; i++) {
112-
if (lua_isnil(L, i)) {
113-
luaL_addstring(&b, "nil");
114-
continue;
115-
}
116-
const char *s = lua_tostring(L, i);
143+
const char *s = luaT_tolstring(L, i, NULL);
144+
int str_idx = lua_gettop(L);
117145
for (; *s; s++) {
118146
switch(*s) {
119147
case '&':
@@ -136,6 +164,7 @@ lbox_httpd_escape_html(struct lua_State *L)
136164
break;
137165
}
138166
}
167+
lua_remove(L, str_idx);
139168
}
140169

141170
luaL_pushresult(&b);

test/unit/lib_test.lua

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ g.test_template = function()
3737
local rendered = http_lib.template(template, { t = tt })
3838
t.assert(#rendered > 10000, "rendered size")
3939
t.assert_equals(rendered:sub(#rendered - 7, #rendered - 1), "</html>", "rendered eof")
40+
41+
-- gh-51 Incorrect arguments escaping leads to segfault
42+
template = [[<%= {{continue}} %>"]]
43+
local result = http_lib.template(template, {continue = '/'})
44+
t.assert(result:find('\"') ~= nil)
4045
end
4146

4247
g.test_parse_request = function()

0 commit comments

Comments
 (0)