summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReuben Thomas <rrt@sc3d.org>2013-01-08 00:54:08 +0000
committerReuben Thomas <rrt@sc3d.org>2013-01-08 00:54:08 +0000
commitfadff3495c6973eac77bffd115cde3007668a206 (patch)
tree12b78a221f2b90e1d4994f974b042cabe1431e4f
parentcdd65f33ec817c31820e2a7673c33a63df72c12c (diff)
downloadlrexlib-fadff3495c6973eac77bffd115cde3007668a206.tar.gz
Complete the use of the Lua state allocator.
The original work, in commit 44176181c728, failed to call the lua_Alloc function to free allocated memory. Thanks to George Zhao for the report (issue #3). Lrealloc and Lfree functions were added to mirror Lmalloc and simplify the code. In the process two other bugs turned up. First, one caller of Lmalloc tried to take action if the allocation failed, but this was ineffective, as Lmalloc called luaL_error. Hence, Lmalloc was changed not to abort on error. Secondly, in lgnu.c, Lmalloc was called erroneously, to allocate a buffer later freed by regfree (and hence by free); this was corrected to call malloc. The resulting code has been tested with both Lua 5.2 and luajit 2.0.0-beta9.
-rw-r--r--src/common.c29
-rw-r--r--src/common.h2
-rw-r--r--src/gnu/lgnu.c4
-rw-r--r--src/pcre/lpcre.c14
-rw-r--r--src/posix/lposix.c4
-rw-r--r--src/tre/ltre.c4
-rw-r--r--src/tre/ltre_w.c2
7 files changed, 39 insertions, 20 deletions
diff --git a/src/common.c b/src/common.c
index c50ea61..1b1323e 100644
--- a/src/common.c
+++ b/src/common.c
@@ -30,10 +30,19 @@ void set_int_field (lua_State *L, const char* field, int val)
void *Lmalloc(lua_State *L, size_t size) {
void *ud;
lua_Alloc lalloc = lua_getallocf(L, &ud);
- void *p = lalloc(ud, NULL, 0, size);
- if(p == NULL)
- luaL_error(L, "malloc failed");
- return p;
+ return lalloc(ud, NULL, 0, size);
+}
+
+void *Lrealloc(lua_State *L, void *p, size_t osize, size_t nsize) {
+ void *ud;
+ lua_Alloc lalloc = lua_getallocf(L, &ud);
+ return lalloc(ud, p, osize, nsize);
+}
+
+void Lfree(lua_State *L, void *p, size_t osize) {
+ void *ud;
+ lua_Alloc lalloc = lua_getallocf(L, &ud);
+ lalloc(ud, p, osize, 0);
}
/* This function fills a table with string-number pairs.
@@ -117,9 +126,7 @@ void freelist_free (TFreeList *fl) {
enum { ID_NUMBER, ID_STRING };
void buffer_init (TBuffer *buf, size_t sz, lua_State *L, TFreeList *fl) {
- void *ud;
- lua_Alloc lalloc = lua_getallocf(L, &ud);
- buf->arr = (char*) lalloc (ud, NULL, 0, sz);
+ buf->arr = Lmalloc(L, sz);
if (!buf->arr) {
freelist_free (fl);
luaL_error (L, "malloc failed");
@@ -132,9 +139,7 @@ void buffer_init (TBuffer *buf, size_t sz, lua_State *L, TFreeList *fl) {
}
void buffer_free (TBuffer *buf) {
- void *ud;
- lua_Alloc lalloc = lua_getallocf(buf->L, &ud);
- lalloc (ud, buf->arr, buf->size, 0);
+ Lfree(buf->L, buf->arr, buf->size);
}
void buffer_clear (TBuffer *buf) {
@@ -152,9 +157,7 @@ void buffer_addbuffer (TBuffer *trg, TBuffer *src) {
void buffer_addlstring (TBuffer *buf, const void *src, size_t sz) {
size_t newtop = buf->top + sz;
if (newtop > buf->size) {
- void *ud;
- lua_Alloc lalloc = lua_getallocf(buf->L, &ud);
- char *p = (char*) lalloc (ud, buf->arr, buf->size, 2 * newtop); /* 2x expansion */
+ char *p = (char*) Lrealloc (buf->L, buf->arr, buf->size, 2 * newtop); /* 2x expansion */
if (!p) {
freelist_free (buf->freelist);
luaL_error (buf->L, "realloc failed");
diff --git a/src/common.h b/src/common.h
index ee8dd52..e457754 100644
--- a/src/common.h
+++ b/src/common.h
@@ -92,5 +92,7 @@ void set_int_field (lua_State *L, const char* field, int val);
int get_flags (lua_State *L, const flag_pair **arr);
const char *get_flag_key (const flag_pair *fp, int val);
void *Lmalloc (lua_State *L, size_t size);
+void *Lrealloc (lua_State *L, void *p, size_t osize, size_t nsize);
+void Lfree (lua_State *L, void *p, size_t size);
#endif
diff --git a/src/gnu/lgnu.c b/src/gnu/lgnu.c
index c5da82e..54b73ec 100644
--- a/src/gnu/lgnu.c
+++ b/src/gnu/lgnu.c
@@ -105,7 +105,9 @@ static const unsigned char *gettranslate (lua_State *L, int pos) {
if (lua_isnoneornil (L, pos))
return NULL;
- translate = (const unsigned char *) Lmalloc (L, ALG_TRANSLATE_SIZE);
+ translate = (const unsigned char *) malloc (ALG_TRANSLATE_SIZE);
+ if (!translate)
+ luaL_error (L, "malloc failed");
memset ((unsigned char *) translate, 0, ALG_TRANSLATE_SIZE); /* initialize all members to 0 */
for (i = 0; i <= UCHAR_MAX; i++) {
lua_pushinteger (L, i);
diff --git a/src/pcre/lpcre.c b/src/pcre/lpcre.c
index 2ac56eb..87d1a56 100644
--- a/src/pcre/lpcre.c
+++ b/src/pcre/lpcre.c
@@ -221,6 +221,8 @@ static int compile_regex (lua_State *L, const TArgComp *argC, TPcre **pud) {
pcre_fullinfo (ud->pr, ud->extra, PCRE_INFO_CAPTURECOUNT, &ud->ncapt);
/* need (2 ints per capture, plus one for substring match) * 3/2 */
ud->match = (int *) Lmalloc (L, (ALG_NSUB(ud) + 1) * 3 * sizeof (int));
+ if (!ud->match)
+ luaL_error (L, "malloc failed");
if (pud) *pud = ud;
return 1;
@@ -258,9 +260,13 @@ static int Lpcre_dfa_exec (lua_State *L)
TPcre *ud;
int res;
int *buf, *ovector, *wspace;
+ size_t bufsize;
checkarg_dfa_exec (L, &argE, &ud);
- buf = (int*) Lmalloc (L, (argE.ovecsize + argE.wscount) * sizeof(int));
+ bufsize = (argE.ovecsize + argE.wscount) * sizeof(int);
+ buf = (int*) Lmalloc (L, bufsize);
+ if (!buf)
+ luaL_error (L, "malloc failed");
ovector = buf;
wspace = buf + argE.ovecsize;
@@ -277,11 +283,11 @@ static int Lpcre_dfa_exec (lua_State *L)
lua_rawseti (L, -2, i+1);
}
lua_pushinteger (L, res); /* 3-rd return value */
- free (buf);
+ Lfree (L, buf, bufsize);
return 3;
}
else {
- free (buf);
+ Lfree (L, buf, bufsize);
if (ALG_NOMATCH (res))
return lua_pushnil (L), 1;
else
@@ -337,7 +343,7 @@ static int Lpcre_gc (lua_State *L) {
if (ud->pr) pcre_free (ud->pr);
if (ud->extra) pcre_free (ud->extra);
if (ud->tables) pcre_free ((void *)ud->tables);
- free (ud->match);
+ Lfree (L, ud->match, (ALG_NSUB(ud) + 1) * 3 * sizeof (int));
}
return 0;
}
diff --git a/src/posix/lposix.c b/src/posix/lposix.c
index 77fa761..52908d8 100644
--- a/src/posix/lposix.c
+++ b/src/posix/lposix.c
@@ -110,6 +110,8 @@ static int compile_regex (lua_State *L, const TArgComp *argC, TPosix **pud) {
if (argC->cflags & REG_NOSUB)
ud->r.re_nsub = 0;
ud->match = (regmatch_t *) Lmalloc (L, (ALG_NSUB(ud) + 1) * sizeof (regmatch_t));
+ if (!ud->match)
+ luaL_error (L, "malloc failed");
lua_pushvalue (L, ALG_ENVIRONINDEX);
lua_setmetatable (L, -2);
@@ -184,7 +186,7 @@ static int Posix_gc (lua_State *L) {
if (ud->freed == 0) { /* precaution against "manual" __gc calling */
ud->freed = 1;
regfree (&ud->r);
- free (ud->match);
+ Lfree (L, ud->match, (ALG_NSUB(ud) + 1) * sizeof (regmatch_t));
}
return 0;
}
diff --git a/src/tre/ltre.c b/src/tre/ltre.c
index 06c66c8..d734434 100644
--- a/src/tre/ltre.c
+++ b/src/tre/ltre.c
@@ -108,6 +108,8 @@ static int compile_regex (lua_State *L, const TArgComp *argC, TPosix **pud) {
if (argC->cflags & REG_NOSUB)
ud->r.re_nsub = 0;
ud->match = (regmatch_t *) Lmalloc (L, (ALG_NSUB(ud) + 1) * sizeof (regmatch_t));
+ if (!ud->match)
+ luaL_error (L, "malloc failed");
lua_pushvalue (L, ALG_ENVIRONINDEX);
lua_setmetatable (L, -2);
@@ -209,7 +211,7 @@ static int Ltre_gc (lua_State *L) {
if (ud->freed == 0) { /* precaution against "manual" __gc calling */
ud->freed = 1;
tre_regfree (&ud->r);
- free (ud->match);
+ Lfree (L, ud->match, (ALG_NSUB(ud) + 1) * sizeof (regmatch_t));
}
return 0;
}
diff --git a/src/tre/ltre_w.c b/src/tre/ltre_w.c
index 4744cb1..c335346 100644
--- a/src/tre/ltre_w.c
+++ b/src/tre/ltre_w.c
@@ -111,6 +111,8 @@ static int compile_regex (lua_State *L, const TArgComp *argC, TPosix **pud) {
if (argC->cflags & REG_NOSUB)
ud->r.re_nsub = 0;
ud->match = (regmatch_t *) Lmalloc (L, (ALG_NSUB(ud) + 1) * sizeof (regmatch_t));
+ if (!ud->match)
+ luaL_error (L, "malloc failed");
lua_pushvalue (L, ALG_ENVIRONINDEX);
lua_setmetatable (L, -2);