From d2ebbe8d0453b1830261e251e116ccec67a6479c Mon Sep 17 00:00:00 2001
From: dgp <dgp@users.sourceforge.net>
Date: Mon, 8 Apr 2013 15:15:40 +0000
Subject: 3610026 Stop segfault when regexp overflows color limits.

---
 generic/regc_color.c | 21 ++++++++++++++-------
 generic/regerrs.h    |  1 +
 generic/regex.h      |  1 +
 generic/regguts.h    |  1 +
 tests/regexp.test    | 11 +++++++++++
 5 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/generic/regc_color.c b/generic/regc_color.c
index f6716be..183ef27 100644
--- a/generic/regc_color.c
+++ b/generic/regc_color.c
@@ -223,7 +223,6 @@ newcolor(cm)
 struct colormap *cm;
 {
 	struct colordesc *cd;
-	struct colordesc *new;
 	size_t n;
 
 	if (CISERR())
@@ -241,21 +240,29 @@ struct colormap *cm;
 		cd = &cm->cd[cm->max];
 	} else {
 		/* oops, must allocate more */
+		struct colordesc *newCd;
+
+		if (cm->max == MAX_COLOR) {
+			CERR(REG_ECOLORS);
+			return COLORLESS;	/* too many colors */
+		}
 		n = cm->ncds * 2;
+		if (n < MAX_COLOR + 1)
+			n = MAX_COLOR + 1;
 		if (cm->cd == cm->cdspace) {
-			new = (struct colordesc *)MALLOC(n *
+			newCd = (struct colordesc *)MALLOC(n *
 						sizeof(struct colordesc));
-			if (new != NULL)
-				memcpy(VS(new), VS(cm->cdspace), cm->ncds *
+			if (newCd != NULL)
+				memcpy(VS(newCd), VS(cm->cdspace), cm->ncds *
 						sizeof(struct colordesc));
 		} else
-			new = (struct colordesc *)REALLOC(cm->cd,
+			newCd = (struct colordesc *)REALLOC(cm->cd,
 						n * sizeof(struct colordesc));
-		if (new == NULL) {
+		if (newCd == NULL) {
 			CERR(REG_ESPACE);
 			return COLORLESS;
 		}
-		cm->cd = new;
+		cm->cd = newCd;
 		cm->ncds = n;
 		assert(cm->max < cm->ncds - 1);
 		cm->max++;
diff --git a/generic/regerrs.h b/generic/regerrs.h
index 259c0cb..72548ff 100644
--- a/generic/regerrs.h
+++ b/generic/regerrs.h
@@ -17,3 +17,4 @@
 { REG_MIXED,	"REG_MIXED",	"character widths of regex and string differ" },
 { REG_BADOPT,	"REG_BADOPT",	"invalid embedded option" },
 { REG_ETOOBIG,	"REG_ETOOBIG",	"nfa has too many states" },
+{ REG_ECOLORS,	"REG_ECOLORS",	"too many colors" },
diff --git a/generic/regex.h b/generic/regex.h
index a35925a..1cd2ea8 100644
--- a/generic/regex.h
+++ b/generic/regex.h
@@ -293,6 +293,7 @@ typedef struct {
 #define	REG_MIXED	17	/* character widths of regex and string differ */
 #define	REG_BADOPT	18	/* invalid embedded option */
 #define	REG_ETOOBIG	19	/* nfa has too many states */
+#define	REG_ECOLORS	20	/* too many colors */
 /* two specials for debugging and testing */
 #define	REG_ATOI	101	/* convert error-code name to number */
 #define	REG_ITOA	102	/* convert error-code number to name */
diff --git a/generic/regguts.h b/generic/regguts.h
index c77a8fc..ee5c596 100644
--- a/generic/regguts.h
+++ b/generic/regguts.h
@@ -174,6 +174,7 @@
  */
 typedef short color;		/* colors of characters */
 typedef int pcolor;		/* what color promotes to */
+#define MAX_COLOR	SHRT_MAX /* max color value */
 #define	COLORLESS	(-1)	/* impossible color */
 #define	WHITE		0	/* default color, parent of all others */
 
diff --git a/tests/regexp.test b/tests/regexp.test
index 9b4c525..74fdc09 100644
--- a/tests/regexp.test
+++ b/tests/regexp.test
@@ -679,6 +679,17 @@ test regexp-22.4 {Bug 3606139} -setup {
 } -cleanup {
     rename a {}
 } -returnCodes 1 -result {couldn't compile regular expression pattern: nfa has too many states}
+test regexp-22.5 {Bug 3610026} -setup {
+    set e {}
+    set cp 99
+    while {$cp < 32864} {
+	append e [format %c [incr cp]]
+    }
+} -body {
+    regexp -about $e
+} -cleanup {
+    unset -nocomplain e cp
+} -returnCodes error  -match glob -result * 
 
 # cleanup
 ::tcltest::cleanupTests
-- 
cgit v0.12


From f637643facaa33834a74333f56971933a2158176 Mon Sep 17 00:00:00 2001
From: dgp <dgp@users.sourceforge.net>
Date: Mon, 8 Apr 2013 19:30:51 +0000
Subject: Demand the error message indicating the purpose of the test.

---
 tests/regexp.test | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/regexp.test b/tests/regexp.test
index 74fdc09..5328c8e 100644
--- a/tests/regexp.test
+++ b/tests/regexp.test
@@ -689,7 +689,7 @@ test regexp-22.5 {Bug 3610026} -setup {
     regexp -about $e
 } -cleanup {
     unset -nocomplain e cp
-} -returnCodes error  -match glob -result * 
+} -returnCodes error  -match glob -result {*too many colors*}
 
 # cleanup
 ::tcltest::cleanupTests
-- 
cgit v0.12