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]

gconv_open patch (4)



Sorry for the broken fix last week. I was confused because three different
structs have a __data field.

The core dump during "localedef -c -f UTF-8 -i de_DE de_DE.UTF-8" was
still present before Jakub's patch. It crashed at

Program received signal SIGSEGV, Segmentation fault.
__gconv_transform_internal_utf8 (step=0x81cd2b0, data=0x81cd73c, 
    inptrp=0xbfffed30, inend=0x81cd8cc '\223' <repeats 200 times>..., 
    outbufstart=0x0, irreversible=0xbfffee08, do_flush=0, consume_incomplete=0)
    at ../iconv/skeleton.c:442
442                 if (trans->__trans_context_fct != NULL)

because 'trans' is uninitialized garbage (0x93939393), which comes from
the __next field:

(gdb) print *cd
$2 = {__nsteps = 2, __steps = 0x81cd278, __data = 0x81cd718}
(gdb) print cd->__steps[0]
$3 = {__shlib_handle = 0x81cd350, 
  __modname = 0x81bb586 "/packages/glibc22/lib/gconv/ISO8859-1.so", 
  __counter = 1, __from_name = 0x81cd328 "ISO-8859-1//", 
  __to_name = 0x81bb57d "INTERNAL", __fct = 0x40136660 <gconv>, 
  __init_fct = 0x401365b0 <gconv_init>, __end_fct = 0, __min_needed_from = 1, 
  __max_needed_from = 1, __min_needed_to = 4, __max_needed_to = 4, 
  __stateful = 0, __data = 0x40137f14}
(gdb) print cd->__steps[1]
$4 = {__shlib_handle = 0x0, __modname = 0x0, __counter = 2147483647, 
  __from_name = 0x81bb57d "INTERNAL", __to_name = 0x81cd300 "ISO-10646/UTF8/", 
  __fct = 0x400382c0 <__gconv_transform_internal_utf8>, __init_fct = 0, 
  __end_fct = 0, __min_needed_from = 4, __max_needed_from = 4, 
  __min_needed_to = 1, __max_needed_to = 6, __stateful = 0, __data = 0x0}
(gdb) print ((struct __gconv_step_data *)cd->__data)[0]
$15 = {__outbuf = 0x81cd778 "B", __outbufend = 0x81d56f8 "×", __flags = 0, 
  __invocation_counter = 1, __internal_use = 0, __statep = 0x81cd730, 
  __state = {__count = 0, __value = {__wch = 0, __wchb = "\000\000\000"}}, 
  __trans = 0x0}
(gdb) print ((struct __gconv_step_data *)cd->__data)[1]
$16 = {
  __outbuf = 0x81d66c8 "Berechnung der GröĂ\237e der Tabelle der Zeichenklassen: Dies kann einige Zeit dauern...", __outbufend = 0x81d76b0 "×", __flags = 1, 
  __invocation_counter = 0, __internal_use = 0, __statep = 0x81cd754, 
  __state = {__count = 0, __value = {__wch = 0, __wchb = "\000\000\000"}}, 
  __trans = 0x81d5710}
(gdb) print * ((struct __gconv_step_data *)cd->__data)[1].__trans
$18 = {__trans_fct = 0x4003ac70 <__gconv_transliterate>, 
  __trans_context_fct = 0, __trans_end_fct = 0, __data = 0x93939393, 
  __next = 0x93939393}

The patch below
  * initializes __data to the value computed by the trans_init_fct,
    not NULL,
  * simplifies the algorithm used to append an element to a linked list.

Bruno


2000-07-17  Bruno Haible  <haible@clisp.cons.org>

	* iconv/gconv_open.c (__gconv_open): Initialize the __data
	field of struct __gconv_trans_data differently. Don't pass NULL to
	trans_init_fct. Simplify list append operation.

*** glibc-cvs/iconv/gconv_open.c.old	Mon Jul 17 16:52:38 2000
--- glibc-cvs/iconv/gconv_open.c	Mon Jul 17 17:52:33 2000
***************
*** 212,224 ****
  
  		      /* Match!  Now try the initializer.  */
  		      if (runp->trans_init_fct == NULL
! 			  || (runp->trans_init_fct (data, steps[cnt].__to_name)
  			      == __GCONV_OK))
  			{
  			  /* Append at the end of the list.  */
  			  struct __gconv_trans_data *newp;
! 			  struct __gconv_trans_data *endp;
! 			  struct __gconv_trans_data *lastp;
  
  			  newp = (struct __gconv_trans_data *)
  			    malloc (sizeof (struct __gconv_trans_data));
--- 212,223 ----
  
  		      /* Match!  Now try the initializer.  */
  		      if (runp->trans_init_fct == NULL
! 			  || (runp->trans_init_fct (&data, steps[cnt].__to_name)
  			      == __GCONV_OK))
  			{
  			  /* Append at the end of the list.  */
  			  struct __gconv_trans_data *newp;
! 			  struct __gconv_trans_data **lastp;
  
  			  newp = (struct __gconv_trans_data *)
  			    malloc (sizeof (struct __gconv_trans_data));
***************
*** 228,245 ****
  			  newp->__trans_fct = runp->trans_fct;
  			  newp->__trans_context_fct = runp->trans_context_fct;
  			  newp->__trans_end_fct = runp->trans_end_fct;
! 			  newp->__data = NULL;
  			  newp->__next = NULL;
  
! 			  lastp = NULL;
! 			  for (endp = result->__data[cnt].__trans;
! 			       endp != NULL; endp = endp->__next)
! 			    lastp = endp;
  
! 			  if (lastp == NULL)
! 			    result->__data[cnt].__trans = newp;
! 			  else
! 			    lastp->__next = newp;
  			}
  		      break;
  		    }
--- 227,240 ----
  			  newp->__trans_fct = runp->trans_fct;
  			  newp->__trans_context_fct = runp->trans_context_fct;
  			  newp->__trans_end_fct = runp->trans_end_fct;
! 			  newp->__data = data;
  			  newp->__next = NULL;
  
! 			  lastp = &result->__data[cnt].__trans;
! 			  while (*lastp != NULL)
! 			    lastp = &(*lastp)->__next;
  
! 			  *lastp = newp;
  			}
  		      break;
  		    }

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