This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
Re: Possible bug in wcsxfrm() with included testcase
On Tue, Jul 22, 2003 at 04:35:42PM +0200, Jakub Jelinek wrote:
> On Tue, Jul 22, 2003 at 09:28:52AM -0500, Art Haas wrote:
> > I've run the amended testcase again and still see the crash. Would you
> > try it again?
>
> I see no crashes with it (both with glibc from yesterday and ~ a month
> old glibc), but the testcase depends on a) what locale this is run
> b) the content of /tmp
> If this should be a self-contained testcase, it should use a specific
> locale instead of "" and should not depend on content of some directory.
>
Hi.
Here's a new testcase. This one avoids directory reads by testing the
string ".", and the locale is specified to "C". My environment
previously was set with 'LANG=C', but now I'm running with 'LANG=en_US'
to avoid the crashes, and things are working. Some off-list mail
exchange and my desire to understand what is going on made me modify my
previous test case to this one. I think this test case meets the
requirements listed above and, if so, seems to suggest a bug.
$ cat wcsxfrm_test2.c
/* second test case attempt for wcsxfrm() */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#include <locale.h>
const char * string = ".";
/* this function comes from glibc info pages */
wchar_t *
mbstouwcs (const char *s)
{
size_t len;
wchar_t *result;
wchar_t *wcp;
wchar_t tmp[1];
mbstate_t state;
size_t nbytes;
len = strlen(s);
result = malloc((len + 1) * sizeof(wchar_t));
if (result == NULL) {
return NULL;
}
wcp = result;
memset (&state, '\0', sizeof (state));
while ((nbytes = mbrtowc (tmp, s, len, &state)) > 0)
{
if (nbytes >= (size_t) -2)
/* Invalid input string. */
return NULL;
*wcp++ = tmp[0];
len -= nbytes;
s += nbytes;
}
return result;
}
int
main(int argc, char ** argv) {
size_t xfrm_len;
wchar_t * wcstr = NULL;
wchar_t * result_wc = NULL;
setlocale (LC_COLLATE, "C");
wcstr = mbstouwcs(string);
if (wcstr == NULL) {
printf("mbstouwcs() failure\n");
return EXIT_FAILURE;
}
xfrm_len = wcsxfrm(NULL, wcstr, 0);
printf("xfrm_len: %zd\n", xfrm_len);
result_wc = malloc((xfrm_len + 1) * sizeof(wchar_t));
if (result_wc == NULL) {
printf("malloc() failure\n");
free(wcstr);
return EXIT_FAILURE;
}
wcsxfrm(result_wc, wcstr, xfrm_len + 1); /* BOOM! */
free(result_wc);
free(wcstr);
return EXIT_SUCCESS;
}
$ gcc -g -O2 -Wall -o wcsxfrm_test2 wcsxfrm_test2.c
$ EF_PROTECT_BELOW=1 ef ./wcsxfrm_test2
Electric Fence 2.2.0 Copyright (C) 1987-1999 Bruce Perens <bruce@perens.com>
xfrm_len: 1
/opt/gnu/bin/ef: line 20: 982 Segmentation fault (core dumped)
( export LD_PRELOAD=/opt/gnu/lib/libefence.so.0.0; exec $* )
$ gdb ./wcsxfrm_test2 core
#0 0x4009d09e in wcpncpy () from /lib/libc.so.6
(gdb) bt
#0 0x4009d09e in wcpncpy () from /lib/libc.so.6
#1 0x400ae0ee in wcsxfrm () from /lib/libc.so.6
#2 0x0804859d in main (argc=1, argv=0xbffff9c4) at wcsxfrm_test2.c:61
(gdb) frame 2
#2 0x0804859d in main (argc=1, argv=0xbffff9c4) at wcsxfrm_test2.c:61
61 wcsxfrm(result_wc, wcstr, xfrm_len + 1); /* BOOM! */
(gdb)
Bug or a poor test case?
Art Haas
--
Man once surrendering his reason, has no remaining guard against absurdities
the most monstrous, and like a ship without rudder, is the sport of every wind.
-Thomas Jefferson to James Smith, 1822