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]

again a gettext crash



Here are tweaks of small mistakes I made in the previous patches.
a. The size passed to gconv/iconv for its output buffer is larger than the
   room that's really present.
b. After allocation failure for freemem, set freemem_size to 0, otherwise the
   next call will think that freemem is valid and make a NULL pointer access.
c. A portability problem: Use of __alignof__ is gcc specific.


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

	* intl/dcigettext.c (alignof): New macro.
	(_nl_find_msg): Use it instead of __alignof__. Pass correct output
	buffer length to __gconv/iconv. If malloc (freemem_size) fails, set
	freemem_size to 0.

*** intl/dcigettext.c.bak	Thu May  4 12:53:41 2000
--- intl/dcigettext.c	Fri May  5 12:20:35 2000
***************
*** 110,115 ****
--- 110,123 ----
  # 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
***************
*** 795,803 ****
  	      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)
--- 804,815 ----
  	      size_t non_reversible;
  	      int res;
  
+ 	      if (freemem_size < 4)
+ 		goto resize_freemem;
+ 
  	      res = __gconv (domain->conv,
  			     &inbuf, inbuf + resultlen,
! 			     &outbuf, outbuf + freemem_size - 4,
  			     &non_reversible);
  
  	      if (res == __GCONV_OK || res == __GCONV_EMPTY_INPUT)
***************
*** 815,822 ****
  	      const char *inptr = (const char *) inbuf;
  	      size_t inleft = resultlen;
  	      char *outptr = (char *) outbuf;
! 	      size_t outleft = freemem_size;
  
  	      if (iconv (domain->conv, &inptr, &inleft, &outptr, &outleft)
  		  != (size_t) (-1))
  		{
--- 827,838 ----
  	      const char *inptr = (const char *) inbuf;
  	      size_t inleft = resultlen;
  	      char *outptr = (char *) outbuf;
! 	      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))
  		{
***************
*** 831,836 ****
--- 847,853 ----
  #  endif
  # endif
  
+ 	    resize_freemem:
  	      /* We must resize the buffer.  */
  	      freemem_size = 2 * freemem_size;
  	      if (freemem_size < 4064)
***************
*** 838,843 ****
--- 855,861 ----
  	      freemem = (char *) malloc (freemem_size);
  	      if (__builtin_expect (freemem == NULL, 0))
  		{
+ 		  freemem_size = 0;
  		  __libc_lock_unlock (lock);
  		  goto converted;
  		}
***************
*** 852,859 ****
  	  /* 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);
  	}
--- 870,877 ----
  	  /* 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]