Bug 441945 - [RFE] snprintf must not fail with ENOMEM
Summary: [RFE] snprintf must not fail with ENOMEM
Status: NEW
Alias: None
Product: Fedora
Classification: Fedora
Component: glibc   
(Show other bugs)
Version: rawhide
Hardware: All Linux
low
low
Target Milestone: ---
Assignee: glibc team
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Keywords: Reopened, Triaged
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2008-04-10 20:00 UTC by Jim Meyering
Modified: 2017-05-31 15:25 UTC (History)
6 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2008-04-14 10:32:05 UTC
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

Description Jim Meyering 2008-04-10 20:00:43 UTC
Description of problem: snprintf can fail with ENOMEM
Printing into a 200-byte buffer should never have to allocate an arbitrarily
large amount of memory.  In fact, snprintf should never allocate memory in a
manner that can fail, period.

Version-Release number of selected component (if applicable):
glibc-2.7.90-13.x86_64

How reproducible: every time


Steps to Reproduce:
cat <<\EOF > k.c
/* snprintf should not allocate memory, *ever*.
   POSIX says that snprintf may fail with EOVERFLOW (n > INT_MAX or size of
   output would exceed INT_MAX).  It appears not to allow failure with ENOMEM,
   as happens here:

   $ zsh -c 'ulimit -v 5000; ./a.out %$[5*2**20]d'
   fmt: %5242880d  retval=-1  errno=Cannot allocate memory
   # Same with bash, but it requires more memory:
   $ bash -c 'ulimit -v 12000; ./a.out %$[12*2**20]d'
  */
#include <stdio.h>
#include <string.h>
#include <errno.h>
int
main(int argc, char **argv)
{
  char buf[200];
  char *fmt = argv[1];
  if (argc < 2)
    return 1;
  int n = snprintf (buf, sizeof buf, fmt, 1);
  int saved_errno = errno;
  printf ("fmt: %s  retval=%d  errno=%s\n", fmt, n,
	   n < 0 ? strerror(saved_errno) : "");
  return 0;
}
EOF
gcc k.c
zsh -c 'ulimit -v 5000; ./a.out %$[5*2**20]d'
  
Actual results:
fmt: %5242880d  retval=-1  errno=Cannot allocate memory

Expected results:
fmt: %5242880d  retval=5242880  errno=

Additional info:

Comment 1 Jim Meyering 2008-04-10 22:12:53 UTC
Regarding POSIX conformance, consider this:
snprintf (NULL, 0, fmt, 1); currently, that fails just like the example above. 
However, POSIX requires something else:

   If the value of n is zero on a call to snprintf(),
   nothing shall be written, the number of bytes that
   would have been written had n been sufficiently large
   excluding the terminating null shall be returned, and
   s may be a null pointer.


Comment 2 Jakub Jelinek 2008-04-14 10:32:05 UTC
That applies only upon successful completion.  Even for n 0 if there are errors
snprintf is supposed to return -1 and set errno.
For cases like:
#include <errno.h>
#include <locale.h>
#include <stdio.h>

int
main (void)
{
  setlocale (LC_ALL, "en_US.ISO-8859-1");
  int ret = snprintf (NULL, 0, "%lC\n", (wint_t) 0x10c);
  printf ("%d %m\n", ret);
  return 0;
}

where ret should be -1 and errno EILSEQ, but even cases where memory was needed
and -1/ENOMEM is returned.

Comment 3 Jim Meyering 2008-04-14 11:58:13 UTC
Hi Jakub,

That's a fine example, but it merely suggests that the crystal clear wording in
POSIX (quoted above) should be relaxed to allow snprintf to return -1 upon
EILSEQ.  There is already explicit language that implies snprintf w/n=0 will not
fail with ENOMEM, so at least in that latter case, glibc violates the intent of
the standard.

Comment 4 Jim Meyering 2010-11-03 10:08:51 UTC
Hi guys,

Please do not close this until snprintf stops allocating from the heap at least for integer and string formats.  If you prefer, I can change the title to a request for improved QoI, so it doesn't look like a bug, but imho, it should be considered a bug for snprintf(NULL,0, ...) to allocate memory when the format involves no floating point conversion specifier.

http://thread.gmane.org/gmane.comp.lib.gnulib.bugs/23838

As I said there, FreeBSD's snprintf appears to get this right,
so glibc's should, too.

Comment 5 Fedora Admin XMLRPC Client 2011-11-14 19:14:41 UTC
This package has changed ownership in the Fedora Package Database.  Reassigning to the new owner of this component.

Comment 6 Fedora Admin XMLRPC Client 2011-11-15 04:46:45 UTC
This package has changed ownership in the Fedora Package Database.  Reassigning to the new owner of this component.

Comment 7 Jeff Law 2012-02-03 20:03:16 UTC
Just changing status so this pops up in my searches for bugs needing my attention

Comment 8 Fedora Admin XMLRPC Client 2013-01-28 20:07:30 UTC
This package has changed ownership in the Fedora Package Database.  Reassigning to the new owner of this component.


Note You need to log in before you can comment on or make changes to this bug.