Tcl Source Code

Check-in [a5e7d0c908]
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:3610026 Stop crash when the number of "colors" in a regular expression overflows a short int. Thanks to Heikki Linnakangas for the report and the patch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | core-8-4-branch
Files: files | file ages | folders
SHA1: a5e7d0c9082690a9f14ea5e960c8f169fa47e5ba
User & Date: dgp 2013-04-08 19:45:55
Context
2013-04-09
10:10
Make (deprecated) Tcl_EvalObj/Tcl_GlobalEvalObj macro's always, not only when using stubs. check-in: 58c923ed9e user: jan.nijtmans tags: core-8-4-branch
2013-04-08
19:59
3610026 Stop crash when the number of "colors" in a regular expression overflows a short int. Thank... check-in: a0f071f00b user: dgp tags: core-8-5-branch
19:45
3610026 Stop crash when the number of "colors" in a regular expression overflows a short int. Thank... check-in: a5e7d0c908 user: dgp tags: core-8-4-branch
19:30
Demand the error message indicating the purpose of the test. Closed-Leaf check-in: 2c6fed253d user: dgp tags: bug-3610026
2013-04-03
20:46
some more "ignore-glob" patterns check-in: 9f64830f2e user: jan.nijtmans tags: core-8-4-branch
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ChangeLog.









1
2
3
4
5
6
7







2013-03-19  Don Porter  <[email protected]>

	* generic/tclFCmd.c: [Bug 3597000] Consistent [file copy] result.

2013-03-19  Jan Nijtmans  <[email protected]>

	* win/tclWinFile.c: [Bug 2893771]: file stat fails on locked files
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2013-04-08  Don Porter  <[email protected]>

	* generic/regc_color.c:	[Bug 3610026] Stop crash when the number of
	* generic/regerrs.h:	"colors" in a regular expression overflows
	* generic/regex.h:	a short int.  Thanks to Heikki Linnakangas
	* generic/regguts.h:	for the report and the patch.
	* tests/regexp.test:

2013-03-19  Don Porter  <[email protected]>

	* generic/tclFCmd.c: [Bug 3597000] Consistent [file copy] result.

2013-03-19  Jan Nijtmans  <[email protected]>

	* win/tclWinFile.c: [Bug 2893771]: file stat fails on locked files

Changes to generic/regc_color.c.

219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
...
237
238
239
240
241
242
243






244


245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
 ^ static color newcolor(struct colormap *);
 */
static color			/* COLORLESS for error */
newcolor(cm)
struct colormap *cm;
{
	struct colordesc *cd;
	struct colordesc *new;
	size_t n;

	if (CISERR())
		return COLORLESS;

	if (cm->free != 0) {
		assert(cm->free > 0);
................................................................................
		assert(cd->arcs == NULL);
		cm->free = cd->sub;
	} else if (cm->max < cm->ncds - 1) {
		cm->max++;
		cd = &cm->cd[cm->max];
	} else {
		/* oops, must allocate more */






		n = cm->ncds * 2;


		if (cm->cd == cm->cdspace) {
			new = (struct colordesc *)MALLOC(n *
						sizeof(struct colordesc));
			if (new != NULL)
				memcpy(VS(new), VS(cm->cdspace), cm->ncds *
						sizeof(struct colordesc));
		} else
			new = (struct colordesc *)REALLOC(cm->cd,
						n * sizeof(struct colordesc));
		if (new == NULL) {
			CERR(REG_ESPACE);
			return COLORLESS;
		}
		cm->cd = new;
		cm->ncds = n;
		assert(cm->max < cm->ncds - 1);
		cm->max++;
		cd = &cm->cd[cm->max];
	}

	cd->nchrs = 0;






<







 







>
>
>
>
>
>

>
>

|

|
|


|

|



|







219
220
221
222
223
224
225

226
227
228
229
230
231
232
...
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
 ^ static color newcolor(struct colormap *);
 */
static color			/* COLORLESS for error */
newcolor(cm)
struct colormap *cm;
{
	struct colordesc *cd;

	size_t n;

	if (CISERR())
		return COLORLESS;

	if (cm->free != 0) {
		assert(cm->free > 0);
................................................................................
		assert(cd->arcs == NULL);
		cm->free = cd->sub;
	} else if (cm->max < cm->ncds - 1) {
		cm->max++;
		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) {
			newCd = (struct colordesc *)MALLOC(n *
						sizeof(struct colordesc));
			if (newCd != NULL)
				memcpy(VS(newCd), VS(cm->cdspace), cm->ncds *
						sizeof(struct colordesc));
		} else
			newCd = (struct colordesc *)REALLOC(cm->cd,
						n * sizeof(struct colordesc));
		if (newCd == NULL) {
			CERR(REG_ESPACE);
			return COLORLESS;
		}
		cm->cd = newCd;
		cm->ncds = n;
		assert(cm->max < cm->ncds - 1);
		cm->max++;
		cd = &cm->cd[cm->max];
	}

	cd->nchrs = 0;

Changes to generic/regerrs.h.

13
14
15
16
17
18
19

{ REG_ESPACE,	"REG_ESPACE",	"out of memory" },
{ REG_BADRPT,	"REG_BADRPT",	"quantifier operand invalid" },
{ REG_ASSERT,	"REG_ASSERT",	"\"can't happen\" -- you found a bug" },
{ REG_INVARG,	"REG_INVARG",	"invalid argument to regex function" },
{ 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" },







>
13
14
15
16
17
18
19
20
{ REG_ESPACE,	"REG_ESPACE",	"out of memory" },
{ REG_BADRPT,	"REG_BADRPT",	"quantifier operand invalid" },
{ REG_ASSERT,	"REG_ASSERT",	"\"can't happen\" -- you found a bug" },
{ REG_INVARG,	"REG_INVARG",	"invalid argument to regex function" },
{ 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" },

Changes to generic/regex.h.

289
290
291
292
293
294
295

296
297
298
299
300
301
302
#define	REG_ESPACE	12	/* out of memory */
#define	REG_BADRPT	13	/* quantifier operand invalid */
#define	REG_ASSERT	15	/* "can't happen" -- you found a bug */
#define	REG_INVARG	16	/* invalid argument to regex function */
#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 */

/* 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 */



/*






>







289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
#define	REG_ESPACE	12	/* out of memory */
#define	REG_BADRPT	13	/* quantifier operand invalid */
#define	REG_ASSERT	15	/* "can't happen" -- you found a bug */
#define	REG_INVARG	16	/* invalid argument to regex function */
#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 */



/*

Changes to generic/regguts.h.

170
171
172
173
174
175
176

177
178
179
180
181
182
183
/*
 * As soon as possible, we map chrs into equivalence classes -- "colors" --
 * which are of much more manageable number.
 */
typedef short color;		/* colors of characters */
typedef int pcolor;		/* what color promotes to */

#define	COLORLESS	(-1)	/* impossible color */
#define	WHITE		0	/* default color, parent of all others */



/*
 * A colormap is a tree -- more precisely, a DAG -- indexed at each level






>







170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*
 * As soon as possible, we map chrs into equivalence classes -- "colors" --
 * which are of much more manageable number.
 */
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 */



/*
 * A colormap is a tree -- more precisely, a DAG -- indexed at each level

Changes to tests/regexp.test.

675
676
677
678
679
680
681











682
683
684
685
	[a 671]([a 55])[a 669]([a 55])[a 668]([a 55])[a 669]([a 55]) \
	[a 669]([a 55])[a 669]([a 55])[a 668]([a 55])[a 669]([a 55]) \
	[a 668]([a 55])[a 710]([a 55])[a 668]([a 55])[a 668]([a 55]) \
	[a 668]([a 55])[a 668]([a 55])[a 668]([a 55])[a 511]] {}] a
} -cleanup {
    rename a {}
} -returnCodes 1 -result {couldn't compile regular expression pattern: nfa has too many states}












# cleanup
::tcltest::cleanupTests
return






>
>
>
>
>
>
>
>
>
>
>




675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
	[a 671]([a 55])[a 669]([a 55])[a 668]([a 55])[a 669]([a 55]) \
	[a 669]([a 55])[a 669]([a 55])[a 668]([a 55])[a 669]([a 55]) \
	[a 668]([a 55])[a 710]([a 55])[a 668]([a 55])[a 668]([a 55]) \
	[a 668]([a 55])[a 668]([a 55])[a 668]([a 55])[a 511]] {}] a
} -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 {*too many colors*}

# cleanup
::tcltest::cleanupTests
return