gconv_open patch (4)
Bruno Haible
haible@ilog.fr
Mon Jul 17 10:46:00 GMT 2000
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;
}
More information about the Libc-alpha
mailing list