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