Browse Source

avoid overflows (detected with 'clang -ftrapv')

Roberto Ierusalimschy 10 years ago
parent
commit
2b61360d82
2 changed files with 14 additions and 7 deletions
  1. 7 4
      lgc.c
  2. 7 3
      lstate.c

+ 7 - 4
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;
+  }
 }
 
 /*

+ 7 - 3
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;
 }