This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]