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