diff --git a/regexp.c b/regexp.c index 9d16867..8a43fef 100644 --- a/regexp.c +++ b/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");