summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2013-04-08 15:15:40 (GMT)
committerdgp <dgp@users.sourceforge.net>2013-04-08 15:15:40 (GMT)
commitd2ebbe8d0453b1830261e251e116ccec67a6479c (patch)
treecb7cf35ca6a7d94b2d37084a2787526b1de32931
parent84d7d75f97cf88a8414d4b9832487567cfaf2bd4 (diff)
downloadtcl-d2ebbe8d0453b1830261e251e116ccec67a6479c.zip
tcl-d2ebbe8d0453b1830261e251e116ccec67a6479c.tar.gz
tcl-d2ebbe8d0453b1830261e251e116ccec67a6479c.tar.bz2
3610026 Stop segfault when regexp overflows color limits.
-rw-r--r--generic/regc_color.c21
-rw-r--r--generic/regerrs.h1
-rw-r--r--generic/regex.h1
-rw-r--r--generic/regguts.h1
-rw-r--r--tests/regexp.test11
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