mirror of
https://github.com/lua/lua.git
synced 2026-10-26 10:35:26 +00:00
Correction of maximum string size in 'lundump'
The maximum size for internal strings in Lua is MAX_SIZE minus 'sizeof(TString)'. Moreover, 'loadVarint' must be precise about the limit of the integer being read.
This commit is contained in:
@@ -96,11 +96,12 @@ static lu_byte loadByte (LoadState *S) {
|
||||
|
||||
static lua_Unsigned loadVarint (LoadState *S, lua_Unsigned limit) {
|
||||
lua_Unsigned x = 0;
|
||||
lua_Unsigned limit_high = limit >> 7;
|
||||
int limit_low = limit & 0x7f;
|
||||
int b;
|
||||
limit >>= 7;
|
||||
do {
|
||||
b = loadByte(S);
|
||||
if (x > limit)
|
||||
if (x >= limit_high && (x > limit_high || (b & 0x7f) > limit_low))
|
||||
error(S, "integer overflow");
|
||||
x = (x << 7) | (b & 0x7f);
|
||||
} while ((b & 0x80) != 0);
|
||||
@@ -108,11 +109,6 @@ static lua_Unsigned loadVarint (LoadState *S, lua_Unsigned limit) {
|
||||
}
|
||||
|
||||
|
||||
static size_t loadSize (LoadState *S) {
|
||||
return cast_sizet(loadVarint(S, MAX_SIZE));
|
||||
}
|
||||
|
||||
|
||||
static int loadInt (LoadState *S) {
|
||||
return cast_int(loadVarint(S, cast_sizet(INT_MAX)));
|
||||
}
|
||||
@@ -137,16 +133,17 @@ static lua_Integer loadInteger (LoadState *S) {
|
||||
|
||||
|
||||
/*
|
||||
** Load a nullable string into slot 'sl' from prototype 'p'. The
|
||||
** assignment to the slot and the barrier must be performed before any
|
||||
** possible GC activity, to anchor the string. (Both 'loadVector' and
|
||||
** 'luaH_setint' can call the GC.)
|
||||
** Load a nullable string into slot 'sl' from prototype 'p'. 'size' is
|
||||
** either the string length + 1 or zero for a previously saved string.
|
||||
** The assignment to the slot and the barrier must be performed before
|
||||
** any possible GC activity, to anchor the string. (Both 'loadVector'
|
||||
** and 'luaH_setint' can call the GC.)
|
||||
*/
|
||||
static void loadString (LoadState *S, Proto *p, TString **sl) {
|
||||
lua_State *L = S->L;
|
||||
TString *ts;
|
||||
TValue sv;
|
||||
size_t size = loadSize(S);
|
||||
size_t size = cast_sizet(loadVarint(S, MAX_SIZE - sizeof(TString) + 1));
|
||||
if (size == 0) { /* previously saved string? */
|
||||
lua_Unsigned idx = loadVarint(S, LUA_MAXUNSIGNED); /* get its index */
|
||||
TValue stv;
|
||||
@@ -160,7 +157,7 @@ static void loadString (LoadState *S, Proto *p, TString **sl) {
|
||||
luaC_objbarrier(L, p, ts);
|
||||
return; /* do not save it again */
|
||||
}
|
||||
else if ((size -= 1) <= LUAI_MAXSHORTLEN) { /* short string? */
|
||||
else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */
|
||||
char buff[LUAI_MAXSHORTLEN + 1]; /* extra space for '\0' */
|
||||
loadVector(S, buff, size + 1); /* load string into buffer */
|
||||
*sl = ts = luaS_newlstr(L, buff, size); /* create string */
|
||||
|
||||
@@ -303,6 +303,7 @@ checkI(function () return 0xF0.0 | 0xCC.0 ~ 0xAA & 0xFD end, 0xF4)
|
||||
checkI(function () return ~(~kFF0 | kFF0) end, 0)
|
||||
checkI(function () return ~~-1024.0 end, -1024)
|
||||
checkI(function () return ((100 << k6) << -4) >> 2 end, 100)
|
||||
checkK(function () return ~(-1 >> 1) end, math.mininteger)
|
||||
|
||||
-- borders around MAXARG_sBx ((((1 << 17) - 1) >> 1) == 65535)
|
||||
local a = 17; local sbx = ((1 << a) - 1) >> 1 -- avoid folding
|
||||
|
||||
@@ -385,6 +385,12 @@ do
|
||||
assert(minint == load("return " .. minint)())
|
||||
assert(eqT(maxint, load("return " .. maxint)()))
|
||||
|
||||
-- limit for integer encoding in binary chunks
|
||||
-- (~(-1 >> 1) is optimized by the compiler as minint, which is
|
||||
-- then encoded in a binary chunk as max unsigned)
|
||||
local f = string.dump(function () return ~(-1 >> 1) end)
|
||||
assert(load(f)() == minint)
|
||||
|
||||
assert(eqT(10000000000000000000000.0, 10000000000000000000000))
|
||||
assert(eqT(-10000000000000000000000.0, -10000000000000000000000))
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user