shithub: libmujs

Download patch

ref: 160ae29578054dc09fd91e5401ef040d52797e61
parent: db110ea88edde20cfdd76a7162de751fefcc1fde
author: Tor Andersson <tor.andersson@artifex.com>
date: Tue May 17 11:31:50 EDT 2022

Issue #162: Check stack overflow during regexp compilation.

Only bother checking during the first compilation pass that counts
the size of the program.

--- a/regexp.c
+++ b/regexp.c
@@ -622,25 +622,26 @@
 	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 @@
 	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");