View | Details | Raw Unified | Return to bug 169302
Collapse All | Expand All

(-)lib/libc/regex/engine.c (-1 / +1 lines)
Lines 219-225 Link Here
219
		} else {
219
		} else {
220
			for (dp = start; dp < stop; dp++)
220
			for (dp = start; dp < stop; dp++)
221
				if (*dp == g->must[0] &&
221
				if (*dp == g->must[0] &&
222
				    stop - dp >= g->mlen &&
222
				    (size_t)(stop - dp) >= g->mlen &&
223
				    memcmp(dp, g->must, (size_t)g->mlen) == 0)
223
				    memcmp(dp, g->must, (size_t)g->mlen) == 0)
224
					break;
224
					break;
225
			if (dp == stop)		/* we didn't find g->must */
225
			if (dp == stop)		/* we didn't find g->must */
(-)lib/libc/regex/regcomp.c (-29 / +63 lines)
Lines 86-96 Link Here
86
#endif
86
#endif
87
87
88
/* === regcomp.c === */
88
/* === regcomp.c === */
89
static void p_ere(struct parse *p, int stop);
89
static void p_ere(struct parse *p, int stop, size_t reclimit);
90
static void p_ere_exp(struct parse *p);
90
static void p_ere_exp(struct parse *p, size_t reclimit);
91
static void p_str(struct parse *p);
91
static void p_str(struct parse *p);
92
static void p_bre(struct parse *p, int end1, int end2);
92
static void p_bre(struct parse *p, int end1, int end2, size_t reclimit);
93
static int p_simp_re(struct parse *p, int starordinary);
93
static int p_simp_re(struct parse *p, int starordinary, size_t reclimit);
94
static int p_count(struct parse *p);
94
static int p_count(struct parse *p);
95
static void p_bracket(struct parse *p);
95
static void p_bracket(struct parse *p);
96
static void p_b_term(struct parse *p, cset *cs);
96
static void p_b_term(struct parse *p, cset *cs);
Lines 102-108 Link Here
102
static void bothcases(struct parse *p, wint_t ch);
102
static void bothcases(struct parse *p, wint_t ch);
103
static void ordinary(struct parse *p, wint_t ch);
103
static void ordinary(struct parse *p, wint_t ch);
104
static void nonnewline(struct parse *p);
104
static void nonnewline(struct parse *p);
105
static void repeat(struct parse *p, sopno start, int from, int to);
105
static void repeat(struct parse *p, sopno start, int from, int to, size_t reclimit);
106
static int seterr(struct parse *p, int e);
106
static int seterr(struct parse *p, int e);
107
static cset *allocset(struct parse *p);
107
static cset *allocset(struct parse *p);
108
static void freeset(struct parse *p, cset *cs);
108
static void freeset(struct parse *p, cset *cs);
Lines 167-172 Link Here
167
#define	never	0		/* some <assert.h>s have bugs too */
167
#define	never	0		/* some <assert.h>s have bugs too */
168
#endif
168
#endif
169
169
170
#define	MEMLIMIT	0x8000000
171
#define MEMSIZE(p) \
172
	((p)->ncsalloc / CHAR_BIT * NC + \
173
	(p)->ncsalloc * sizeof(cset) + \
174
	(p)->ssize * sizeof(sop))
175
#define	RECLIMIT	256
176
170
/* Macro used by computejump()/computematchjump() */
177
/* Macro used by computejump()/computematchjump() */
171
#define MIN(a,b)	((a)<(b)?(a):(b))
178
#define MIN(a,b)	((a)<(b)?(a):(b))
172
179
Lines 249-259 Link Here
249
	EMIT(OEND, 0);
256
	EMIT(OEND, 0);
250
	g->firststate = THERE();
257
	g->firststate = THERE();
251
	if (cflags&REG_EXTENDED)
258
	if (cflags&REG_EXTENDED)
252
		p_ere(p, OUT);
259
		p_ere(p, OUT, 0);
253
	else if (cflags&REG_NOSPEC)
260
	else if (cflags&REG_NOSPEC)
254
		p_str(p);
261
		p_str(p);
255
	else
262
	else
256
		p_bre(p, OUT, OUT);
263
		p_bre(p, OUT, OUT, 0);
257
	EMIT(OEND, 0);
264
	EMIT(OEND, 0);
258
	g->laststate = THERE();
265
	g->laststate = THERE();
259
266
Lines 294-300 Link Here
294
 */
301
 */
295
static void
302
static void
296
p_ere(struct parse *p,
303
p_ere(struct parse *p,
297
	int stop)		/* character this ERE should end at */
304
	int stop,		/* character this ERE should end at */
305
	size_t reclimit)
298
{
306
{
299
	char c;
307
	char c;
300
	sopno prevback;
308
	sopno prevback;
Lines 302-312 Link Here
302
	sopno conc;
310
	sopno conc;
303
	int first = 1;		/* is this the first alternative? */
311
	int first = 1;		/* is this the first alternative? */
304
312
313
	if (reclimit++ > RECLIMIT || p->error == REG_ESPACE) {
314
		p->error = REG_ESPACE;
315
		return;
316
	}
317
305
	for (;;) {
318
	for (;;) {
306
		/* do a bunch of concatenated expressions */
319
		/* do a bunch of concatenated expressions */
307
		conc = HERE();
320
		conc = HERE();
308
		while (MORE() && (c = PEEK()) != '|' && c != stop)
321
		while (MORE() && (c = PEEK()) != '|' && c != stop)
309
			p_ere_exp(p);
322
			p_ere_exp(p, reclimit);
310
		(void)REQUIRE(HERE() != conc, REG_EMPTY);	/* require nonempty */
323
		(void)REQUIRE(HERE() != conc, REG_EMPTY);	/* require nonempty */
311
324
312
		if (!EAT('|'))
325
		if (!EAT('|'))
Lines 335-344 Link Here
335
348
336
/*
349
/*
337
 - p_ere_exp - parse one subERE, an atom possibly followed by a repetition op
350
 - p_ere_exp - parse one subERE, an atom possibly followed by a repetition op
338
 == static void p_ere_exp(struct parse *p);
351
 == static void p_ere_exp(struct parse *p, size_t reclimit);
339
 */
352
 */
340
static void
353
static void
341
p_ere_exp(struct parse *p)
354
p_ere_exp(struct parse *p, size_t reclimit)
342
{
355
{
343
	char c;
356
	char c;
344
	wint_t wc;
357
	wint_t wc;
Lines 361-367 Link Here
361
			p->pbegin[subno] = HERE();
374
			p->pbegin[subno] = HERE();
362
		EMIT(OLPAREN, subno);
375
		EMIT(OLPAREN, subno);
363
		if (!SEE(')'))
376
		if (!SEE(')'))
364
			p_ere(p, ')');
377
			p_ere(p, ')', reclimit);
365
		if (subno < NPAREN) {
378
		if (subno < NPAREN) {
366
			p->pend[subno] = HERE();
379
			p->pend[subno] = HERE();
367
			assert(p->pend[subno] != 0);
380
			assert(p->pend[subno] != 0);
Lines 465-471 Link Here
465
				count2 = INFINITY;
478
				count2 = INFINITY;
466
		} else		/* just a single number */
479
		} else		/* just a single number */
467
			count2 = count;
480
			count2 = count;
468
		repeat(p, pos, count, count2);
481
		repeat(p, pos, count, count2, 0);
469
		if (!EAT('}')) {	/* error heuristics */
482
		if (!EAT('}')) {	/* error heuristics */
470
			while (MORE() && PEEK() != '}')
483
			while (MORE() && PEEK() != '}')
471
				NEXT();
484
				NEXT();
Lines 499-505 Link Here
499
/*
512
/*
500
 - p_bre - BRE parser top level, anchoring and concatenation
513
 - p_bre - BRE parser top level, anchoring and concatenation
501
 == static void p_bre(struct parse *p,  int end1, \
514
 == static void p_bre(struct parse *p,  int end1, \
502
 ==	int end2);
515
 ==	int end2, size_t reclimit);
503
 * Giving end1 as OUT essentially eliminates the end1/end2 check.
516
 * Giving end1 as OUT essentially eliminates the end1/end2 check.
504
 *
517
 *
505
 * This implementation is a bit of a kludge, in that a trailing $ is first
518
 * This implementation is a bit of a kludge, in that a trailing $ is first
Lines 509-516 Link Here
509
static void
522
static void
510
p_bre(struct parse *p,
523
p_bre(struct parse *p,
511
	int end1,		/* first terminating character */
524
	int end1,		/* first terminating character */
512
	int end2)		/* second terminating character */
525
	int end2,		/* second terminating character */
526
	size_t reclimit)
513
{
527
{
528
	if (reclimit++ > RECLIMIT || p->error == REG_ESPACE) {
529
		p->error = REG_ESPACE;
530
		return;
531
	}
532
514
	sopno start = HERE();
533
	sopno start = HERE();
515
	int first = 1;			/* first subexpression? */
534
	int first = 1;			/* first subexpression? */
516
	int wasdollar = 0;
535
	int wasdollar = 0;
Lines 521-527 Link Here
521
		p->g->nbol++;
540
		p->g->nbol++;
522
	}
541
	}
523
	while (MORE() && !SEETWO(end1, end2)) {
542
	while (MORE() && !SEETWO(end1, end2)) {
524
		wasdollar = p_simp_re(p, first);
543
		wasdollar = p_simp_re(p, first, reclimit);
525
		first = 0;
544
		first = 0;
526
	}
545
	}
527
	if (wasdollar) {	/* oops, that was a trailing anchor */
546
	if (wasdollar) {	/* oops, that was a trailing anchor */
Lines 536-546 Link Here
536
555
537
/*
556
/*
538
 - p_simp_re - parse a simple RE, an atom possibly followed by a repetition
557
 - p_simp_re - parse a simple RE, an atom possibly followed by a repetition
539
 == static int p_simp_re(struct parse *p, int starordinary);
558
 == static int p_simp_re(struct parse *p, int starordinary, size_t reclimit);
540
 */
559
 */
541
static int			/* was the simple RE an unbackslashed $? */
560
static int			/* was the simple RE an unbackslashed $? */
542
p_simp_re(struct parse *p,
561
p_simp_re(struct parse *p,
543
	int starordinary)	/* is a leading * an ordinary character? */
562
	int starordinary,	/* is a leading * an ordinary character? */
563
	size_t reclimit)
544
{
564
{
545
	int c;
565
	int c;
546
	int count;
566
	int count;
Lines 580-586 Link Here
580
		EMIT(OLPAREN, subno);
600
		EMIT(OLPAREN, subno);
581
		/* the MORE here is an error heuristic */
601
		/* the MORE here is an error heuristic */
582
		if (MORE() && !SEETWO('\\', ')'))
602
		if (MORE() && !SEETWO('\\', ')'))
583
			p_bre(p, '\\', ')');
603
			p_bre(p, '\\', ')', reclimit);
584
		if (subno < NPAREN) {
604
		if (subno < NPAREN) {
585
			p->pend[subno] = HERE();
605
			p->pend[subno] = HERE();
586
			assert(p->pend[subno] != 0);
606
			assert(p->pend[subno] != 0);
Lines 641-647 Link Here
641
				count2 = INFINITY;
661
				count2 = INFINITY;
642
		} else		/* just a single number */
662
		} else		/* just a single number */
643
			count2 = count;
663
			count2 = count;
644
		repeat(p, pos, count, count2);
664
		repeat(p, pos, count, count2, 0);
645
		if (!EATTWO('\\', '}')) {	/* error heuristics */
665
		if (!EATTWO('\\', '}')) {	/* error heuristics */
646
			while (MORE() && !SEETWO('\\', '}'))
666
			while (MORE() && !SEETWO('\\', '}'))
647
				NEXT();
667
				NEXT();
Lines 996-1008 Link Here
996
1016
997
/*
1017
/*
998
 - repeat - generate code for a bounded repetition, recursively if needed
1018
 - repeat - generate code for a bounded repetition, recursively if needed
999
 == static void repeat(struct parse *p, sopno start, int from, int to);
1019
 == static void repeat(struct parse *p, sopno start, int from, int to,
1020
 == size_t reclimit );
1000
 */
1021
 */
1001
static void
1022
static void
1002
repeat(struct parse *p,
1023
repeat(struct parse *p,
1003
	sopno start,		/* operand from here to end of strip */
1024
	sopno start,		/* operand from here to end of strip */
1004
	int from,		/* repeated from this number */
1025
	int from,		/* repeated from this number */
1005
	int to)			/* to this number of times (maybe INFINITY) */
1026
	int to,			/* to this number of times (maybe INFINITY) */
1027
	size_t reclimit)
1006
{
1028
{
1007
	sopno finish = HERE();
1029
	sopno finish = HERE();
1008
#	define	N	2
1030
#	define	N	2
Lines 1011-1017 Link Here
1011
#	define	MAP(n)	(((n) <= 1) ? (n) : ((n) == INFINITY) ? INF : N)
1033
#	define	MAP(n)	(((n) <= 1) ? (n) : ((n) == INFINITY) ? INF : N)
1012
	sopno copy;
1034
	sopno copy;
1013
1035
1014
	if (p->error != 0)	/* head off possible runaway recursion */
1036
	if (reclimit++ > RECLIMIT) 
1037
		p->error = REG_ESPACE;
1038
	if (p->error)
1015
		return;
1039
		return;
1016
1040
1017
	assert(from <= to);
1041
	assert(from <= to);
Lines 1025-1031 Link Here
1025
	case REP(0, INF):		/* as x{1,}? */
1049
	case REP(0, INF):		/* as x{1,}? */
1026
		/* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
1050
		/* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
1027
		INSERT(OCH_, start);		/* offset is wrong... */
1051
		INSERT(OCH_, start);		/* offset is wrong... */
1028
		repeat(p, start+1, 1, to);
1052
		repeat(p, start+1, 1, to, reclimit);
1029
		ASTERN(OOR1, start);
1053
		ASTERN(OOR1, start);
1030
		AHEAD(start);			/* ... fix it */
1054
		AHEAD(start);			/* ... fix it */
1031
		EMIT(OOR2, 0);
1055
		EMIT(OOR2, 0);
Lines 1045-1051 Link Here
1045
		ASTERN(O_CH, THERETHERE());
1069
		ASTERN(O_CH, THERETHERE());
1046
		copy = dupl(p, start+1, finish+1);
1070
		copy = dupl(p, start+1, finish+1);
1047
		assert(copy == finish+4);
1071
		assert(copy == finish+4);
1048
		repeat(p, copy, 1, to-1);
1072
		repeat(p, copy, 1, to-1, reclimit);
1049
		break;
1073
		break;
1050
	case REP(1, INF):		/* as x+ */
1074
	case REP(1, INF):		/* as x+ */
1051
		INSERT(OPLUS_, start);
1075
		INSERT(OPLUS_, start);
Lines 1053-1063 Link Here
1053
		break;
1077
		break;
1054
	case REP(N, N):			/* as xx{m-1,n-1} */
1078
	case REP(N, N):			/* as xx{m-1,n-1} */
1055
		copy = dupl(p, start, finish);
1079
		copy = dupl(p, start, finish);
1056
		repeat(p, copy, from-1, to-1);
1080
		repeat(p, copy, from-1, to-1, reclimit);
1057
		break;
1081
		break;
1058
	case REP(N, INF):		/* as xx{n-1,INF} */
1082
	case REP(N, INF):		/* as xx{n-1,INF} */
1059
		copy = dupl(p, start, finish);
1083
		copy = dupl(p, start, finish);
1060
		repeat(p, copy, from-1, to);
1084
		repeat(p, copy, from-1, to, reclimit);
1061
		break;
1085
		break;
1062
	default:			/* "can't happen" */
1086
	default:			/* "can't happen" */
1063
		SETERROR(REG_ASSERT);	/* just in case */
1087
		SETERROR(REG_ASSERT);	/* just in case */
Lines 1112-1119 Link Here
1112
{
1136
{
1113
	cset *cs, *ncs;
1137
	cset *cs, *ncs;
1114
1138
1139
1140
	if (MEMSIZE(p) > MEMLIMIT)
1141
		goto oomem;
1142
1115
	ncs = realloc(p->g->sets, (p->g->ncsets + 1) * sizeof(*ncs));
1143
	ncs = realloc(p->g->sets, (p->g->ncsets + 1) * sizeof(*ncs));
1116
	if (ncs == NULL) {
1144
	if (ncs == NULL) {
1145
oomem:
1117
		SETERROR(REG_ESPACE);
1146
		SETERROR(REG_ESPACE);
1118
		return (NULL);
1147
		return (NULL);
1119
	}
1148
	}
Lines 1347-1363 Link Here
1347
enlarge(struct parse *p, sopno size)
1376
enlarge(struct parse *p, sopno size)
1348
{
1377
{
1349
	sop *sp;
1378
	sop *sp;
1379
	sopno osize;
1350
1380
1351
	if (p->ssize >= size)
1381
	if (p->ssize >= size)
1352
		return 1;
1382
		return 1;
1353
1383
	osize = p->ssize;
1384
	p->ssize = size;
1385
	if (MEMSIZE(p) > MEMLIMIT)
1386
		goto oomem;
1354
	sp = (sop *)realloc(p->strip, size*sizeof(sop));
1387
	sp = (sop *)realloc(p->strip, size*sizeof(sop));
1355
	if (sp == NULL) {
1388
	if (sp == NULL) {
1389
oomem:
1390
		p->ssize = osize;
1356
		SETERROR(REG_ESPACE);
1391
		SETERROR(REG_ESPACE);
1357
		return 0;
1392
		return 0;
1358
	}
1393
	}
1359
	p->strip = sp;
1394
	p->strip = sp;
1360
	p->ssize = size;
1361
	return 1;
1395
	return 1;
1362
}
1396
}
1363
1397
(-)lib/libc/regex/regex2.h (-5 / +5 lines)
Lines 73-79 Link Here
73
 * immediately *preceding* "execution" of that operator.
73
 * immediately *preceding* "execution" of that operator.
74
 */
74
 */
75
typedef unsigned long sop;	/* strip operator */
75
typedef unsigned long sop;	/* strip operator */
76
typedef long sopno;
76
typedef size_t sopno;
77
#define	OPRMASK	0xf8000000L
77
#define	OPRMASK	0xf8000000L
78
#define	OPDMASK	0x07ffffffL
78
#define	OPDMASK	0x07ffffffL
79
#define	OPSHIFT	((unsigned)27)
79
#define	OPSHIFT	((unsigned)27)
Lines 165-171 Link Here
165
	int magic;
165
	int magic;
166
#		define	MAGIC2	((('R'^0200)<<8)|'E')
166
#		define	MAGIC2	((('R'^0200)<<8)|'E')
167
	sop *strip;		/* malloced area for strip */
167
	sop *strip;		/* malloced area for strip */
168
	int ncsets;		/* number of csets in use */
168
	size_t ncsets;		/* number of csets in use */
169
	cset *sets;		/* -> cset [ncsets] */
169
	cset *sets;		/* -> cset [ncsets] */
170
	int cflags;		/* copy of regcomp() cflags argument */
170
	int cflags;		/* copy of regcomp() cflags argument */
171
	sopno nstates;		/* = number of sops */
171
	sopno nstates;		/* = number of sops */
Lines 175-187 Link Here
175
#		define	USEBOL	01	/* used ^ */
175
#		define	USEBOL	01	/* used ^ */
176
#		define	USEEOL	02	/* used $ */
176
#		define	USEEOL	02	/* used $ */
177
#		define	BAD	04	/* something wrong */
177
#		define	BAD	04	/* something wrong */
178
	int nbol;		/* number of ^ used */
178
	size_t nbol;		/* number of ^ used */
179
	int neol;		/* number of $ used */
179
	size_t neol;		/* number of $ used */
180
	char *must;		/* match must contain this string */
180
	char *must;		/* match must contain this string */
181
	int moffset;		/* latest point at which must may be located */
181
	int moffset;		/* latest point at which must may be located */
182
	int *charjump;		/* Boyer-Moore char jump table */
182
	int *charjump;		/* Boyer-Moore char jump table */
183
	int *matchjump;		/* Boyer-Moore match jump table */
183
	int *matchjump;		/* Boyer-Moore match jump table */
184
	int mlen;		/* length of must */
184
	size_t mlen;		/* length of must */
185
	size_t nsub;		/* copy of re_nsub */
185
	size_t nsub;		/* copy of re_nsub */
186
	int backrefs;		/* does it use back references? */
186
	int backrefs;		/* does it use back references? */
187
	sopno nplus;		/* how deep does it nest +s? */
187
	sopno nplus;		/* how deep does it nest +s? */

Return to bug 169302