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

Re: strange bytes in "locale -m" output


The bug occurs in the processing of

             fscanf (fp, " <code_set_name> %as", &name)

line. The result string is realloc()ed at the end of vfscanf, but
without the terminating NUL byte.

Here is a fix: two occurrences of
    *str = '\0';
replaced with
    *str++ = '\0;

The realloc() code for the multibyte/widechar case has a number
of other bugs, which are also fixed in the patch below. In particular,
if after 97 bytes a wide char is converted to multibyte and only 100
bytes are allocated, the previous code would realloc to at least 103
bytes and reposition 'str' to point to byte 100, not to byte 97, of
the new realloc()ed string. And in case of realloc() failure the
terminating NUL byte would be put at the wrong place.


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

	* stdio-common/vfscanf.c (__vfscanf, _IO_vfscanf): Fix bugs in
	reallocation logic for MALLOC (%as, %aS directives).

*** glibc-2000-08-29/stdio-common/vfscanf.c.bak	Tue Aug 29 21:43:08 2000
--- glibc-2000-08-29/stdio-common/vfscanf.c	Thu Sep 21 18:31:39 2000
***************
*** 858,889 ****
  		      {
  			/* We have to enlarge the buffer if the `a' flag
  			   was given.  */
! 			str = (char *) realloc (*strptr, strsize * 2);
! 			if (str == NULL)
  			  {
  			    /* Can't allocate that much.  Last-ditch
  			       effort.  */
! 			    str = (char *) realloc (*strptr, strsize + 1);
! 			    if (str == NULL)
  			      {
  				/* We lose.  Oh well.  Terminate the
  				   string and stop converting,
  				   so at least we don't skip any input.  */
! 				((char *) (*strptr))[strsize - 1] = '\0';
  				++done;
  				conv_error ();
  			      }
  			    else
  			      {
! 				*strptr = (char *) str;
! 				str += strsize;
! 				++strsize;
  			      }
  			  }
  			else
  			  {
! 			    *strptr = (char *) str;
! 			    str += strsize;
  			    strsize *= 2;
  			  }
  		      }
--- 858,893 ----
  		      {
  			/* We have to enlarge the buffer if the `a' flag
  			   was given.  */
! 			size_t strleng = str - *strptr;
! 			char *newstr;
! 
! 			newstr = (char *) realloc (*strptr, strsize * 2);
! 			if (newstr == NULL)
  			  {
  			    /* Can't allocate that much.  Last-ditch
  			       effort.  */
! 			    newstr = (char *) realloc (*strptr,
! 						       strleng + MB_CUR_MAX);
! 			    if (newstr == NULL)
  			      {
  				/* We lose.  Oh well.  Terminate the
  				   string and stop converting,
  				   so at least we don't skip any input.  */
! 				((char *) (*strptr))[strleng] = '\0';
  				++done;
  				conv_error ();
  			      }
  			    else
  			      {
! 				*strptr = newstr;
! 				str = newstr + strleng;
! 				strsize = strleng + MB_CUR_MAX;
  			      }
  			  }
  			else
  			  {
! 			    *strptr = newstr;
! 			    str = newstr + strleng;
  			    strsize *= 2;
  			  }
  		      }
***************
*** 950,977 ****
  		      && str + n >= *strptr + strsize)
  		    {
  		      /* Enlarge the buffer.  */
! 		      str = (char *) realloc (*strptr,
! 					      (str + n + 1) - *strptr);
! 		      if (str == NULL)
  			{
  			  /* We lose.  Oh well.  Terminate the string
  			     and stop converting, so at least we don't
  			     skip any input.  */
! 			  ((char *) (*strptr))[strsize - 1] = '\0';
  			  ++done;
  			  conv_error ();
  			}
  		      else
  			{
! 			  *strptr = (char *) str;
! 			  str = ((char *) *strptr) + strsize;
! 			  strsize = (str + n + 1) - *strptr;
  			}
  		    }
  
  		  str = __mempcpy (str, buf, n);
  #endif
! 		  *str = '\0';
  
  		  if ((flags & MALLOC) && str - *strptr != strsize)
  		    {
--- 954,983 ----
  		      && str + n >= *strptr + strsize)
  		    {
  		      /* Enlarge the buffer.  */
! 		      size_t strleng = str - *strptr;
! 		      char *newstr;
! 
! 		      newstr = (char *) realloc (*strptr, strleng + n + 1);
! 		      if (newstr == NULL)
  			{
  			  /* We lose.  Oh well.  Terminate the string
  			     and stop converting, so at least we don't
  			     skip any input.  */
! 			  ((char *) (*strptr))[strleng] = '\0';
  			  ++done;
  			  conv_error ();
  			}
  		      else
  			{
! 			  *strptr = newstr;
! 			  str = newstr + strleng;
! 			  strsize = strleng + n + 1;
  			}
  		    }
  
  		  str = __mempcpy (str, buf, n);
  #endif
! 		  *str++ = '\0';
  
  		  if ((flags & MALLOC) && str - *strptr != strsize)
  		    {
***************
*** 1028,1035 ****
  			    /* Can't allocate that much.  Last-ditch
                                 effort.  */
  			    wstr = (wchar_t *) realloc (*strptr,
! 							(strsize
! 							 + sizeof (wchar_t)));
  			    if (wstr == NULL)
  			      {
  				/* We lose.  Oh well.  Terminate the string
--- 1034,1041 ----
  			    /* Can't allocate that much.  Last-ditch
                                 effort.  */
  			    wstr = (wchar_t *) realloc (*strptr,
! 							(strsize + 1)
! 							* sizeof (wchar_t));
  			    if (wstr == NULL)
  			      {
  				/* We lose.  Oh well.  Terminate the string
***************
*** 2030,2037 ****
  			      /* Can't allocate that much.  Last-ditch
  				 effort.  */
  			      wstr = (wchar_t *)
! 				realloc (*strptr, (strsize
! 						   + sizeof (wchar_t)));
  			      if (wstr == NULL)
  				{
  				  /* We lose.  Oh well.  Terminate the string
--- 2036,2043 ----
  			      /* Can't allocate that much.  Last-ditch
  				 effort.  */
  			      wstr = (wchar_t *)
! 				realloc (*strptr, (strsize + 1)
! 						  * sizeof (wchar_t));
  			      if (wstr == NULL)
  				{
  				  /* We lose.  Oh well.  Terminate the string
***************
*** 2227,2258 ****
  			  && str + MB_CUR_MAX >= *strptr + strsize)
  			{
  			  /* Enlarge the buffer.  */
! 			  str = (char *) realloc (*strptr, 2 * strsize);
! 			  if (str == NULL)
  			    {
  			      /* Can't allocate that much.  Last-ditch
  				 effort.  */
! 			      str = (char *) realloc (*strptr, strsize + 1);
! 			      if (str == NULL)
  				{
  				  /* We lose.  Oh well.  Terminate the string
  				     and stop converting, so at least we don't
  				     skip any input.  */
! 				  (*strptr)[strsize - 1] = '\0';
  				  ++done;
  				  conv_error ();
  				}
  			      else
  				{
! 				  *strptr = str;
! 				  str += strsize;
! 				  ++strsize;
  				}
  			    }
  			  else
  			    {
! 			      *strptr = str;
! 			      str += strsize;
  			      strsize *= 2;
  			    }
  			}
--- 2233,2268 ----
  			  && str + MB_CUR_MAX >= *strptr + strsize)
  			{
  			  /* Enlarge the buffer.  */
! 			  size_t strleng = str - *strptr;
! 			  char *newstr;
! 
! 			  newstr = (char *) realloc (*strptr, 2 * strsize);
! 			  if (newstr == NULL)
  			    {
  			      /* Can't allocate that much.  Last-ditch
  				 effort.  */
! 			      newstr = (char *) realloc (*strptr,
! 							 strleng + MB_CUR_MAX);
! 			      if (newstr == NULL)
  				{
  				  /* We lose.  Oh well.  Terminate the string
  				     and stop converting, so at least we don't
  				     skip any input.  */
! 				  ((char *) (*strptr))[strleng] = '\0';
  				  ++done;
  				  conv_error ();
  				}
  			      else
  				{
! 				  *strptr = newstr;
! 				  str = newstr + strleng;
! 				  strsize = strleng + MB_CUR_MAX;
  				}
  			    }
  			  else
  			    {
! 			      *strptr = newstr;
! 			      str = newstr + strleng;
  			      strsize *= 2;
  			    }
  			}
***************
*** 2336,2363 ****
  		      && str + n >= *strptr + strsize)
  		    {
  		      /* Enlarge the buffer.  */
! 		      str = (char *) realloc (*strptr,
! 					      (str + n + 1) - *strptr);
! 		      if (str == NULL)
  			{
  			  /* We lose.  Oh well.  Terminate the string
  			     and stop converting, so at least we don't
  			     skip any input.  */
! 			  ((char *) (*strptr))[strsize - 1] = '\0';
  			  ++done;
  			  conv_error ();
  			}
  		      else
  			{
! 			  *strptr = (char *) str;
! 			  str = ((char *) *strptr) + strsize;
! 			  strsize = (str + n + 1) - *strptr;
  			}
  		    }
  
  		  str = __mempcpy (str, buf, n);
  #endif
! 		  *str = '\0';
  
  		  if ((flags & MALLOC) && str - *strptr != strsize)
  		    {
--- 2346,2375 ----
  		      && str + n >= *strptr + strsize)
  		    {
  		      /* Enlarge the buffer.  */
! 		      size_t strleng = str - *strptr;
! 		      char *newstr;
! 
! 		      newstr = (char *) realloc (*strptr, strleng + n + 1);
! 		      if (newstr == NULL)
  			{
  			  /* We lose.  Oh well.  Terminate the string
  			     and stop converting, so at least we don't
  			     skip any input.  */
! 			  ((char *) (*strptr))[strleng] = '\0';
  			  ++done;
  			  conv_error ();
  			}
  		      else
  			{
! 			  *strptr = newstr;
! 			  str = newstr + strleng;
! 			  strsize = strleng + n + 1;
  			}
  		    }
  
  		  str = __mempcpy (str, buf, n);
  #endif
! 		  *str++ = '\0';
  
  		  if ((flags & MALLOC) && str - *strptr != strsize)
  		    {

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