mirror of
https://github.com/ccxvii/mujs.git
synced 2026-02-05 17:29:43 +08:00
Issue #162: Check stack overflow during regexp compilation.
Only bother checking during the first compilation pass that counts the size of the program.
This commit is contained in:
21
regexp.c
21
regexp.c
@@ -622,25 +622,26 @@ struct Reinst {
|
||||
Reinst *y;
|
||||
};
|
||||
|
||||
static int count(struct cstate *g, Renode *node)
|
||||
static int count(struct cstate *g, Renode *node, int depth)
|
||||
{
|
||||
int min, max, n;
|
||||
if (!node) return 0;
|
||||
if (++depth > REG_MAXREC) die(g, "stack overflow");
|
||||
switch (node->type) {
|
||||
default: return 1;
|
||||
case P_CAT: return count(g, node->x) + count(g, node->y);
|
||||
case P_ALT: return count(g, node->x) + count(g, node->y) + 2;
|
||||
case P_CAT: return count(g, node->x, depth) + count(g, node->y, depth);
|
||||
case P_ALT: return count(g, node->x, depth) + count(g, node->y, depth) + 2;
|
||||
case P_REP:
|
||||
min = node->m;
|
||||
max = node->n;
|
||||
if (min == max) n = count(g, node->x) * min;
|
||||
else if (max < REPINF) n = count(g, node->x) * max + (max - min);
|
||||
else n = count(g, node->x) * (min + 1) + 2;
|
||||
if (min == max) n = count(g, node->x, depth) * min;
|
||||
else if (max < REPINF) n = count(g, node->x, depth) * max + (max - min);
|
||||
else n = count(g, node->x, depth) * (min + 1) + 2;
|
||||
if (n < 0 || n > REG_MAXPROG) die(g, "program too large");
|
||||
return n;
|
||||
case P_PAR: return count(g, node->x) + 2;
|
||||
case P_PLA: return count(g, node->x) + 2;
|
||||
case P_NLA: return count(g, node->x) + 2;
|
||||
case P_PAR: return count(g, node->x, depth) + 2;
|
||||
case P_PLA: return count(g, node->x, depth) + 2;
|
||||
case P_NLA: return count(g, node->x, depth) + 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -903,7 +904,7 @@ Reprog *regcompx(void *(*alloc)(void *ctx, void *p, int n), void *ctx,
|
||||
putchar('\n');
|
||||
#endif
|
||||
|
||||
n = 6 + count(&g, node);
|
||||
n = 6 + count(&g, node, 0);
|
||||
if (n < 0 || n > REG_MAXPROG)
|
||||
die(&g, "program too large");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user