xref: /minix3/tests/lib/libc/regex/t_exhaust.c (revision 11be35a165022172ed3cea20f2b5df0307540b0e)
1*11be35a1SLionel Sambuc /*	$NetBSD: t_exhaust.c,v 1.7 2011/11/16 18:37:31 christos Exp $	*/
2*11be35a1SLionel Sambuc 
3*11be35a1SLionel Sambuc /*-
4*11be35a1SLionel Sambuc  * Copyright (c) 2011 The NetBSD Foundation, Inc.
5*11be35a1SLionel Sambuc  * All rights reserved.
6*11be35a1SLionel Sambuc  *
7*11be35a1SLionel Sambuc  * This code is derived from software contributed to The NetBSD Foundation
8*11be35a1SLionel Sambuc  * by Christos Zoulas.
9*11be35a1SLionel Sambuc  *
10*11be35a1SLionel Sambuc  * Redistribution and use in source and binary forms, with or without
11*11be35a1SLionel Sambuc  * modification, are permitted provided that the following conditions
12*11be35a1SLionel Sambuc  * are met:
13*11be35a1SLionel Sambuc  * 1. Redistributions of source code must retain the above copyright
14*11be35a1SLionel Sambuc  *    notice, this list of conditions and the following disclaimer.
15*11be35a1SLionel Sambuc  * 2. Redistributions in binary form must reproduce the above copyright
16*11be35a1SLionel Sambuc  *    notice, this list of conditions and the following disclaimer in the
17*11be35a1SLionel Sambuc  *    documentation and/or other materials provided with the distribution.
18*11be35a1SLionel Sambuc  * 3. All advertising materials mentioning features or use of this software
19*11be35a1SLionel Sambuc  *    must display the following acknowledgement:
20*11be35a1SLionel Sambuc  *        This product includes software developed by the NetBSD
21*11be35a1SLionel Sambuc  *        Foundation, Inc. and its contributors.
22*11be35a1SLionel Sambuc  * 4. Neither the name of The NetBSD Foundation nor the names of its
23*11be35a1SLionel Sambuc  *    contributors may be used to endorse or promote products derived
24*11be35a1SLionel Sambuc  *    from this software without specific prior written permission.
25*11be35a1SLionel Sambuc  *
26*11be35a1SLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27*11be35a1SLionel Sambuc  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28*11be35a1SLionel Sambuc  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29*11be35a1SLionel Sambuc  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30*11be35a1SLionel Sambuc  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31*11be35a1SLionel Sambuc  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32*11be35a1SLionel Sambuc  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33*11be35a1SLionel Sambuc  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34*11be35a1SLionel Sambuc  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35*11be35a1SLionel Sambuc  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36*11be35a1SLionel Sambuc  * POSSIBILITY OF SUCH DAMAGE.
37*11be35a1SLionel Sambuc  */
38*11be35a1SLionel Sambuc 
39*11be35a1SLionel Sambuc #include <sys/cdefs.h>
40*11be35a1SLionel Sambuc __RCSID("$NetBSD: t_exhaust.c,v 1.7 2011/11/16 18:37:31 christos Exp $");
41*11be35a1SLionel Sambuc 
42*11be35a1SLionel Sambuc #include <stdio.h>
43*11be35a1SLionel Sambuc #include <regex.h>
44*11be35a1SLionel Sambuc #include <string.h>
45*11be35a1SLionel Sambuc #include <stdlib.h>
46*11be35a1SLionel Sambuc #include <err.h>
47*11be35a1SLionel Sambuc #include <atf-c.h>
48*11be35a1SLionel Sambuc 
49*11be35a1SLionel Sambuc #ifndef REGEX_MAXSIZE
50*11be35a1SLionel Sambuc #define REGEX_MAXSIZE	9999
51*11be35a1SLionel Sambuc #endif
52*11be35a1SLionel Sambuc 
53*11be35a1SLionel Sambuc static char *
mkstr(const char * str,size_t len)54*11be35a1SLionel Sambuc mkstr(const char *str, size_t len)
55*11be35a1SLionel Sambuc {
56*11be35a1SLionel Sambuc 	size_t slen = strlen(str);
57*11be35a1SLionel Sambuc 	char *p = malloc(slen * len + 1);
58*11be35a1SLionel Sambuc 	ATF_REQUIRE(p != NULL);
59*11be35a1SLionel Sambuc 	for (size_t i = 0; i < len; i++)
60*11be35a1SLionel Sambuc 		strcpy(&p[i * slen], str);
61*11be35a1SLionel Sambuc 	return p;
62*11be35a1SLionel Sambuc }
63*11be35a1SLionel Sambuc 
64*11be35a1SLionel Sambuc static char *
concat(const char * d,const char * s)65*11be35a1SLionel Sambuc concat(const char *d, const char *s)
66*11be35a1SLionel Sambuc {
67*11be35a1SLionel Sambuc 	size_t dlen = strlen(d);
68*11be35a1SLionel Sambuc 	size_t slen = strlen(s);
69*11be35a1SLionel Sambuc 	char *p = malloc(dlen + slen + 1);
70*11be35a1SLionel Sambuc 
71*11be35a1SLionel Sambuc 	ATF_REQUIRE(p != NULL);
72*11be35a1SLionel Sambuc 	strcpy(p, d);
73*11be35a1SLionel Sambuc 	strcpy(p + dlen, s);
74*11be35a1SLionel Sambuc 	return p;
75*11be35a1SLionel Sambuc }
76*11be35a1SLionel Sambuc 
77*11be35a1SLionel Sambuc static char *
p0(size_t len)78*11be35a1SLionel Sambuc p0(size_t len)
79*11be35a1SLionel Sambuc {
80*11be35a1SLionel Sambuc 	char *d, *s1, *s2;
81*11be35a1SLionel Sambuc 	s1 = mkstr("\\(", len);
82*11be35a1SLionel Sambuc 	s2 = concat(s1, ")");
83*11be35a1SLionel Sambuc 	free(s1);
84*11be35a1SLionel Sambuc 	d = concat("(", s2);
85*11be35a1SLionel Sambuc 	free(s2);
86*11be35a1SLionel Sambuc 	return d;
87*11be35a1SLionel Sambuc }
88*11be35a1SLionel Sambuc 
89*11be35a1SLionel Sambuc static char *
p1(size_t len)90*11be35a1SLionel Sambuc p1(size_t len)
91*11be35a1SLionel Sambuc {
92*11be35a1SLionel Sambuc 	char *d, *s1, *s2, *s3;
93*11be35a1SLionel Sambuc 	s1 = mkstr("\\(", 60);
94*11be35a1SLionel Sambuc 	s2 = mkstr("(.*)", len);
95*11be35a1SLionel Sambuc 	s3 = concat(s1, s2);
96*11be35a1SLionel Sambuc 	free(s2);
97*11be35a1SLionel Sambuc 	free(s1);
98*11be35a1SLionel Sambuc 	s1 = concat(s3, ")");
99*11be35a1SLionel Sambuc 	free(s3);
100*11be35a1SLionel Sambuc 	d = concat("(", s1);
101*11be35a1SLionel Sambuc 	free(s1);
102*11be35a1SLionel Sambuc 	return d;
103*11be35a1SLionel Sambuc }
104*11be35a1SLionel Sambuc 
105*11be35a1SLionel Sambuc static char *
ps(const char * m,const char * s,size_t len)106*11be35a1SLionel Sambuc ps(const char *m, const char *s, size_t len)
107*11be35a1SLionel Sambuc {
108*11be35a1SLionel Sambuc 	char *d, *s1, *s2, *s3;
109*11be35a1SLionel Sambuc 	s1 = mkstr(m, len);
110*11be35a1SLionel Sambuc 	s2 = mkstr(s, len);
111*11be35a1SLionel Sambuc 	s3 = concat(s1, s2);
112*11be35a1SLionel Sambuc 	free(s2);
113*11be35a1SLionel Sambuc 	free(s1);
114*11be35a1SLionel Sambuc 	d = concat("(.?)", s3);
115*11be35a1SLionel Sambuc 	free(s3);
116*11be35a1SLionel Sambuc 	return d;
117*11be35a1SLionel Sambuc }
118*11be35a1SLionel Sambuc 
119*11be35a1SLionel Sambuc static char *
p2(size_t len)120*11be35a1SLionel Sambuc p2(size_t len)
121*11be35a1SLionel Sambuc {
122*11be35a1SLionel Sambuc 	return ps("((.*){0,255}", ")", len);
123*11be35a1SLionel Sambuc }
124*11be35a1SLionel Sambuc 
125*11be35a1SLionel Sambuc static char *
p3(size_t len)126*11be35a1SLionel Sambuc p3(size_t len)
127*11be35a1SLionel Sambuc {
128*11be35a1SLionel Sambuc 	return ps("(.\\{0,}", ")", len);
129*11be35a1SLionel Sambuc }
130*11be35a1SLionel Sambuc 
131*11be35a1SLionel Sambuc static char *
p4(size_t len)132*11be35a1SLionel Sambuc p4(size_t len)
133*11be35a1SLionel Sambuc {
134*11be35a1SLionel Sambuc 	return ps("((.*){1,255}", ")", len);
135*11be35a1SLionel Sambuc }
136*11be35a1SLionel Sambuc 
137*11be35a1SLionel Sambuc static char *
p5(size_t len)138*11be35a1SLionel Sambuc p5(size_t len)
139*11be35a1SLionel Sambuc {
140*11be35a1SLionel Sambuc 	return ps("(", "){1,100}", len);
141*11be35a1SLionel Sambuc }
142*11be35a1SLionel Sambuc 
143*11be35a1SLionel Sambuc static char *
p6(size_t len)144*11be35a1SLionel Sambuc p6(size_t len)
145*11be35a1SLionel Sambuc {
146*11be35a1SLionel Sambuc 	char *d, *s1, *s2;
147*11be35a1SLionel Sambuc 	s1 = mkstr("(?:(.*)|", len);
148*11be35a1SLionel Sambuc 	s2 = concat(s1, "(.*)");
149*11be35a1SLionel Sambuc 	free(s1);
150*11be35a1SLionel Sambuc 	s1 = mkstr(")", len);
151*11be35a1SLionel Sambuc 	d = concat(s2, s1);
152*11be35a1SLionel Sambuc 	free(s1);
153*11be35a1SLionel Sambuc 	free(s2);
154*11be35a1SLionel Sambuc 	return d;
155*11be35a1SLionel Sambuc }
156*11be35a1SLionel Sambuc 
157*11be35a1SLionel Sambuc static const struct {
158*11be35a1SLionel Sambuc 	char *(*pattern)(size_t);
159*11be35a1SLionel Sambuc 	int type;
160*11be35a1SLionel Sambuc } tests[] = {
161*11be35a1SLionel Sambuc 	{ p0, REG_EXTENDED },
162*11be35a1SLionel Sambuc 	{ p1, REG_EXTENDED },
163*11be35a1SLionel Sambuc 	{ p2, REG_EXTENDED },
164*11be35a1SLionel Sambuc 	{ p3, REG_EXTENDED },
165*11be35a1SLionel Sambuc 	{ p4, REG_EXTENDED },
166*11be35a1SLionel Sambuc 	{ p5, REG_EXTENDED },
167*11be35a1SLionel Sambuc 	{ p6, REG_BASIC },
168*11be35a1SLionel Sambuc };
169*11be35a1SLionel Sambuc 
170*11be35a1SLionel Sambuc ATF_TC(regcomp_too_big);
171*11be35a1SLionel Sambuc 
ATF_TC_HEAD(regcomp_too_big,tc)172*11be35a1SLionel Sambuc ATF_TC_HEAD(regcomp_too_big, tc)
173*11be35a1SLionel Sambuc {
174*11be35a1SLionel Sambuc 
175*11be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr", "Check that large patterns don't"
176*11be35a1SLionel Sambuc 	    " crash, but return a proper error code");
177*11be35a1SLionel Sambuc 	// libtre needs it.
178*11be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "timeout", "600");
179*11be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "require.memory", "120M");
180*11be35a1SLionel Sambuc }
181*11be35a1SLionel Sambuc 
ATF_TC_BODY(regcomp_too_big,tc)182*11be35a1SLionel Sambuc ATF_TC_BODY(regcomp_too_big, tc)
183*11be35a1SLionel Sambuc {
184*11be35a1SLionel Sambuc 	regex_t re;
185*11be35a1SLionel Sambuc 	int e;
186*11be35a1SLionel Sambuc 
187*11be35a1SLionel Sambuc 	for (size_t i = 0; i < __arraycount(tests); i++) {
188*11be35a1SLionel Sambuc 		char *d = (*tests[i].pattern)(REGEX_MAXSIZE);
189*11be35a1SLionel Sambuc 		e = regcomp(&re, d, tests[i].type);
190*11be35a1SLionel Sambuc 		if (e) {
191*11be35a1SLionel Sambuc 			char ebuf[1024];
192*11be35a1SLionel Sambuc 			(void)regerror(e, &re, ebuf, sizeof(ebuf));
193*11be35a1SLionel Sambuc 			ATF_REQUIRE_MSG(e == REG_ESPACE,
194*11be35a1SLionel Sambuc 			    "regcomp returned %d (%s) for pattern %zu [%s]", e, ebuf,
195*11be35a1SLionel Sambuc 			    i, d);
196*11be35a1SLionel Sambuc 			free(d);
197*11be35a1SLionel Sambuc 			continue;
198*11be35a1SLionel Sambuc 		}
199*11be35a1SLionel Sambuc 		free(d);
200*11be35a1SLionel Sambuc 		(void)regexec(&re, "aaaaaaaaaaa", 0, NULL, 0);
201*11be35a1SLionel Sambuc 		regfree(&re);
202*11be35a1SLionel Sambuc 	}
203*11be35a1SLionel Sambuc }
204*11be35a1SLionel Sambuc 
ATF_TP_ADD_TCS(tp)205*11be35a1SLionel Sambuc ATF_TP_ADD_TCS(tp)
206*11be35a1SLionel Sambuc {
207*11be35a1SLionel Sambuc 
208*11be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, regcomp_too_big);
209*11be35a1SLionel Sambuc 	return atf_no_error();
210*11be35a1SLionel Sambuc }
211