From b6f570180beda2bd35b9010f4d137a9af46f15b5 Mon Sep 17 00:00:00 2001 From: dgp 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