Преглед на файлове

better control over memory-size overflows

Roberto Ierusalimschy преди 20 години
родител
ревизия
6f1ea817f5
променени са 6 файла, в които са добавени 47 реда и са изтрити 32 реда
  1. 4 4
      lgc.c
  2. 13 8
      lmem.c
  3. 17 11
      lmem.h
  4. 2 2
      lstate.c
  5. 8 3
      lstring.c
  6. 3 4
      lstring.h

+ 4 - 4
lgc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 2.13 2004/10/06 18:34:16 roberto Exp roberto $
+** $Id: lgc.c,v 2.14 2004/10/08 16:00:34 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -139,7 +139,7 @@ size_t luaC_separateudata (lua_State *L, int all) {
       p = &curr->gch.next;
     }
     else {  /* must call its gc method */
-      deadmem += sizeudata(gco2u(curr)->len);
+      deadmem += sizeudata(gco2u(curr));
       markfinalized(gco2u(curr));
       *p = curr->gch.next;
       curr->gch.next = NULL;  /* link `curr' at the end of `collected' list */
@@ -388,11 +388,11 @@ static void freeobj (lua_State *L, GCObject *o) {
     }
     case LUA_TSTRING: {
       G(L)->strt.nuse--;
-      luaM_free(L, o, sizestring(gco2ts(o)->len));
+      luaM_free(L, o, sizestring(gco2ts(o)));
       break;
     }
     case LUA_TUSERDATA: {
-      luaM_free(L, o, sizeudata(gco2u(o)->len));
+      luaM_free(L, o, sizeudata(gco2u(o)));
       break;
     }
     default: lua_assert(0);

+ 13 - 8
lmem.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lmem.c,v 1.64 2004/04/30 20:13:38 roberto Exp roberto $
+** $Id: lmem.c,v 1.65 2004/08/30 13:44:44 roberto Exp roberto $
 ** Interface to Memory Manager
 ** See Copyright Notice in lua.h
 */
@@ -43,10 +43,12 @@
 #define MINSIZEARRAY	4
 
 
-void *luaM_growaux (lua_State *L, void *block, int *size, int size_elems,
+void *luaM_growaux (lua_State *L, void *block, int *size, size_t size_elems,
                     int limit, const char *errormsg) {
   void *newblock;
   int newsize;
+  if (cast(size_t, limit) > MAX_SIZET/size_elems)
+    limit = cast(int, MAX_SIZET/size_elems);
   if (*size >= limit/2) {  /* cannot double it? */
     if (*size >= limit - MINSIZEARRAY)  /* try something smaller... */
       luaG_runerror(L, errormsg);
@@ -57,22 +59,25 @@ void *luaM_growaux (lua_State *L, void *block, int *size, int size_elems,
     if (newsize < MINSIZEARRAY)
       newsize = MINSIZEARRAY;  /* minimum size */
   }
-  newblock = luaM_realloc(L, block,
-                          cast(lu_mem, *size)*cast(lu_mem, size_elems),
-                          cast(lu_mem, newsize)*cast(lu_mem, size_elems));
+  newblock = luaM_reallocv(L, block, *size, newsize, size_elems);
   *size = newsize;  /* update only when everything else is OK */
   return newblock;
 }
 
 
+void *luaM_toobig (lua_State *L) {
+  luaG_runerror(L, "memory allocation error: block too big");
+  return NULL;  /* to avoid warnings */
+}
+
+
+
 /*
 ** generic allocation routine.
 */
-void *luaM_realloc (lua_State *L, void *block, lu_mem osize, lu_mem nsize) {
+void *luaM_realloc (lua_State *L, void *block, size_t osize, size_t nsize) {
   global_State *g = G(L);
   lua_assert((osize == 0) == (block == NULL));
-  if (nsize >= MAX_SIZET)
-    luaG_runerror(L, "memory allocation error: block too big");
   block = (*g->realloc)(g->ud, block, osize, nsize);
   if (block == NULL && nsize > 0)
     luaD_throw(L, LUA_ERRMEM);

+ 17 - 11
lmem.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lmem.h,v 1.25 2001/11/28 20:13:13 roberto Exp roberto $
+** $Id: lmem.h,v 1.26 2002/05/01 20:40:42 roberto Exp roberto $
 ** Interface to Memory Manager
 ** See Copyright Notice in lua.h
 */
@@ -16,28 +16,34 @@
 #define MEMERRMSG	"not enough memory"
 
 
-void *luaM_realloc (lua_State *L, void *oldblock, lu_mem oldsize, lu_mem size);
+void *luaM_realloc (lua_State *L, void *block, size_t oldsize, size_t size);
 
-void *luaM_growaux (lua_State *L, void *block, int *size, int size_elem,
+void *luaM_toobig (lua_State *L);
+
+#define luaM_reallocv(L,b,on,n,e) \
+  ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ?  /* +1 only to avoid warnings */ \
+    luaM_realloc(L, (b), (on)*(e), (n)*(e)) : \
+    luaM_toobig(L))
+
+
+void *luaM_growaux (lua_State *L, void *block, int *size, size_t size_elem,
                     int limit, const char *errormsg);
 
 #define luaM_free(L, b, s)	luaM_realloc(L, (b), (s), 0)
 #define luaM_freelem(L, b)	luaM_realloc(L, (b), sizeof(*(b)), 0)
-#define luaM_freearray(L, b, n, t)	luaM_realloc(L, (b), \
-                                      cast(lu_mem, n)*cast(lu_mem, sizeof(t)), 0)
+#define luaM_freearray(L, b, n, t)   luaM_reallocv(L, (b), n, 0, sizeof(t))
 
-#define luaM_malloc(L, t)	luaM_realloc(L, NULL, 0, (t))
-#define luaM_new(L, t)          cast(t *, luaM_malloc(L, sizeof(t)))
-#define luaM_newvector(L, n,t)  cast(t *, luaM_malloc(L, \
-                                         cast(lu_mem, n)*cast(lu_mem, sizeof(t))))
+#define luaM_malloc(L,t)	luaM_realloc(L, NULL, 0, (t))
+#define luaM_new(L,t)		cast(t *, luaM_malloc(L, sizeof(t)))
+#define luaM_newvector(L,n,t) \
+		cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t)))
 
 #define luaM_growvector(L,v,nelems,size,t,limit,e) \
           if (((nelems)+1) > (size)) \
             ((v)=cast(t *, luaM_growaux(L,v,&(size),sizeof(t),limit,e)))
 
 #define luaM_reallocvector(L, v,oldn,n,t) \
-   ((v)=cast(t *, luaM_realloc(L, v,cast(lu_mem, oldn)*cast(lu_mem, sizeof(t)), \
-                                    cast(lu_mem, n)*cast(lu_mem, sizeof(t)))))
+   ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t))))
 
 
 #endif

+ 2 - 2
lstate.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.c,v 2.14 2004/09/15 20:39:42 roberto Exp roberto $
+** $Id: lstate.c,v 2.15 2004/10/06 18:34:16 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -79,7 +79,7 @@ static void f_luaopen (lua_State *L, void *ud) {
   Udata *u;  /* head of udata list */
   global_State *g = G(L);
   UNUSED(ud);
-  u = cast(Udata *, luaM_malloc(L, sizeudata(0)));
+  u = luaM_new(L, Udata);
   u->uv.len = 0;
   u->uv.metatable = NULL;
   g->firstudata = obj2gco(u);

+ 8 - 3
lstring.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstring.c,v 2.2 2004/04/30 20:13:38 roberto Exp roberto $
+** $Id: lstring.c,v 2.3 2004/08/24 20:12:06 roberto Exp roberto $
 ** String table (keeps all strings handled by Lua)
 ** See Copyright Notice in lua.h
 */
@@ -49,8 +49,11 @@ void luaS_resize (lua_State *L, int newsize) {
 
 static TString *newlstr (lua_State *L, const char *str, size_t l,
                                        unsigned int h) {
-  TString *ts = cast(TString *, luaM_malloc(L, sizestring(l)));
+  TString *ts;
   stringtable *tb;
+  if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char))
+    luaM_toobig(L);
+  ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString)));
   ts->tsv.len = l;
   ts->tsv.hash = h;
   ts->tsv.marked = luaC_white(G(L));
@@ -92,7 +95,9 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
 
 Udata *luaS_newudata (lua_State *L, size_t s) {
   Udata *u;
-  u = cast(Udata *, luaM_malloc(L, sizeudata(s)));
+  if (s > MAX_SIZET - sizeof(Udata))
+    luaM_toobig(L);
+  u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata)));
   u->uv.marked = luaC_white(G(L));  /* is not finalized */
   u->uv.tt = LUA_TUSERDATA;
   u->uv.len = s;

+ 3 - 4
lstring.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lstring.h,v 1.38 2003/11/17 19:50:05 roberto Exp roberto $
+** $Id: lstring.h,v 1.39 2004/08/24 20:12:06 roberto Exp roberto $
 ** String table (keep all strings handled by Lua)
 ** See Copyright Notice in lua.h
 */
@@ -13,10 +13,9 @@
 #include "lstate.h"
 
 
-#define sizestring(l)	(cast(lu_mem, sizeof(union TString))+ \
-                         (cast(lu_mem, l)+1)*sizeof(char))
+#define sizestring(s)	(sizeof(union TString)+((s)->len+1)*sizeof(char))
 
-#define sizeudata(l)	(cast(lu_mem, sizeof(union Udata))+(l))
+#define sizeudata(u)	(sizeof(union Udata)+(u)->len)
 
 #define luaS_new(L, s)	(luaS_newlstr(L, s, strlen(s)))
 #define luaS_newliteral(L, s)	(luaS_newlstr(L, "" s, \