aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lpvm.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/lpvm.c b/lpvm.c
index af9e617..f7c7e62 100644
--- a/lpvm.c
+++ b/lpvm.c
@@ -80,16 +80,25 @@ typedef struct Stack {
80** array, it is simpler to ensure the array always has at least one free 80** array, it is simpler to ensure the array always has at least one free
81** slot upfront and check its size later.) 81** slot upfront and check its size later.)
82*/ 82*/
83
84/* new size in number of elements cannot overflow integers, and new
85 size in bytes cannot overflow size_t. */
86#define MAXNEWSIZE \
87 (((size_t)INT_MAX) <= (~(size_t)0 / sizeof(Capture)) ? \
88 ((size_t)INT_MAX) : (~(size_t)0 / sizeof(Capture)))
89
83static Capture *growcap (lua_State *L, Capture *capture, int *capsize, 90static Capture *growcap (lua_State *L, Capture *capture, int *capsize,
84 int captop, int n, int ptop) { 91 int captop, int n, int ptop) {
85 if (*capsize - captop > n) 92 if (*capsize - captop > n)
86 return capture; /* no need to grow array */ 93 return capture; /* no need to grow array */
87 else { /* must grow */ 94 else { /* must grow */
88 Capture *newc; 95 Capture *newc;
89 int newsize = captop + n + 1; /* minimum size needed */ 96 unsigned int newsize = captop + n + 1; /* minimum size needed */
90 if (newsize < INT_MAX/((int)sizeof(Capture) * 2)) 97 if (newsize < MAXNEWSIZE / 2)
91 newsize *= 2; /* twice that size, if not too big */ 98 newsize *= 2; /* twice that size, if not too big */
92 else if (newsize >= INT_MAX/((int)sizeof(Capture))) 99 else if (newsize < (MAXNEWSIZE / 9) * 8)
100 newsize += newsize / 8; /* else, try 9/8 that size */
101 else
93 luaL_error(L, "too many captures"); 102 luaL_error(L, "too many captures");
94 newc = (Capture *)lua_newuserdata(L, newsize * sizeof(Capture)); 103 newc = (Capture *)lua_newuserdata(L, newsize * sizeof(Capture));
95 memcpy(newc, capture, captop * sizeof(Capture)); 104 memcpy(newc, capture, captop * sizeof(Capture));
@@ -329,7 +338,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
329 case IFailTwice: 338 case IFailTwice:
330 assert(stack > getstackbase(L, ptop)); 339 assert(stack > getstackbase(L, ptop));
331 stack--; 340 stack--;
332 /* go through */ 341 /* FALLTHROUGH */
333 case IFail: 342 case IFail:
334 fail: { /* pattern failed: try to backtrack */ 343 fail: { /* pattern failed: try to backtrack */
335 do { /* remove pending calls */ 344 do { /* remove pending calls */