Subject: lib/26986: regcomp() segfaults on 8-bit input with only one case
To: None <gnats-bugs@gnats.netbsd.org>
From: Alexander Becher <abecher@kawo2.rwth-aachen.de>
List: netbsd-bugs
Date: 09/18/2004 00:47:49
>Number:         26986
>Category:       lib
>Synopsis:       regcomp() segfaults on 8-bit input with only one case
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Sep 17 22:48:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     Alexander Becher
>Release:        NetBSD 2.0_BETA
>Organization:
>Environment:
	
	
System: NetBSD abc 2.0_BETA NetBSD 2.0_BETA (MYKERNEL-2-0.1) #0: Mon Aug 23 19:33:36 CEST 2004 alex@abc:/usr/local/obj/kernel/MYKERNEL-2-0.1 i386
Architecture: i386
Machine: i386
>Description:
In src/lib/libc/regex/regcomp.c:ordinary(), bothcases gets called
although there is no other case. This is either due to a cast missing or
one that is superfluous. The result is an endless recursion in
p_bracket, which results in a segfault.
>How-To-Repeat:
	setenv LC_CTYPE de_DE.ISO8859-1 # or -15
	echo set iclower >> ~/.exrc
	vi +/ß $NON_EMPTY_FILE # that's &szlig; = U+00DF = \337

Or use the following program instead of vi:
---8<-----8<-----8<---
#include <locale.h>
#include <regex.h>

int
main(int argc, char *argv[])
{
	regex_t re;

	setlocale(LC_CTYPE, "");

	return regcomp(&re, "ß", REG_ICASE);
}
--->8----->8----->8---

>Fix:
Either:

RCS file: /cvsroot/src/lib/libc/regex/regcomp.c,v
retrieving revision 1.18
diff -u -r1.18 regcomp.c
--- regcomp.c   7 Aug 2003 16:43:20 -0000       1.18
+++ regcomp.c   17 Sep 2004 22:41:18 -0000
@@ -1060,7 +1060,7 @@

        cap = p->g->categories;
        if ((p->g->cflags&REG_ICASE) && isalpha((unsigned char) ch)
-           && othercase((unsigned char) ch) != (unsigned char) ch)
+           && othercase((unsigned char) ch) != ch)
                bothcases(p, (unsigned char) ch);
        else {
                EMIT(OCHAR, (unsigned char)ch);


or:

RCS file: /cvsroot/src/lib/libc/regex/regcomp.c,v
retrieving revision 1.18
diff -u -r1.18 regcomp.c
--- regcomp.c	7 Aug 2003 16:43:20 -0000	1.18
+++ regcomp.c	17 Sep 2004 22:43:28 -0000
@@ -1060,7 +1060,7 @@
 
 	cap = p->g->categories;
 	if ((p->g->cflags&REG_ICASE) && isalpha((unsigned char) ch)
-	    && othercase((unsigned char) ch) != (unsigned char) ch)
+	    && (unsigned char) othercase((unsigned char) ch) != (unsigned char) ch)
 		bothcases(p, (unsigned char) ch);
 	else {
 		EMIT(OCHAR, (unsigned char)ch);


>Release-Note:
>Audit-Trail:
>Unformatted: