Bug Summary

File:luaext/lrexlib.c
Warning:line 114, column 12
Potential leak of memory pointed to by 'match'

Annotated Source Code

1/* lrexlib.c - POSIX & PCRE regular expression library */
2/* POSIX regexs can use Spencer extensions for matching NULs if available
3 (REG_BASIC) */
4/* Reuben Thomas nov00-06oct03 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9
10#include "lua.h"
11#include "lauxlib.h"
12#include "lrexlib.h"
13
14
15/* Sanity check */
16#if !defined(WITH_POSIX1) && !defined(WITH_PCRE)
17#error Define WITH_POSIX1 or WITH_PCRE, otherwise this library is useless!
18#endif
19
20
21/* POSIX regex methods */
22
23#ifdef WITH_POSIX1
24
25#include <regex.h>
26
27static int rex_comp(lua_State *L)
28{
29 size_t l;
30 const char *pattern;
31 int res;
32 regex_t *pr = (regex_t *)lua_newuserdata(L, sizeof(regex_t));
33 pattern = luaL_checklstring(L, 1, &l);
34#ifdef REG_BASIC
35 pr->re_endp = pattern + lua_strlen(L, 1)lua_rawlen(L, (1));
36 res = regcomp(pr, pattern, REG_EXTENDED1 | REG_PEND);
37#else
38 res = regcomp(pr, pattern, REG_EXTENDED1);
39#endif
40 if (res) {
41 size_t sz = regerror(res, pr, NULL((void*)0), 0);
42 char errbuf[sz];
43 regerror(res, pr, errbuf, sz);
44 lua_pushstring(L, errbuf);
45 lua_error(L);
46 }
47 luaL_getmetatable(L, "regex_t")(lua_getfield(L, (-1000000 - 1000), ("regex_t")));
48 lua_setmetatable(L, -2);
49 return 1;
50}
51
52static void rex_getargs(lua_State *L, size_t *len, size_t *ncapt,
53 const char **text, regex_t **pr, regmatch_t **match)
54{
55 luaL_checkany(L, 1);
56 *pr = (regex_t *)lua_touserdata(L, 1);
57#ifdef REG_BASIC
58 *text = luaL_checklstring(L, 2, len);
59#else
60 *text = luaL_checklstring(L, 2, NULL((void*)0));
61#endif
62 *ncapt = (*pr)->re_nsub;
63 luaL_checkstack(L, *ncapt + 2, "too many captures");
64 *match = malloc((*ncapt + 1) * sizeof(regmatch_t));
2
Memory is allocated
65}
66
67static void rex_push_matches(lua_State *L, const char *text, regmatch_t *match,
68 size_t ncapt)
69{
70 size_t i;
71 lua_newtable(L)lua_createtable(L, 0, 0);
72 for (i = 1; i <= ncapt; i++) {
73 if (match[i].rm_so >= 0) {
74 lua_pushlstring(L, text + match[i].rm_so,
75 match[i].rm_eo - match[i].rm_so);
76 lua_rawseti(L, -2, i);
77 }
78 }
79}
80
81static int rex_match(lua_State *L)
82{
83 int res;
84#ifdef REG_BASIC
85 size_t len;
86#endif
87 size_t ncapt;
88 const char *text;
89 regex_t *pr;
90 regmatch_t *match;
91 rex_getargs(L,
1
Calling 'rex_getargs'
3
Returned allocated memory via 6th parameter
92#ifdef REG_BASIC
93 &len,
94#else
95 NULL((void*)0),
96#endif
97 &ncapt, &text, &pr, &match);
98#ifdef REG_BASIC
99 match[0].rm_so = 0;
100 match[0].rm_eo = len;
101 res = regexec(pr, text, ncapt + 1, match, REG_STARTEND(1 << 2));
102#else
103 res = regexec(pr, text, ncapt + 1, match, 0);
104#endif
105 if (res == 0) {
4
Assuming 'res' is not equal to 0
5
Taking false branch
106 lua_pushnumber(L, match[0].rm_so + 1);
107 lua_pushnumber(L, match[0].rm_eo);
108 rex_push_matches(L, text, match, ncapt);
109 lua_pushstring(L, "n");
110 lua_pushnumber(L, ncapt);
111 lua_rawset(L, -3);
112 return 3;
113 } else
114 return 0;
6
Potential leak of memory pointed to by 'match'
115}
116
117static int rex_gmatch(lua_State *L)
118{
119 int res;
120#ifdef REG_BASIC
121 size_t len;
122#endif
123 size_t ncapt, nmatch = 0, maxmatch = 0, limit = 0;
124 const char *text;
125 regex_t *pr;
126 regmatch_t *match;
127 rex_getargs(L,
128#ifdef REG_BASIC
129 &len,
130#else
131 NULL((void*)0),
132#endif
133 &ncapt, &text, &pr, &match);
134 luaL_checktype(L, 3, LUA_TFUNCTION6);
135 if (lua_gettop(L) > 3) {
136 maxmatch = (size_t)luaL_checknumber(L, 4);
137 limit = 1;
138 }
139 while (!limit || nmatch < maxmatch) {
140#ifdef REG_BASIC
141 match[0].rm_so = 0;
142 match[0].rm_eo = len;
143 res = regexec(pr, text, ncapt + 1, match, REG_STARTEND(1 << 2));
144#else
145 res = regexec(pr, text, ncapt + 1, match, 0);
146#endif
147 if (res == 0) {
148 lua_pushvalue(L, 3);
149 lua_pushlstring(L, text + match[0].rm_so, match[0].rm_eo - match[0].rm_so);
150 rex_push_matches(L, text, match, ncapt);
151 lua_call(L, 2, 0)lua_callk(L, (2), (0), 0, ((void*)0));
152 text += match[0].rm_eo;
153#ifdef REG_BASIC
154 len -= match[0].rm_eo;
155#endif
156 nmatch++;
157 } else
158 break;
159 }
160 lua_pushnumber(L, nmatch);
161 return 1;
162}
163
164static int rex_gc (lua_State *L)
165{
166 regex_t *r = (regex_t *)luaL_checkudata(L, 1, "regex_t");
167 if (r)
168 regfree(r);
169 return 0;
170}
171
172static const luaL_Reg rexmeta[] = {
173 {"match", rex_match},
174 {"gmatch", rex_gmatch},
175 {"__gc", rex_gc},
176 {NULL((void*)0), NULL((void*)0)}
177};
178
179#endif /* WITH_POSIX */
180
181
182/* PCRE methods */
183
184#ifdef WITH_PCRE
185
186#include <pcre/pcre.h>
187
188static int pcre_comp(lua_State *L)
189{
190 size_t l;
191 const char *pattern;
192 const char *error;
193 int erroffset;
194 pcre **ppr = (pcre **)lua_newuserdata(L, sizeof(pcre **));
195 pcre *pr;
196 pattern = luaL_checklstring(L, 1, &l);
197 pr = pcre_compile(pattern, 0, &error, &erroffset, NULL((void*)0));
198 if (!pr) {
199 lua_pushstring(L, error);
200 lua_error(L);
201 }
202 *ppr = pr;
203 luaL_getmetatable(L, "pcre")(lua_getfield(L, (-1000000 - 1000), ("pcre")));
204 lua_setmetatable(L, -2);
205 return 1;
206}
207
208static void pcre_getargs(lua_State *L, int *len, int *ncapt, const char **text,
209 pcre ***ppr, int **match)
210{
211 luaL_checkany(L, 1);
212 *ppr = (pcre **)lua_touserdata(L, 1);
213 *text = luaL_checklstring(L, 2, len);
214 pcre_fullinfo(**ppr, NULL((void*)0), PCRE_INFO_CAPTURECOUNT, ncapt);
215 luaL_checkstack(L, *ncapt + 2, "too many captures");
216 /* need (2 ints per capture, plus one for substring match) * 3/2 */
217 *match = malloc((*ncapt + 1) * 3 * sizeof(int));
218}
219
220static void pcre_push_matches(lua_State *L, const char *text, int *match,
221 int ncapt)
222{
223 int i;
224 lua_newtable(L)lua_createtable(L, 0, 0);
225 for (i = 1; i <= ncapt; i++) {
226 if (match[i * 2] >= 0) {
227 lua_pushlstring(L, text + match[i * 2],
228 match[i * 2 + 1] - match[i * 2]);
229 lua_rawseti(L, -2, i);
230 }
231 }
232}
233
234static int pcre_match(lua_State *L)
235{
236 int res;
237 const char *text;
238 pcre **ppr;
239 int *match;
240 int ncapt;
241 int len;
242 pcre_getargs(L, &len, &ncapt, &text, &ppr, &match);
243 res = pcre_exec(*ppr, NULL((void*)0), text, len, 0, 0, match, (ncapt + 1) * 3);
244 if (res >= 0) {
245 lua_pushnumber(L, match[0] + 1);
246 lua_pushnumber(L, match[1]);
247 pcre_push_matches(L, text, match, ncapt);
248 lua_pushstring(L, "n");
249 lua_pushnumber(L, ncapt);
250 lua_rawset(L, -3);
251 return 3;
252 } else
253 return 0;
254}
255
256static int pcre_gmatch(lua_State *L)
257{
258 int res;
259 const char *text;
260 int limit = 0;
261 int ncapt, nmatch = 0, maxmatch;
262 pcre **ppr;
263 int *match;
264 int len;
265 pcre_getargs(L, &len, &ncapt, &text, &ppr, &match);
266 luaL_checktype(L, 3, LUA_TFUNCTION6);
267 if (lua_gettop(L) > 3) {
268 maxmatch = (int)luaL_checknumber(L, 4);
269 limit = 1;
270 }
271 while (!limit || nmatch < maxmatch) {
272 res = pcre_exec(*ppr, NULL((void*)0), text, len, 0, 0, match, (ncapt + 1) * 3);
273 if (res == 0) {
274 lua_pushvalue(L, 3);
275 lua_pushlstring(L, text + match[0], match[1] - match[0]);
276 pcre_push_matches(L, text, match, ncapt);
277 lua_call(L, 2, 0)lua_callk(L, (2), (0), 0, ((void*)0));
278 text += match[1];
279 len -= match[1];
280 nmatch++;
281 } else
282 break;
283 }
284 lua_pushnumber(L, nmatch);
285 return 1;
286}
287
288static int pcre_gc (lua_State *L)
289{
290 pcre **ppr = (pcre **)luaL_checkudata(L, 1, "pcre");
291 if (ppr)
292 pcre_free(*ppr);
293 return 0;
294}
295
296static const luaL_reg pcremeta[] = {
297 {"match", pcre_match},
298 {"gmatch", pcre_gmatch},
299 {"__gc", pcre_gc},
300 {NULL((void*)0), NULL((void*)0)}
301};
302
303#endif /* defined(WITH_PCRE) */
304
305
306/* Open the library */
307
308static const luaL_Reg rexlib[] = {
309#ifdef WITH_POSIX1
310 {"newPOSIX", rex_comp},
311#endif
312#ifdef WITH_PCRE
313 {"newPCRE", pcre_comp},
314#endif
315 {NULL((void*)0), NULL((void*)0)}
316};
317
318static void createmeta(lua_State *L, const char *name)
319{
320 luaL_newmetatable(L, name); /* create new metatable */
321 lua_pushliteral(L, "__index")lua_pushstring(L, "" "__index");
322 lua_pushvalue(L, -2); /* push metatable */
323 lua_rawset(L, -3); /* metatable.__index = metatable */
324}
325
326LUALIB_APIextern int luaopen_rex(lua_State *L)
327{
328#ifdef WITH_POSIX1
329 createmeta(L, "regex_t");
330 luaL_openlib(L, NULL((void*)0), rexmeta, 0);
331 lua_pop(L, 1)lua_settop(L, -(1)-1);
332#endif
333#ifdef WITH_PCRE
334 createmeta(L, "pcre");
335 luaL_openlib(L, NULL((void*)0), pcremeta, 0);
336 lua_pop(L, 1)lua_settop(L, -(1)-1);
337#endif
338 luaL_openlib(L, "rex", rexlib, 0);
339 return 1;
340}