diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-12-07 16:59:52 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-12-07 16:59:52 -0200 |
commit | 76223730332cbda5d47c09f019ce721b91bd5be2 (patch) | |
tree | 375c159891df5faf827dde4175ce42b7aa503194 /lmem.c | |
parent | 46bc7f2bf7cf7f48c354fde6b9571b795bdd5b4d (diff) | |
download | lua-76223730332cbda5d47c09f019ce721b91bd5be2.tar.gz lua-76223730332cbda5d47c09f019ce721b91bd5be2.tar.bz2 lua-76223730332cbda5d47c09f019ce721b91bd5be2.zip |
using explicit tests for allocation overflow whenever possible
Diffstat (limited to 'lmem.c')
-rw-r--r-- | lmem.c | 28 |
1 files changed, 15 insertions, 13 deletions
@@ -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 | ||
56 | void *luaM_growaux_ (lua_State *L, void *block, int nelems, int *size, | 56 | void *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 | */ |
116 | void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { | 118 | void *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)); |