1 /* $NetBSD: t_exhaust.c,v 1.1 2011/10/09 18:21:08 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.1 2011/10/09 18:21:08 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 != 0) 182 ATF_REQUIRE_MSG(e == REG_ESPACE, 183 "regcomp returned %d for pattern %zu", e, i); 184 if (e) 185 continue; 186 e = 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