From b600ba0123b8af27d2d25e7655b311163afaec91 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Fri, 5 May 2017 10:33:23 +1000 Subject: Fix luaL_error callsites - Now that luaL_error does sprintf-like formatting it shouldn't take user input - % now needs to be escaped when passed to luaL_error - Removes several wasteful lua->js->lua string transformations --- src/lauxlib.js | 12 ++++++------ src/liolib.js | 4 ++-- src/loadlib.js | 7 ++++--- src/lstrlib.js | 30 +++++++++++++++--------------- src/ltablib.js | 7 ++++--- src/lutf8lib.js | 2 +- 6 files changed, 32 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/lauxlib.js b/src/lauxlib.js index 389afdf..8616736 100644 --- a/src/lauxlib.js +++ b/src/lauxlib.js @@ -142,20 +142,20 @@ const luaL_argerror = function(L, arg, extramsg) { let ar = new lua.lua_Debug(); if (!lua.lua_getstack(L, 0, ar)) /* no stack frame? */ - return luaL_error(L, lua.to_luastring(`bad argument #${arg} (${lua.to_jsstring(extramsg)})`)); + return luaL_error(L, lua.to_luastring("bad argument #%d (%s)"), arg, extramsg); lua.lua_getinfo(L, 'n', ar); if (ar.namewhat === lua.to_luastring('method', true)) { arg--; /* do not count 'self' */ if (arg === 0) /* error is in the self argument itself? */ - return luaL_error(L, lua.to_luastring(`calling '${lua.to_jsstring(ar.name)}' on bad self (${lua.to_jsstring(extramsg)})`)); + return luaL_error(L, lua.to_luastring("calling '%s' on bad self (%s)"), ar.name, extramsg); } if (ar.name === null) ar.name = pushglobalfuncname(L, ar) ? lua.lua_tostring(L, -1) : ["?".charCodeAt(0)]; - return luaL_error(L, lua.to_luastring(`bad argument #${arg} to '${lua.to_jsstring(ar.name)}' (${lua.to_jsstring(extramsg)})`)); + return luaL_error(L, lua.to_luastring("bad argument #%d to '%s' (%s)"), arg, ar.name, extramsg); }; const typeerror = function(L, arg, tname) { @@ -167,7 +167,7 @@ const typeerror = function(L, arg, tname) { else typearg = luaL_typename(L, arg); - let msg = lua.lua_pushstring(L, lua.to_luastring(`${lua.to_jsstring(tname)} expected, got ${lua.to_jsstring(typearg)}`)); + let msg = lua.lua_pushfstring(L, lua.to_luastring("%s expected, got %s"), tname, typearg); return luaL_argerror(L, arg, msg); }; @@ -176,7 +176,7 @@ const luaL_where = function(L, level) { if (lua.lua_getstack(L, level, ar)) { lua.lua_getinfo(L, lua.to_luastring("Sl", true), ar); if (ar.currentline > 0) { - lua.lua_pushstring(L, lua.to_luastring(`${lua.to_jsstring(ar.short_src)}:${ar.currentline}:`)); + lua.lua_pushfstring(L, lua.to_luastring("%s:%d: "), ar.short_src, ar.currentline); return; } } @@ -607,7 +607,7 @@ const luaL_setfuncs = function(L, l, nup) { const luaL_checkstack = function(L, space, msg) { if (!lua.lua_checkstack(L, space)) { if (msg) - luaL_error(L, lua.to_luastring(`stack overflow (${lua.to_jsstring(msg)})`)); + luaL_error(L, lua.to_luastring("stack overflow (%s)"), msg); else luaL_error(L, lua.to_luastring('stack overflow', true)); } diff --git a/src/liolib.js b/src/liolib.js index 2136755..1557adf 100644 --- a/src/liolib.js +++ b/src/liolib.js @@ -31,7 +31,7 @@ const f_tostring = function(L) { const tofile = function(L) { let p = tolstream(L); if (isclosed(p)) - lauxlib.luaL_error(L, "attempt to use a closed file"); + lauxlib.luaL_error(L, lua.to_luastring("attempt to use a closed file")); assert(p.f); return p.f; }; @@ -62,7 +62,7 @@ const getiofile = function(L, findex) { lua.lua_getfield(L, lua.LUA_REGISTRYINDEX, findex); let p = lua.lua_touserdata(L, -1); if (isclosed(p)) - lauxlib.luaL_error(L, lua.to_luastring(`standard ${lua.to_jsstring(findex.slice(IOPREF_LEN))} file is closed`)); + lauxlib.luaL_error(L, lua.to_luastring("standard %s file is closed"), findex.slice(IOPREF_LEN)); return p.f; }; diff --git a/src/loadlib.js b/src/loadlib.js index 7213796..e7b1680 100644 --- a/src/loadlib.js +++ b/src/loadlib.js @@ -249,7 +249,7 @@ const findfile = function(L, name, pname, dirsep) { lua.lua_getfield(L, lua.lua_upvalueindex(1), pname); let path = lua.lua_tostring(L, -1); if (path === null) - lauxlib.luaL_error(L, `'package.${lua.to_jsstring(pname)}' must be a string`); + lauxlib.luaL_error(L, lua.to_luastring("'package.%s' must be a string"), pname); return searchpath(L, name, path, ['.'.charCodeAt(0)], dirsep); }; @@ -258,7 +258,8 @@ const checkload = function(L, stat, filename) { lua.lua_pushstring(L, filename); /* will be 2nd argument to module */ return 2; /* return open function and file name */ } else - return lauxlib.luaL_error(L, lua.to_luastring(`error loading module '${lua.lua_tojsstring(L, 1)}' from file '${lua.to_jsstring(filename)}':\n\t${lua.lua_tojsstring(L, 1)}`)); + return lauxlib.luaL_error(L, lua.to_luastring("error loading module '%s' from file '%s':\n\t%s"), + lua.lua_tostring(L, 1), filename, lua.lua_tostring(L, 1)); }; const searcher_Lua = function(L) { @@ -336,7 +337,7 @@ const findloader = function(L, name) { if (lua.lua_rawgeti(L, 3, i) === lua.LUA_TNIL) { /* no more searchers? */ lua.lua_pop(L, 1); /* remove nil */ lua.lua_pushstring(L, msg); /* create error message */ - lauxlib.luaL_error(L, lua.to_luastring(`module '${lua.to_jsstring(name)}' not found:${lua.lua_tojsstring(L, -1)}`)); + lauxlib.luaL_error(L, lua.to_luastring("module '%s' not found:%s"), name, lua.lua_tostring(L, -1)); } lua.lua_pushstring(L, name); lua.lua_call(L, 1, 2); /* call it */ diff --git a/src/lstrlib.js b/src/lstrlib.js index b5f235f..7881ade 100644 --- a/src/lstrlib.js +++ b/src/lstrlib.js @@ -139,7 +139,7 @@ const lua_number2strx = function(L, fmt, x) { for (let i = 0; i < buff.length; i++) buff[i] = String.fromCharCode(buff[i]).toUpperCase().charCodeAt(0); } else if (fmt[SIZELENMOD] !== 'a'.charCodeAt(0)) - lauxlib.luaL_error(L, lua.to_luastring("modifiers for format '%a'/'%A' not implemented", true)); + lauxlib.luaL_error(L, lua.to_luastring("modifiers for format '%%a'/'%%A' not implemented")); return buff; }; @@ -344,7 +344,7 @@ const str_format = function(L) { concat(b, s); /* keep entire string */ lua.lua_pop(L, 1); /* remove result from 'luaL_tolstring' */ } else { /* format the string into 'buff' */ - // TODO: will failt if s is not valid UTF-8 + // TODO: will fail if s is not valid UTF-8 concat(b, lua.to_luastring(sprintf(String.fromCharCode(...form), lua.to_jsstring(s)))); lua.lua_pop(L, 1); /* remove result from 'luaL_tolstring' */ } @@ -352,7 +352,7 @@ const str_format = function(L) { break; } default: { /* also treat cases 'pnLlh' */ - return lauxlib.luaL_error(L, lua.to_luastring(`invalid option '%${String.fromCharCode(strfrmt[0])}'`)); + return lauxlib.luaL_error(L, lua.to_luastring("invalid option '%%%c' to 'format'"), strfrmt[0]); } } } @@ -428,7 +428,7 @@ const getnum = function(fmt, df) { const getnumlimit = function(h, fmt, df) { let sz = getnum(fmt, df); if (sz > MAXINTSIZE || sz <= 0) - lauxlib.luaL_error(h.L, lua.to_luastring(`integral size (${sz}) out of limits [1,${MAXINTSIZE}]`)); + lauxlib.luaL_error(h.L, lua.to_luastring("integral size (%d) out of limits [1,%d]"), sz, MAXINTSIZE); return sz; }; @@ -463,7 +463,7 @@ const getoption = function(h, fmt) { case 'c'.charCodeAt(0): { r.size = getnum(fmt, -1); if (r.size === -1) - lauxlib.luaL_error(h.L, lua.to_luastring("missing size for format option 'c'", true)); + lauxlib.luaL_error(h.L, lua.to_luastring("missing size for format option 'c'")); r.opt = KOption.Kchar; return r; } @@ -475,7 +475,7 @@ const getoption = function(h, fmt) { case '>'.charCodeAt(0): h.islittle = false; break; case '='.charCodeAt(0): h.islittle = true; break; case '!'.charCodeAt(0): h.maxalign = getnumlimit(h, fmt, MAXALIGN); break; - default: lauxlib.luaL_error(h.L, lua.to_luastring(`invalid format option '${String.fromCharCode(r.opt)}'`)); + default: lauxlib.luaL_error(h.L, lua.to_luastring("invalid format option '%c'"), r.opt); } r.opt = KOption.Knop; @@ -739,7 +739,7 @@ const unpackint = function(L, str, islittle, size, issigned) { let mask = issigned || res >= 0 ? 0 : MC; for (let i = limit; i < size; i++) { if (str[islittle ? i : size - 1 - i] !== mask) - lauxlib.luaL_error(L, lua.to_luastring(`${size}-byte integer does not fit into Lua Integer`)); + lauxlib.luaL_error(L, lua.to_luastring("%d-byte integer does not fit into Lua Integer"), size); } } return res; @@ -839,7 +839,7 @@ class MatchState { const check_capture = function(ms, l) { l = l - '1'.charCodeAt(0); if (l < 0 || l >= ms.level || ms.capture[l].len === CAP_UNFINISHED) - return lauxlib.luaL_error(ms.L, lua.to_luastring(`invalid capture index %${l + 1}`)); + return lauxlib.luaL_error(ms.L, lua.to_luastring("invalid capture index %%%d"), l + 1); return l; }; @@ -847,21 +847,21 @@ const capture_to_close = function(ms) { let level = ms.level; for (level--; level >= 0; level--) if (ms.capture[level].len === CAP_UNFINISHED) return level; - return lauxlib.luaL_error(ms.L, lua.to_luastring("invalid pattern capture", true)); + return lauxlib.luaL_error(ms.L, lua.to_luastring("invalid pattern capture")); }; const classend = function(ms, p) { switch(ms.p[p++]) { case L_ESC: { if (p === ms.p_end) - lauxlib.luaL_error(ms.L, lua.to_luastring("malformed pattern (ends with '%')", true)); + lauxlib.luaL_error(ms.L, lua.to_luastring("malformed pattern (ends with '%%')")); return p + 1; } case '['.charCodeAt(0): { if (ms.p[p] === '^'.charCodeAt(0)) p++; do { /* look for a ']' */ if (p === ms.p_end) - lauxlib.luaL_error(ms.L, lua.to_luastring("malformed pattern (missing ']')", true)); + lauxlib.luaL_error(ms.L, lua.to_luastring("malformed pattern (missing ']')")); if (ms.p[p++] === L_ESC && p < ms.p_end) p++; /* skip escapes (e.g. '%]') */ } while (ms.p[p] !== ']'.charCodeAt(0)); @@ -928,7 +928,7 @@ const singlematch = function(ms, s, p, ep) { const matchbalance = function(ms, s, p) { if (p >= ms.p_end - 1) - lauxlib.luaL_error(ms.L, lua.to_luastring("malformed pattern (missing arguments to '%b'", true)); + lauxlib.luaL_error(ms.L, lua.to_luastring("malformed pattern (missing arguments to '%%b'")); if (ms.src[s] !== ms.p[p]) return null; else { @@ -1042,7 +1042,7 @@ const match = function(ms, s, p) { case 'f'.charCodeAt(0): { p += 2; if (ms.p[p] !== '[') - lauxlib.luaL_error(ms.L, lua.to_luastring(`missing '[' after '%f' in pattern`)); + lauxlib.luaL_error(ms.L, lua.to_luastring("missing '[' after '%%f' in pattern")); let ep = classend(ms, p); /* points to what is next */ let previous = s === ms.src_init ? 0 : ms.s[s-1]; if (!matchbracketclass(ms, previous, p, ep - 1) && matchbracketclass(ms, ms.src[s], p, ep - 1)) { @@ -1281,7 +1281,7 @@ const add_s = function(ms, b, s, e) { i++; /* skip ESC */ if (!isdigit(news[i])) { if (news[i] !== L_ESC) - lauxlib.luaL_error(L, lua.to_luastring(`invalid use of '${sL_ESC}' in replacement string`)); + lauxlib.luaL_error(L, lua.to_luastring("invalid use of '%c' in replacement string"), sL_ESC); lauxlib.luaL_addchar(b, news[i]); } else if (news[i] === '0'.charCodeAt(0)) lauxlib.luaL_addlstring(b, ms.src.slice(s), e - s); @@ -1318,7 +1318,7 @@ const add_value = function(ms, b, s, e, tr) { lua.lua_pop(L, 1); lua.lua_pushlstring(L, s, e - s); /* keep original text */ } else if (!lua.lua_isstring(L, -1)) - lauxlib.luaL_error(L, lua.to_luastring(`invalid replacement value (a ${lua.to_jsstring(lauxlib.luaL_typename(L, -1))})`)); + lauxlib.luaL_error(L, lua.to_luastring("invalid replacement value (a %s)"), lauxlib.luaL_typename(L, -1)); lauxlib.luaL_addvalue(b); /* add result to accumulator */ }; diff --git a/src/ltablib.js b/src/ltablib.js index 56ba2cd..788e236 100644 --- a/src/ltablib.js +++ b/src/ltablib.js @@ -47,7 +47,8 @@ const aux_getn = function(L, n, w) { const addfield = function(L, b, i) { lua.lua_geti(L, 1, i); if (!lua.lua_isstring(L, -1)) - lauxlib.luaL_error(L, lua.to_luastring(`invalid value (${lua.to_jsstring(lauxlib.luaL_typename(L, -1))}) at index ${i} in table for 'concat'`)); + lauxlib.luaL_error(L, lua.to_luastring("invalid value (%s) at index %d in table for 'concat'"), + lauxlib.luaL_typename(L, -1), i); lauxlib.luaL_addvalue(b); }; @@ -206,14 +207,14 @@ const partition = function(L, lo, up) { /* next loop: repeat ++i while a[i] < P */ while (lua.lua_geti(L, 1, ++i), sort_comp(L, -1, -2)) { if (i == up - 1) /* a[i] < P but a[up - 1] == P ?? */ - lauxlib.luaL_error(L, "invalid order function for sorting"); + lauxlib.luaL_error(L, lua.to_luastring("invalid order function for sorting")); lua.lua_pop(L, 1); /* remove a[i] */ } /* after the loop, a[i] >= P and a[lo .. i - 1] < P */ /* next loop: repeat --j while P < a[j] */ while (lua.lua_geti(L, 1, --j), sort_comp(L, -3, -1)) { if (j < i) /* j < i but a[j] > P ?? */ - lauxlib.luaL_error(L, "invalid order function for sorting"); + lauxlib.luaL_error(L, lua.to_luastring("invalid order function for sorting")); lua.lua_pop(L, 1); /* remove a[j] */ } /* after the loop, a[j] <= P and a[j + 1 .. up] >= P */ diff --git a/src/lutf8lib.js b/src/lutf8lib.js index 9e0302f..1a401c4 100644 --- a/src/lutf8lib.js +++ b/src/lutf8lib.js @@ -117,7 +117,7 @@ const byteoffset = function(L) { let posi = n >= 0 ? 1 : s.length + 1; posi = u_posrelat(lauxlib.luaL_optinteger(L, 3, posi), s.length); - lauxlib.luaL_argcheck(L, 1 <= posi && --posi <= s.length, 3, lua.to_luastring("position ot ouf range", true)); + lauxlib.luaL_argcheck(L, 1 <= posi && --posi <= s.length, 3, lua.to_luastring("position out of range", true)); if (n === 0) { /* find beginning of current byte sequence */ -- cgit v1.2.3-70-g09d2