This is the mail archive of the libc-alpha@sourceware.cygnus.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]

gettext gconv error handling



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);
  	}
  

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