aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lmem.c28
-rw-r--r--lmem.h32
-rw-r--r--lstring.c12
-rw-r--r--ltable.c38
-rw-r--r--lundump.c16
5 files changed, 80 insertions, 46 deletions
diff --git a/lmem.c b/lmem.c
index ebbfb56a..23dc14d6 100644
--- a/lmem.c
+++ b/lmem.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lmem.c,v 1.91 2015/03/06 19:45:54 roberto Exp roberto $ 2** $Id: lmem.c,v 1.92 2017/12/06 18:36:31 roberto Exp roberto $
3** Interface to Memory Manager 3** Interface to Memory Manager
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -53,24 +53,26 @@
53#define MINSIZEARRAY 4 53#define MINSIZEARRAY 4
54 54
55 55
56void *luaM_growaux_ (lua_State *L, void *block, int nelems, int *size, 56void *luaM_growaux_ (lua_State *L, void *block, int nelems, int *psize,
57 int size_elems, int limit, const char *what) { 57 int size_elems, int limit, const char *what) {
58 void *newblock; 58 void *newblock;
59 int newsize; 59 int size = *psize;
60 if (nelems + 1 <= *size) /* does one extra element still fit? */ 60 if (nelems + 1 <= size) /* does one extra element still fit? */
61 return block; /* nothing to be done */ 61 return block; /* nothing to be done */
62 if (*size >= limit/2) { /* cannot double it? */ 62 if (size >= limit / 2) { /* cannot double it? */
63 if (*size >= limit) /* cannot grow even a little? */ 63 if (size >= limit) /* cannot grow even a little? */
64 luaG_runerror(L, "too many %s (limit is %d)", what, limit); 64 luaG_runerror(L, "too many %s (limit is %d)", what, limit);
65 newsize = limit; /* still have at least one free place */ 65 size = limit; /* still have at least one free place */
66 } 66 }
67 else { 67 else {
68 newsize = (*size)*2; 68 size *= 2;
69 if (newsize < MINSIZEARRAY) 69 if (size < MINSIZEARRAY)
70 newsize = MINSIZEARRAY; /* minimum size */ 70 size = MINSIZEARRAY; /* minimum size */
71 } 71 }
72 newblock = luaM_reallocv(L, block, *size, newsize, size_elems); 72 /* 'limit' ensures that multiplication will not overflow */
73 *size = newsize; /* update only when everything else is OK */ 73 newblock = luaM_realloc(L, block, cast(size_t, *psize) * size_elems,
74 cast(size_t, size) * size_elems);
75 *psize = size; /* update only when everything else is OK */
74 return newblock; 76 return newblock;
75} 77}
76 78
@@ -113,7 +115,7 @@ void luaM_free_ (lua_State *L, void *block, size_t osize) {
113/* 115/*
114** generic allocation routine. 116** generic allocation routine.
115*/ 117*/
116void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { 118void *luaM_realloc (lua_State *L, void *block, size_t osize, size_t nsize) {
117 void *newblock; 119 void *newblock;
118 global_State *g = G(L); 120 global_State *g = G(L);
119 lua_assert((osize == 0) == (block == NULL)); 121 lua_assert((osize == 0) == (block == NULL));
diff --git a/lmem.h b/lmem.h
index 4ccb88ab..3c828789 100644
--- a/lmem.h
+++ b/lmem.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lmem.h,v 1.43 2014/12/19 17:26:14 roberto Exp roberto $ 2** $Id: lmem.h,v 1.44 2017/12/06 18:36:31 roberto Exp roberto $
3** Interface to Memory Manager 3** Interface to Memory Manager
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -31,36 +31,40 @@
31#define luaM_checksize(L,n,e) \ 31#define luaM_checksize(L,n,e) \
32 (luaM_testsize(n,e) ? luaM_toobig(L) : cast_void(0)) 32 (luaM_testsize(n,e) ? luaM_toobig(L) : cast_void(0))
33 33
34
34/* 35/*
35** This macro reallocs a vector 'b' from 'on' to 'n' elements, where 36** Computes the minimum between 'n' and 'MAX_SIZET/sizeof(t)', so that
36** each element has size 'e'. In case of arithmetic overflow of the 37** the result is not larger than 'n' and cannot overflow a 'size_t'
37** product 'n'*'e', it raises an error (calling 'luaM_toobig'). 38** when multiplied by the size of type 't'. (Assumes that 'n' is an
39** 'int' or 'unsigned int' and that 'int' is not larger than 'size_t'.)
38*/ 40*/
39#define luaM_reallocv(L,b,on,n,e) \ 41#define luaM_limitN(n,t) \
40 (luaM_checksize(L,n,e), \ 42 ((cast(size_t, n) > MAX_SIZET/sizeof(t)) ? (MAX_SIZET/sizeof(t)) : (n))
41 luaM_realloc_(L, (b), cast(size_t, on)*(e), cast(size_t, n)*(e)))
42 43
43/* 44/*
44** Arrays of chars do not need any test 45** Arrays of chars do not need any test
45*/ 46*/
46#define luaM_reallocvchar(L,b,on,n) \ 47#define luaM_reallocvchar(L,b,on,n) \
47 cast(char *, luaM_realloc_(L, (b), (on)*sizeof(char), (n)*sizeof(char))) 48 cast(char *, luaM_realloc(L, (b), (on)*sizeof(char), (n)*sizeof(char)))
48 49
49#define luaM_freemem(L, b, s) luaM_free_(L, (b), (s)) 50#define luaM_freemem(L, b, s) luaM_free_(L, (b), (s))
50#define luaM_free(L, b) luaM_free_(L, (b), sizeof(*(b))) 51#define luaM_free(L, b) luaM_free_(L, (b), sizeof(*(b)))
51#define luaM_freearray(L, b, n) luaM_free_(L, (b), (n)*sizeof(*(b))) 52#define luaM_freearray(L, b, n) luaM_free_(L, (b), (n)*sizeof(*(b)))
52 53
53#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t), 0)) 54#define luaM_new(L,t) cast(t*, luaM_malloc(L, sizeof(t), 0))
54#define luaM_newvector(L,n,t) \ 55#define luaM_newvector(L,n,t) cast(t*, luaM_malloc(L, (n)*sizeof(t), 0))
55 (luaM_checksize(L,n,sizeof(t)), cast(t *, luaM_malloc(L, (n)*sizeof(t), 0))) 56#define luaM_newvectorchecked(L,n,t) \
57 (luaM_checksize(L,n,sizeof(t)), luaM_newvector(L,n,t))
56 58
57#define luaM_newobject(L,tag,s) luaM_malloc(L, (s), tag) 59#define luaM_newobject(L,tag,s) luaM_malloc(L, (s), tag)
58 60
59#define luaM_growvector(L,v,nelems,size,t,limit,e) \ 61#define luaM_growvector(L,v,nelems,size,t,limit,e) \
60 ((v)=cast(t *, luaM_growaux_(L,v,nelems,&(size),sizeof(t),limit,e))) 62 ((v)=cast(t *, luaM_growaux_(L,v,nelems,&(size),sizeof(t), \
63 luaM_limitN(limit,t),e)))
61 64
62#define luaM_reallocvector(L, v,oldn,n,t) \ 65#define luaM_reallocvector(L, v,oldn,n,t) \
63 ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) 66 ((v)=cast(t *, luaM_realloc(L, v, cast(size_t, oldn) * sizeof(t), \
67 cast(size_t, n) * sizeof(t))))
64 68
65#define luaM_shrinkvector(L,v,size,fs,t) \ 69#define luaM_shrinkvector(L,v,size,fs,t) \
66 ((v)=cast(t *, luaM_shrinkvector_(L, v, &(size), fs, sizeof(t)))) 70 ((v)=cast(t *, luaM_shrinkvector_(L, v, &(size), fs, sizeof(t))))
@@ -68,7 +72,7 @@
68LUAI_FUNC l_noret luaM_toobig (lua_State *L); 72LUAI_FUNC l_noret luaM_toobig (lua_State *L);
69 73
70/* not to be called directly */ 74/* not to be called directly */
71LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, 75LUAI_FUNC void *luaM_realloc (lua_State *L, void *block, size_t oldsize,
72 size_t size); 76 size_t size);
73LUAI_FUNC void luaM_free_ (lua_State *L, void *block, size_t osize); 77LUAI_FUNC void luaM_free_ (lua_State *L, void *block, size_t osize);
74LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int nelems, 78LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int nelems,
diff --git a/lstring.c b/lstring.c
index e8f6f5c9..1b3f53e1 100644
--- a/lstring.c
+++ b/lstring.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstring.c,v 2.57 2017/07/27 13:50:16 roberto Exp roberto $ 2** $Id: lstring.c,v 2.58 2017/12/01 16:40:29 roberto Exp roberto $
3** String table (keeps all strings handled by Lua) 3** String table (keeps all strings handled by Lua)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -31,6 +31,13 @@
31#endif 31#endif
32 32
33 33
34
35/*
36** Maximum size for string table.
37*/
38#define MAXSTRTB cast_int(luaM_limitN(MAX_INT, TString*))
39
40
34/* 41/*
35** equality for long strings 42** equality for long strings
36*/ 43*/
@@ -173,7 +180,8 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) {
173 return ts; 180 return ts;
174 } 181 }
175 } 182 }
176 if (g->strt.nuse >= g->strt.size && g->strt.size <= MAX_INT/2) { 183 if (g->strt.nuse >= g->strt.size &&
184 g->strt.size <= MAXSTRTB / 2) {
177 luaS_resize(L, g->strt.size * 2); 185 luaS_resize(L, g->strt.size * 2);
178 list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */ 186 list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */
179 } 187 }
diff --git a/ltable.c b/ltable.c
index 54799c21..d1345009 100644
--- a/ltable.c
+++ b/ltable.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.c,v 2.126 2017/11/08 14:50:23 roberto Exp roberto $ 2** $Id: ltable.c,v 2.127 2017/11/23 19:29:04 roberto Exp roberto $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -40,21 +40,34 @@
40 40
41 41
42/* 42/*
43** Maximum size of array part (MAXASIZE) is 2^MAXABITS. MAXABITS is 43** MAXABITS is the largest integer such that MAXASIZE fits in an
44** the largest integer such that MAXASIZE fits in an unsigned int. 44** unsigned int.
45*/ 45*/
46#define MAXABITS cast_int(sizeof(int) * CHAR_BIT - 1) 46#define MAXABITS cast_int(sizeof(int) * CHAR_BIT - 1)
47#define MAXASIZE (1u << MAXABITS) 47
48 48
49/* 49/*
50** Maximum size of hash part is 2^MAXHBITS. MAXHBITS is the largest 50** MAXASIZE is the maximum size of the array part. It is the minimum
51** integer such that 2^MAXHBITS fits in a signed int. (Note that the 51** between 2^MAXABITS and the maximum size such that, measured in bytes,
52** maximum number of elements in a table, 2^MAXABITS + 2^MAXHBITS, still 52** it fits in a 'size_t'.
53** fits comfortably in an unsigned int.) 53*/
54#define MAXASIZE luaM_limitN(1u << MAXABITS, TValue)
55
56/*
57** MAXHBITS is the largest integer such that 2^MAXHBITS fits in a
58** signed int.
54*/ 59*/
55#define MAXHBITS (MAXABITS - 1) 60#define MAXHBITS (MAXABITS - 1)
56 61
57 62
63/*
64** MAXHSIZE is the maximum size of the hash part. It is the minimum
65** between 2^MAXHBITS and the maximum size such that, measured in bytes,
66** it fits in a 'size_t'.
67*/
68#define MAXHSIZE luaM_limitN(1u << MAXHBITS, Node)
69
70
58#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) 71#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
59 72
60#define hashstr(t,str) hashpow2(t, (str)->hash) 73#define hashstr(t,str) hashpow2(t, (str)->hash)
@@ -353,6 +366,13 @@ static void setarrayvector (lua_State *L, Table *t, unsigned int size) {
353} 366}
354 367
355 368
369/*
370** Creates an array for the hash part of a table with the given
371** size, or reuses the dummy node if size is zero.
372** The computation for size overflow is in two steps: the first
373** comparison ensures that the shift in the second one does not
374** overflow.
375*/
356static void setnodevector (lua_State *L, Table *t, unsigned int size) { 376static void setnodevector (lua_State *L, Table *t, unsigned int size) {
357 if (size == 0) { /* no elements to hash part? */ 377 if (size == 0) { /* no elements to hash part? */
358 t->node = cast(Node *, dummynode); /* use common 'dummynode' */ 378 t->node = cast(Node *, dummynode); /* use common 'dummynode' */
@@ -362,7 +382,7 @@ static void setnodevector (lua_State *L, Table *t, unsigned int size) {
362 else { 382 else {
363 int i; 383 int i;
364 int lsize = luaO_ceillog2(size); 384 int lsize = luaO_ceillog2(size);
365 if (lsize > MAXHBITS) 385 if (lsize > MAXHBITS || (1u << lsize) > MAXHSIZE)
366 luaG_runerror(L, "table overflow"); 386 luaG_runerror(L, "table overflow");
367 size = twoto(lsize); 387 size = twoto(lsize);
368 t->node = luaM_newvector(L, size, Node); 388 t->node = luaM_newvector(L, size, Node);
diff --git a/lundump.c b/lundump.c
index 489a1494..25ab102d 100644
--- a/lundump.c
+++ b/lundump.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lundump.c,v 2.47 2017/06/29 15:06:44 roberto Exp roberto $ 2** $Id: lundump.c,v 2.48 2017/11/28 11:19:07 roberto Exp roberto $
3** load precompiled Lua chunks 3** load precompiled Lua chunks
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -114,7 +114,7 @@ static TString *LoadString (LoadState *S) {
114 114
115static void LoadCode (LoadState *S, Proto *f) { 115static void LoadCode (LoadState *S, Proto *f) {
116 int n = LoadInt(S); 116 int n = LoadInt(S);
117 f->code = luaM_newvector(S->L, n, Instruction); 117 f->code = luaM_newvectorchecked(S->L, n, Instruction);
118 f->sizecode = n; 118 f->sizecode = n;
119 LoadVector(S, f->code, n); 119 LoadVector(S, f->code, n);
120} 120}
@@ -126,7 +126,7 @@ static void LoadFunction(LoadState *S, Proto *f, TString *psource);
126static void LoadConstants (LoadState *S, Proto *f) { 126static void LoadConstants (LoadState *S, Proto *f) {
127 int i; 127 int i;
128 int n = LoadInt(S); 128 int n = LoadInt(S);
129 f->k = luaM_newvector(S->L, n, TValue); 129 f->k = luaM_newvectorchecked(S->L, n, TValue);
130 f->sizek = n; 130 f->sizek = n;
131 for (i = 0; i < n; i++) 131 for (i = 0; i < n; i++)
132 setnilvalue(&f->k[i]); 132 setnilvalue(&f->k[i]);
@@ -159,7 +159,7 @@ static void LoadConstants (LoadState *S, Proto *f) {
159static void LoadProtos (LoadState *S, Proto *f) { 159static void LoadProtos (LoadState *S, Proto *f) {
160 int i; 160 int i;
161 int n = LoadInt(S); 161 int n = LoadInt(S);
162 f->p = luaM_newvector(S->L, n, Proto *); 162 f->p = luaM_newvectorchecked(S->L, n, Proto *);
163 f->sizep = n; 163 f->sizep = n;
164 for (i = 0; i < n; i++) 164 for (i = 0; i < n; i++)
165 f->p[i] = NULL; 165 f->p[i] = NULL;
@@ -173,7 +173,7 @@ static void LoadProtos (LoadState *S, Proto *f) {
173static void LoadUpvalues (LoadState *S, Proto *f) { 173static void LoadUpvalues (LoadState *S, Proto *f) {
174 int i, n; 174 int i, n;
175 n = LoadInt(S); 175 n = LoadInt(S);
176 f->upvalues = luaM_newvector(S->L, n, Upvaldesc); 176 f->upvalues = luaM_newvectorchecked(S->L, n, Upvaldesc);
177 f->sizeupvalues = n; 177 f->sizeupvalues = n;
178 for (i = 0; i < n; i++) 178 for (i = 0; i < n; i++)
179 f->upvalues[i].name = NULL; 179 f->upvalues[i].name = NULL;
@@ -187,18 +187,18 @@ static void LoadUpvalues (LoadState *S, Proto *f) {
187static void LoadDebug (LoadState *S, Proto *f) { 187static void LoadDebug (LoadState *S, Proto *f) {
188 int i, n; 188 int i, n;
189 n = LoadInt(S); 189 n = LoadInt(S);
190 f->lineinfo = luaM_newvector(S->L, n, ls_byte); 190 f->lineinfo = luaM_newvectorchecked(S->L, n, ls_byte);
191 f->sizelineinfo = n; 191 f->sizelineinfo = n;
192 LoadVector(S, f->lineinfo, n); 192 LoadVector(S, f->lineinfo, n);
193 n = LoadInt(S); 193 n = LoadInt(S);
194 f->abslineinfo = luaM_newvector(S->L, n, AbsLineInfo); 194 f->abslineinfo = luaM_newvectorchecked(S->L, n, AbsLineInfo);
195 f->sizeabslineinfo = n; 195 f->sizeabslineinfo = n;
196 for (i = 0; i < n; i++) { 196 for (i = 0; i < n; i++) {
197 f->abslineinfo[i].pc = LoadInt(S); 197 f->abslineinfo[i].pc = LoadInt(S);
198 f->abslineinfo[i].line = LoadInt(S); 198 f->abslineinfo[i].line = LoadInt(S);
199 } 199 }
200 n = LoadInt(S); 200 n = LoadInt(S);
201 f->locvars = luaM_newvector(S->L, n, LocVar); 201 f->locvars = luaM_newvectorchecked(S->L, n, LocVar);
202 f->sizelocvars = n; 202 f->sizelocvars = n;
203 for (i = 0; i < n; i++) 203 for (i = 0; i < n; i++)
204 f->locvars[i].varname = NULL; 204 f->locvars[i].varname = NULL;