commit 2b61360d826355e996ec4b9b3af7778af9d84ada
parent 5b6ac971f9223be8cbe44036fdd7c5e46389412d
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Mon, 13 Jul 2015 10:29:37 -0300
avoid overflows (detected with 'clang -ftrapv')
Diffstat:
2 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/lgc.c b/lgc.c
@@ -1,5 +1,5 @@
/*
-** $Id: lgc.c,v 2.204 2015/03/04 13:51:55 roberto Exp roberto $
+** $Id: lgc.c,v 2.205 2015/03/25 13:42:19 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -1114,9 +1114,12 @@ void luaC_runtilstate (lua_State *L, int statesmask) {
static l_mem getdebt (global_State *g) {
l_mem debt = g->GCdebt;
int stepmul = g->gcstepmul;
- debt = (debt / STEPMULADJ) + 1;
- debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM;
- return debt;
+ if (debt <= 0) return 0; /* minimal debt */
+ else {
+ debt = (debt / STEPMULADJ) + 1;
+ debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM;
+ return debt;
+ }
}
/*
diff --git a/lstate.c b/lstate.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.c,v 2.127 2014/11/02 19:33:33 roberto Exp roberto $
+** $Id: lstate.c,v 2.128 2015/03/04 13:31:21 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@@ -93,10 +93,14 @@ static unsigned int makeseed (lua_State *L) {
/*
** set GCdebt to a new value keeping the value (totalbytes + GCdebt)
-** invariant
+** invariant (and avoiding underflows in 'totalbytes')
*/
void luaE_setdebt (global_State *g, l_mem debt) {
- g->totalbytes -= (debt - g->GCdebt);
+ l_mem tb = gettotalbytes(g);
+ lua_assert(tb > 0);
+ if (debt < tb - MAX_LMEM)
+ debt = tb - MAX_LMEM; /* will make 'totalbytes == MAX_LMEM' */
+ g->totalbytes = tb - debt;
g->GCdebt = debt;
}