65 lines
2.1 KiB
Diff
65 lines
2.1 KiB
Diff
From 160ae29578054dc09fd91e5401ef040d52797e61 Mon Sep 17 00:00:00 2001
|
|
From: Tor Andersson <tor.andersson@artifex.com>
|
|
Date: Tue, 17 May 2022 15:31:50 +0200
|
|
Subject: [PATCH 1/3] Issue #162: Check stack overflow during regexp
|
|
compilation.
|
|
|
|
Only bother checking during the first compilation pass that counts
|
|
the size of the program.
|
|
---
|
|
regexp.c | 21 +++++++++++----------
|
|
1 file changed, 11 insertions(+), 10 deletions(-)
|
|
|
|
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");
|
|
|
|
--
|
|
2.20.1
|
|
|