diff --git a/bugs b/bugs index 6743c41e..b9015051 100644 --- a/bugs +++ b/bugs @@ -1538,6 +1538,37 @@ lua.c: ]], } +Bug{ +what = [['gsub' may go wild when wrongly called without its third +argument and with a large subject]], +report = [[Florian Berger, on 10/2007]], +since = [[5.1]], +example = [[ +x = string.rep('a', 10000) .. string.rep('b', 10000) +print(#string.gsub(x, 'b')) +]], +patch = [[ +lstrlib.c: +@@ -631,6 +631,2 @@ + } +- default: { +- luaL_argerror(L, 3, "string/function/table expected"); +- return; +- } + } +@@ -650,2 +646,3 @@ + const char *p = luaL_checkstring(L, 2); ++ int tr = lua_type(L, 3); + int max_s = luaL_optint(L, 4, srcl+1); +@@ -655,2 +652,5 @@ + luaL_Buffer b; ++ luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || ++ tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, ++ "string/function/table expected"); + luaL_buffinit(L, &b); +]], +} + Bug{ what = [[ ]], report = [[ , on ]], diff --git a/lstrlib.c b/lstrlib.c index 5f5269eb..75c72f27 100644 --- a/lstrlib.c +++ b/lstrlib.c @@ -1,5 +1,5 @@ /* -** $Id: lstrlib.c,v 1.136 2007/02/07 17:53:08 roberto Exp roberto $ +** $Id: lstrlib.c,v 1.137 2007/10/25 19:30:36 roberto Exp roberto $ ** Standard library for string operations and pattern-matching ** See Copyright Notice in lua.h */ @@ -611,14 +611,9 @@ static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, - const char *e) { + const char *e, int tr) { lua_State *L = ms->L; - switch (lua_type(L, 3)) { - case LUA_TNUMBER: - case LUA_TSTRING: { - add_s(ms, b, s, e); - return; - } + switch (tr) { case LUA_TFUNCTION: { int n; lua_pushvalue(L, 3); @@ -631,8 +626,8 @@ static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, lua_gettable(L, 3); break; } - default: { - luaL_argerror(L, 3, "string/function/table expected"); + default: { /* LUA_TNUMBER or LUA_TSTRING */ + add_s(ms, b, s, e); return; } } @@ -650,11 +645,15 @@ static int str_gsub (lua_State *L) { size_t srcl; const char *src = luaL_checklstring(L, 1, &srcl); const char *p = luaL_checkstring(L, 2); + int tr = lua_type(L, 3); size_t max_s = luaL_optinteger(L, 4, srcl+1); int anchor = (*p == '^') ? (p++, 1) : 0; size_t n = 0; MatchState ms; luaL_Buffer b; + luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || + tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, + "string/function/table expected"); luaL_buffinit(L, &b); ms.L = L; ms.src_init = src; @@ -665,7 +664,7 @@ static int str_gsub (lua_State *L) { e = match(&ms, src, p); if (e) { n++; - add_value(&ms, &b, src, e); + add_value(&ms, &b, src, e, tr); } if (e && e>src) /* non empty match? */ src = e; /* skip it */