diff options
author | Siddhesh Poyarekar <siddhesh@redhat.com> | 2012-11-16 19:13:11 +0530 |
---|---|---|
committer | Siddhesh Poyarekar <siddhesh@redhat.com> | 2012-11-16 19:13:11 +0530 |
commit | 2b766585f9b4ffabeef2f36200c275976b93f2c7 (patch) | |
tree | d6be89abc6bfa88e5e9fd997bb4cfd94b035adc2 /stdio-common | |
parent | b1848fdeec705bc7d2f64e3a365f1ff66eeb4f0d (diff) | |
download | glibc-2b766585f9b4ffabeef2f36200c275976b93f2c7.tar.gz glibc-2b766585f9b4ffabeef2f36200c275976b93f2c7.tar.xz glibc-2b766585f9b4ffabeef2f36200c275976b93f2c7.zip |
printf should return negative value on error
[BZ #11741] Fixed bug where printf and family may return a spurious success when printing padded formats.
Diffstat (limited to 'stdio-common')
-rw-r--r-- | stdio-common/tst-put-error.c | 26 | ||||
-rw-r--r-- | stdio-common/vfprintf.c | 28 |
2 files changed, 50 insertions, 4 deletions
diff --git a/stdio-common/tst-put-error.c b/stdio-common/tst-put-error.c index 115dbd509a..7b95491725 100644 --- a/stdio-common/tst-put-error.c +++ b/stdio-common/tst-put-error.c @@ -1,3 +1,22 @@ +/* Verify that print functions return error when there is an I/O error. + + Copyright (C) 2005-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + #include <errno.h> #include <error.h> #include <stdio.h> @@ -26,6 +45,13 @@ do_test (void) printf ("fprintf = %d\n", n); if (n >= 0) error (EXIT_FAILURE, 0, "second fprintf succeeded"); + + /* Padded printing takes a different code path. */ + n = fprintf (fp, "%10000s", "foo"); + printf ("fprintf = %d\n", n); + if (n >= 0) + error (EXIT_FAILURE, 0, "padded fprintf succeeded"); + return 0; } diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c index 17d3f42a97..0c1339febd 100644 --- a/stdio-common/vfprintf.c +++ b/stdio-common/vfprintf.c @@ -87,8 +87,18 @@ # define PUT(F, S, N) _IO_sputn ((F), (S), (N)) # define PAD(Padchar) \ - if (width > 0) \ - done_add (_IO_padn (s, (Padchar), width)) + do { \ + if (width > 0) \ + { \ + unsigned int d = _IO_padn (s, (Padchar), width); \ + if (__builtin_expect (d == EOF, 0)) \ + { \ + done = -1; \ + goto all_done; \ + } \ + done_add (d); \ + } \ + } while (0) # define PUTC(C, F) _IO_putc_unlocked (C, F) # define ORIENT if (_IO_vtable_offset (s) == 0 && _IO_fwide (s, -1) != -1)\ return -1 @@ -106,8 +116,18 @@ # define PUT(F, S, N) _IO_sputn ((F), (S), (N)) # define PAD(Padchar) \ - if (width > 0) \ - done_add (_IO_wpadn (s, (Padchar), width)) + do { \ + if (width > 0) \ + { \ + unsigned int d = _IO_wpadn (s, (Padchar), width); \ + if (__builtin_expect (d == EOF, 0)) \ + { \ + done = -1; \ + goto all_done; \ + } \ + done_add (d); \ + } \ + } while (0) # define PUTC(C, F) _IO_putwc_unlocked (C, F) # define ORIENT if (_IO_fwide (s, 1) != 1) return -1 |