Bug (?) in sprintf family?

Jeff Johnston jjohnstn@redhat.com
Mon May 5 22:45:00 GMT 2008



Eric Blake wrote:
> Eric Blake <ebb9 <at> byu.net> writes:
>
>   
>> It seems like the fix would be making sure that in vfprintf.c, when __SMBF is 
>> set, __sprint_r must allocate a string even if it will not be populating it, 
>> since asprintf.c depends on the string being pre-allocated large enough to 
>>     
> hold 
>   
>> the trailing NUL.
>>     
>
> Yep.  The old __sprint_r calls __sfvwrite_r calls cantwrite calls __smakebuf_r 
> which always mallocs a string the first time through asprintf, but the new 
> __sprint_r lacks this malloc.  Fixed as follows, as well as catching all 
> remaining string-based printf functions that don't need full I/O baggage at 
> link time.  Okay to apply?
>
>   

Yes.  Thanks for fixing this.

-- Jeff J.
> 2008-04-29  Eric Blake  <ebb9@byu.net>
>
> 	Fix 2008-04-14 regression in asprintf(ptr,"").
> 	* libc/stdio/asnprintf.c (asnprintf, _asnprintf_r): Avoid stdio
> 	baggage.
> 	* libc/stdio/asniprintf.c (asniprintf, _asniprintf_r): Likewise.
> 	* libc/stdio/asiprintf.c (asiprintf, _asiprintf_r): Likewise.
> 	* libc/stdio/vasniprintf.c (_vasniprintf_r): Likewise.
> 	* libc/stdio/vsnprintf.c (_vsnprintf_r): Likewise.
> 	* libc/stdio/vfprintf.c (__sprint_r) [STRING_ONLY]: Always malloc
> 	an initial buffer for asprintf.
>
>
> Index: libc/stdio/asiprintf.c
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/stdio/asiprintf.c,v
> retrieving revision 1.4
> diff -u -p -r1.4 asiprintf.c
> --- libc/stdio/asiprintf.c	4 May 2007 02:55:16 -0000	1.4
> +++ libc/stdio/asiprintf.c	29 Apr 2008 22:59:43 -0000
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright (c) 1990, 2007 The Regents of the University of California.
> + * Copyright (c) 1990 The Regents of the University of California.
>   * All rights reserved.
>   *
>   * Redistribution and use in source and binary forms are permitted
> @@ -40,7 +40,7 @@ _DEFUN(_asiprintf_r, (ptr, strp, fmt),
>    f._bf._size = f._w = 0;
>    f._file = -1;  /* No file. */
>    va_start (ap, fmt);
> -  ret = _vfiprintf_r (ptr, &f, fmt, ap);
> +  ret = _svfiprintf_r (ptr, &f, fmt, ap);
>    va_end (ap);
>    if (ret >= 0)
>      {
> @@ -67,7 +67,7 @@ _DEFUN(asiprintf, (strp, fmt),
>    f._bf._size = f._w = 0;
>    f._file = -1;  /* No file. */
>    va_start (ap, fmt);
> -  ret = _vfiprintf_r (_REENT, &f, fmt, ap);
> +  ret = _svfiprintf_r (_REENT, &f, fmt, ap);
>    va_end (ap);
>    if (ret >= 0)
>      {
> Index: libc/stdio/asniprintf.c
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/stdio/asniprintf.c,v
> retrieving revision 1.2
> diff -u -p -r1.2 asniprintf.c
> --- libc/stdio/asniprintf.c	9 May 2007 19:27:30 -0000	1.2
> +++ libc/stdio/asniprintf.c	29 Apr 2008 22:59:43 -0000
> @@ -1,4 +1,4 @@
> -/* Copyright (C) 2007 Eric Blake
> +/* Copyright (C) 2007, 2008 Eric Blake
>   * Permission to use, copy, modify, and distribute this software
>   * is freely granted, provided that this notice is preserved.
>   */
> @@ -48,7 +48,7 @@ _DEFUN(_asniprintf_r, (ptr, buf, lenp, f
>    f._bf._size = f._w = len;
>    f._file = -1;  /* No file. */
>    va_start (ap, fmt);
> -  ret = _vfiprintf_r (ptr, &f, fmt, ap);
> +  ret = _svfiprintf_r (ptr, &f, fmt, ap);
>    va_end (ap);
>    if (ret < 0)
>      return NULL;
> @@ -95,7 +95,7 @@ _DEFUN(asniprintf, (buf, lenp, fmt),
>    f._bf._size = f._w = len;
>    f._file = -1;  /* No file. */
>    va_start (ap, fmt);
> -  ret = _vfiprintf_r (ptr, &f, fmt, ap);
> +  ret = _svfiprintf_r (ptr, &f, fmt, ap);
>    va_end (ap);
>    if (ret < 0)
>      return NULL;
> Index: libc/stdio/asnprintf.c
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/stdio/asnprintf.c,v
> retrieving revision 1.2
> diff -u -p -r1.2 asnprintf.c
> --- libc/stdio/asnprintf.c	9 May 2007 19:27:30 -0000	1.2
> +++ libc/stdio/asnprintf.c	29 Apr 2008 22:59:43 -0000
> @@ -1,4 +1,4 @@
> -/* Copyright (C) 2007 Eric Blake
> +/* Copyright (C) 2007, 2008 Eric Blake
>   * Permission to use, copy, modify, and distribute this software
>   * is freely granted, provided that this notice is preserved.
>   */
> @@ -48,7 +48,7 @@ _DEFUN(_asnprintf_r, (ptr, buf, lenp, fm
>    f._bf._size = f._w = len;
>    f._file = -1;  /* No file. */
>    va_start (ap, fmt);
> -  ret = _vfprintf_r (ptr, &f, fmt, ap);
> +  ret = _svfprintf_r (ptr, &f, fmt, ap);
>    va_end (ap);
>    if (ret < 0)
>      return NULL;
> @@ -95,7 +95,7 @@ _DEFUN(asnprintf, (buf, lenp, fmt),
>    f._bf._size = f._w = len;
>    f._file = -1;  /* No file. */
>    va_start (ap, fmt);
> -  ret = _vfprintf_r (ptr, &f, fmt, ap);
> +  ret = _svfprintf_r (ptr, &f, fmt, ap);
>    va_end (ap);
>    if (ret < 0)
>      return NULL;
> Index: libc/stdio/vasniprintf.c
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/stdio/vasniprintf.c,v
> retrieving revision 1.2
> diff -u -p -r1.2 vasniprintf.c
> --- libc/stdio/vasniprintf.c	9 May 2007 19:27:30 -0000	1.2
> +++ libc/stdio/vasniprintf.c	29 Apr 2008 22:59:43 -0000
> @@ -1,4 +1,4 @@
> -/* Copyright (C) 2007 Eric Blake
> +/* Copyright (C) 2007, 2008 Eric Blake
>   * Permission to use, copy, modify, and distribute this software
>   * is freely granted, provided that this notice is preserved.
>   */
> @@ -47,7 +47,7 @@ _DEFUN(_vasniprintf_r, (ptr, buf, lenp, 
>      }
>    f._bf._size = f._w = len;
>    f._file = -1;  /* No file. */
> -  ret = _vfiprintf_r (ptr, &f, fmt, ap);
> +  ret = _svfiprintf_r (ptr, &f, fmt, ap);
>    if (ret < 0)
>      return NULL;
>    *lenp = ret;
> Index: libc/stdio/vfprintf.c
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/stdio/vfprintf.c,v
> retrieving revision 1.69
> diff -u -p -r1.69 vfprintf.c
> --- libc/stdio/vfprintf.c	14 Apr 2008 21:14:55 -0000	1.69
> +++ libc/stdio/vfprintf.c	29 Apr 2008 22:59:43 -0000
> @@ -178,6 +178,18 @@ _DEFUN(__sprint_r, (ptr, fp, uio),
>  	register struct __siov *iov;
>  	register _CONST char *p = NULL;
>  
> +        /* Check if we are called by asprintf family for initial buffer.  */
> +        if (fp->_flags & __SMBF && !fp->_bf._base)
> +        {
> +		fp->_bf._base = fp->_p = _malloc_r (ptr, 64);
> +		if (!fp->_p)
> +		{
> +			ptr->_errno = ENOMEM;
> +			goto err;
> +		}
> +        	fp->_bf._size = 64;
> +        }
> +
>  	iov = uio->uio_iov;
>  	len = 0;
>  
> Index: libc/stdio/vsnprintf.c
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/stdio/vsnprintf.c,v
> retrieving revision 1.8
> diff -u -p -r1.8 vsnprintf.c
> --- libc/stdio/vsnprintf.c	4 Apr 2007 18:32:49 -0000	1.8
> +++ libc/stdio/vsnprintf.c	29 Apr 2008 22:59:43 -0000
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright (c) 1990, 2007 The Regents of the University of California.
> + * Copyright (c) 1990 The Regents of the University of California.
>   * All rights reserved.
>   *
>   * Redistribution and use in source and binary forms are permitted
> @@ -61,7 +61,7 @@ _DEFUN(_vsnprintf_r, (ptr, str, size, fm
>    f._bf._base = f._p = (unsigned char *) str;
>    f._bf._size = f._w = (size > 0 ? size - 1 : 0);
>    f._file = -1;  /* No file. */
> -  ret = _vfprintf_r (ptr, &f, fmt, ap);
> +  ret = _svfprintf_r (ptr, &f, fmt, ap);
>    if (ret < EOF)
>      ptr->_errno = EOVERFLOW;
>    if (size > 0)
>
>
>   



More information about the Newlib mailing list