diff options
Diffstat (limited to 'intl')
-rw-r--r-- | intl/dcigettext.c | 36 | ||||
-rw-r--r-- | intl/tst-gettext.c | 2 |
2 files changed, 29 insertions, 9 deletions
diff --git a/intl/dcigettext.c b/intl/dcigettext.c index 3c86b83f28..b52fbd58c4 100644 --- a/intl/dcigettext.c +++ b/intl/dcigettext.c @@ -110,6 +110,14 @@ void free (); # define __libc_rwlock_unlock(NAME) #endif +/* Alignment of types. */ +#if defined __GNUC__ && __GNUC__ >= 2 +# define alignof(TYPE) __alignof__ (TYPE) +#else +# define alignof(TYPE) \ + ((int) &((struct { char dummy1; TYPE dummy2; } *) 0)->dummy2) +#endif + /* @@ end of prolog @@ */ #ifdef _LIBC @@ -785,20 +793,24 @@ _nl_find_msg (domain_file, msgid, index) resultlen = p - result; } - inbuf = result; - outbuf = freemem + 4; - __libc_lock_lock (lock); + inbuf = result; + outbuf = freemem + sizeof (nls_uint32); + while (1) { # ifdef _LIBC size_t non_reversible; int res; + if (freemem_size < 4) + goto resize_freemem; + res = __gconv (domain->conv, &inbuf, inbuf + resultlen, - &outbuf, outbuf + freemem_size, + &outbuf, + outbuf + freemem_size - sizeof (nls_uint32), &non_reversible); if (res == __GCONV_OK || res == __GCONV_EMPTY_INPUT) @@ -816,8 +828,12 @@ _nl_find_msg (domain_file, msgid, index) const char *inptr = (const char *) inbuf; size_t inleft = resultlen; char *outptr = (char *) outbuf; - size_t outleft = freemem_size; + size_t outleft; + + if (freemem_size < 4) + goto resize_freemem; + outleft = freemem_size - 4; if (iconv (domain->conv, &inptr, &inleft, &outptr, &outleft) != (size_t) (-1)) { @@ -832,6 +848,7 @@ _nl_find_msg (domain_file, msgid, index) # endif # endif + resize_freemem: /* We must resize the buffer. */ freemem_size = 2 * freemem_size; if (freemem_size < 4064) @@ -839,11 +856,12 @@ _nl_find_msg (domain_file, msgid, index) freemem = (char *) malloc (freemem_size); if (__builtin_expect (freemem == NULL, 0)) { + freemem_size = 0; __libc_lock_unlock (lock); goto converted; } - outbuf = freemem + 4; + outbuf = freemem + sizeof (nls_uint32); } /* We have now in our buffer a converted string. Put this @@ -853,15 +871,15 @@ _nl_find_msg (domain_file, msgid, index) /* 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); + freemem += freemem_size & (alignof (nls_uint32) - 1); + freemem_size = freemem_size & ~ (alignof (nls_uint32) - 1); __libc_lock_unlock (lock); } /* Now domain->conv_tab[act] contains the translation of at least the variants 0 .. INDEX. */ - result = domain->conv_tab[act] + 4; + result = domain->conv_tab[act] + sizeof (nls_uint32); } converted: diff --git a/intl/tst-gettext.c b/intl/tst-gettext.c index 9ce11903aa..b897d71582 100644 --- a/intl/tst-gettext.c +++ b/intl/tst-gettext.c @@ -68,7 +68,9 @@ main (int argc, char *argv[]) setenv ("LANGUAGE", "existing-locale", 1); setenv ("LC_ALL", "non-existing-locale", 1); setenv ("LC_MESSAGES", "non-existing-locale", 1); + setenv ("LC_CTYPE", "non-existing-locale", 1); setenv ("LANG", "non-existing-locale", 1); + unsetenv ("OUTPUT_CHARSET"); /* This is the name of the existing domain with a catalog for the LC_MESSAGES category. */ textdomain ("existing-domain"); |