[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: glibc's snprintf can fail with ENOMEM: replacement needed
From: |
Bruno Haible |
Subject: |
Re: glibc's snprintf can fail with ENOMEM: replacement needed |
Date: |
Fri, 11 Apr 2008 12:43:06 +0200 |
User-agent: |
KMail/1.5.4 |
Jim Meyering wrote:
> FYI, I've just reported the problem:
>
> http://bugzilla.redhat.com/441945
> http://thread.gmane.org/gmane.comp.lib.glibc.alpha/13288
>
> Quick summary: given a small buffer, say "char b[10];" with the latest
> upstream glibc, snprintf (b, sizeof b, fmt, 0) can fail, returning -1
> with ENOMEM.
The possibility of this happening was already mentioned by Andreas Schwab
([1],[2]):
"A failure from printf does not necessarily mean an output failure. It
can also be ENOMEM or EILSEQ, which are unrelated to output."
"There are two failure modes for ENOMEM:
- inability to allocate stdio buffers
- inability to allocate conversion buffers
Only the first condition is related to stream output, and the second
condition is unique to *printf, and can happen without fputc being
called."
There are two cases of conversion buffers:
1) for float to decimal conversion, think of snprintf (NULL, "%Le", x)
or snprintf (NULL, "%Lf", x)
2) for wchar_t* to char* conversion, think of snprintf (NULL, "%ls", s).
and two other cases of memory allocation:
3) for integer to decimal conversion,
4) for padding.
At least in the first case, I don't see how the number of output bytes could
be determined without doing the actual conversion. (In the second case, the
conversion could be done with a fixed-size buffer, using the wcsnrtombs and
mbsnrtowcs functions. In the third case, a fixed-size buffer is also possible.
In the fourth case, a different code path for snprintf could avoid actually
doing the padding.)
> replacement needed
Any replacement function can also fail with ENOMEM, at least in case 1.
Bruno
[1] http://lists.gnu.org/archive/html/bug-coreutils/2007-10/msg00139.html
[2] http://lists.gnu.org/archive/html/bug-coreutils/2007-10/msg00148.html