This is the mail archive of the
libc-alpha@sourceware.cygnus.com
mailing list for the glibc project.
gettext gconv error handling
- To: libc-alpha at sourceware dot cygnus dot com
- Subject: gettext gconv error handling
- From: Bruno Haible <haible at ilog dot fr>
- Date: Tue, 2 May 2000 15:43:25 +0200 (MET DST)
The other reason why the automatic translation feature of gettext doesn't
work in glibc is that the __gconv return value is not interpreted correctly.
Also, the "goto out;" statements for error handling jump (that I introduced
a few days ago) may cause a NULL+4 pointer access later. Here is a fix for
both.
2000-05-01 Bruno Haible <clisp.cons.org>
* intl/dcigettext.c (_nl_find_msg): Terminate __gconv loop if return
value is == __GCONV_OK or == __GCONV_EMPTY_INPUT, not != __GCONV_OK.
In case of failure, goto converted.
*** intl/dcigettext.c.bak Fri Apr 28 12:38:31 2000
--- intl/dcigettext.c Mon May 1 15:37:40 2000
***************
*** 787,819 ****
__libc_lock_lock (lock);
# ifdef _LIBC
! {
! size_t written;
! int res;
!
! while ((res = __gconv (domain->conv,
! &inbuf, inbuf + resultlen,
! &outbuf, outbuf + freemem_size,
! &written)) == __GCONV_OK)
! {
! if (res != __GCONV_FULL_OUTPUT)
! goto out;
!
! /* We must resize the buffer. */
! freemem_size = MAX (2 * freemem_size, 4064);
! freemem = (char *) malloc (freemem_size);
! if (freemem == NULL)
! goto out;
!
! inbuf = result;
! outbuf = freemem + 4;
! }
! }
# else
# if HAVE_ICONV
- for (;;)
- {
const char *inptr = (const char *) inbuf;
size_t inleft = resultlen;
char *outptr = (char *) outbuf;
--- 787,815 ----
__libc_lock_lock (lock);
+ for (;;)
+ {
# ifdef _LIBC
! size_t non_reversible;
! int res;
!
! res = __gconv (domain->conv,
! &inbuf, inbuf + resultlen,
! &outbuf, outbuf + freemem_size,
! &non_reversible);
!
! if (res == __GCONV_OK || res == __GCONV_EMPTY_INPUT)
! break;
!
! if (res != __GCONV_FULL_OUTPUT)
! {
! __libc_lock_unlock (lock);
! goto converted;
! }
!
! inbuf = result;
# else
# if HAVE_ICONV
const char *inptr = (const char *) inbuf;
size_t inleft = resultlen;
char *outptr = (char *) outbuf;
***************
*** 826,845 ****
break;
}
if (errno != E2BIG)
! goto out;
/* We must resize the buffer. */
freemem_size = 2 * freemem_size;
if (freemem_size < 4064)
freemem_size = 4064;
freemem = (char *) malloc (freemem_size);
! if (freemem == NULL)
! goto out;
outbuf = freemem + 4;
}
- # endif
- # endif
/* We have now in our buffer a converted string. Put this
into the table of conversions. */
--- 822,847 ----
break;
}
if (errno != E2BIG)
! {
! __libc_lock_unlock (lock);
! goto converted;
! }
! # endif
! # endif
/* We must resize the buffer. */
freemem_size = 2 * freemem_size;
if (freemem_size < 4064)
freemem_size = 4064;
freemem = (char *) malloc (freemem_size);
! if (__builtin_expect (freemem == NULL, 0))
! {
! __libc_lock_unlock (lock);
! goto converted;
! }
outbuf = freemem + 4;
}
/* We have now in our buffer a converted string. Put this
into the table of conversions. */
***************
*** 848,857 ****
/* Shrink freemem, but keep it aligned. */
freemem_size -= outbuf - freemem;
freemem = outbuf;
! freemem += freemem_size & 3;
! freemem_size = freemem_size & ~3;
- out:
__libc_lock_unlock (lock);
}
--- 850,858 ----
/* Shrink freemem, but keep it aligned. */
freemem_size -= outbuf - freemem;
freemem = outbuf;
! freemem += freemem_size & (__alignof__ (nls_uint32) - 1);
! freemem_size = freemem_size & ~ (__alignof__ (nls_uint32) - 1);
__libc_lock_unlock (lock);
}