]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
printf should return negative value on error
authorSiddhesh Poyarekar <siddhesh@redhat.com>
Fri, 16 Nov 2012 13:43:11 +0000 (19:13 +0530)
committerSiddhesh Poyarekar <siddhesh@redhat.com>
Fri, 16 Nov 2012 13:43:11 +0000 (19:13 +0530)
[BZ #11741]
Fixed bug where printf and family may return a spurious success when
printing padded formats.

ChangeLog
NEWS
libio/fileops.c
libio/iopadn.c
libio/iowpadn.c
libio/libioP.h
stdio-common/tst-put-error.c
stdio-common/vfprintf.c

index 6d522d60db0008208df57f7173a5f99f8608955e..fb21238ecfb77c33c36c825cd1f3b8c00a359695 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2012-11-16  Siddhesh Poyarekar  <siddhesh@redhat.com>
+
+       [BZ #11741]
+       * libio/fileops.c (_IO_new_file_write): Correctly return error.
+       (_IO_new_file_xsputn): Also return EOF if none of the input
+       data was written when overflow failed.
+       * libio/iopadn.c (_IO_padn): Likewise.
+       * libio/iowpadn.c (_IO_wpadn): Likewise.
+       * stdio-common/tst-put-error.c: Add copyright notice.
+       (do_test): Add case for printing padded string.
+       * stdio-common/vfprintf [!COMPILE_WPRINTF] (PAD): Flag error if
+       _IO_padn returned error.
+       [COMPILE_WPRINTF] (PAD): Flag error if _IO_wpadn returned error.
+       * libio/libioP.h (_IO_xsputn_t): Note in comment that xsputn can
+       return EOF.
+
 2012-11-16  Siddhesh Poyarekar  <siddhesh@redhat.com>
 
        * libio/libioP.h: Add comment note that the references to C++
diff --git a/NEWS b/NEWS
index 9791e30dbfdfa9f3f41dfd28db6fc71a0010d3d4..4f57ddb276921a3dc14ed96b4db4eace650cfaeb 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -10,17 +10,17 @@ Version 2.17
 * The following bugs are resolved with this release:
 
   1349, 3439, 3479, 3665, 5044, 5246, 5298, 5400, 6530, 6778, 6808, 9685,
-  9914, 10014, 10038, 10631, 10873, 11438, 11607, 11638, 12140, 13412,
-  13542, 13601, 13603, 13604, 13629, 13679, 13696, 13698, 13717, 13741,
-  13939, 13950, 13952, 13966, 14042, 14047, 14090, 14150, 14151, 14152,
-  14154, 14157, 14166, 14173, 14195, 14237, 14251, 14252, 14283, 14298,
-  14303, 14307, 14328, 14331, 14336, 14337, 14347, 14349, 14376, 14417,
-  14459, 14476, 14477, 14501, 14505, 14510, 14516, 14518, 14519, 14530,
-  14532, 14538, 14543, 14544, 14545, 14557, 14562, 14568, 14576, 14579,
-  14583, 14587, 14595, 14602, 14610, 14621, 14638, 14645, 14648, 14652,
-  14660, 14661, 14669, 14683, 14694, 14716, 14743, 14767, 14783, 14784,
-  14785, 14793, 14796, 14797, 14801, 14805, 14807, 14809, 14811, 14815,
-  14821, 14824, 14828, 14831, 14838.
+  9914, 10014, 10038, 10631, 10873, 11438, 11607, 11638, 11741, 12140,
+  13412, 13542, 13601, 13603, 13604, 13629, 13679, 13696, 13698, 13717,
+  13741, 13939, 13950, 13952, 13966, 14042, 14047, 14090, 14150, 14151,
+  14152, 14154, 14157, 14166, 14173, 14195, 14237, 14251, 14252, 14283,
+  14298, 14303, 14307, 14328, 14331, 14336, 14337, 14347, 14349, 14376,
+  14417, 14459, 14476, 14477, 14501, 14505, 14510, 14516, 14518, 14519,
+  14530, 14532, 14538, 14543, 14544, 14545, 14557, 14562, 14568, 14576,
+  14579, 14583, 14587, 14595, 14602, 14610, 14621, 14638, 14645, 14648,
+  14652, 14660, 14661, 14669, 14683, 14694, 14716, 14743, 14767, 14783,
+  14784, 14785, 14793, 14796, 14797, 14801, 14805, 14807, 14809, 14811,
+  14815, 14821, 14824, 14828, 14831, 14838.
 
 * Port to ARM AArch64 contributed by Linaro.
 
index 6aabadc644012d88b9009dfc346a305b8025ea40..fb6ac17b64e17f4cef5c34d870d8785d0a5de78a 100644 (file)
@@ -1253,12 +1253,13 @@ _IO_new_file_write (f, data, n)
      _IO_ssize_t n;
 {
   _IO_ssize_t to_do = n;
+  _IO_ssize_t count = 0;
   while (to_do > 0)
     {
-      _IO_ssize_t count = (__builtin_expect (f->_flags2
-                                            & _IO_FLAGS2_NOTCANCEL, 0)
-                          ? write_not_cancel (f->_fileno, data, to_do)
-                          : write (f->_fileno, data, to_do));
+      count = (__builtin_expect (f->_flags2
+                                & _IO_FLAGS2_NOTCANCEL, 0)
+              ? write_not_cancel (f->_fileno, data, to_do)
+              : write (f->_fileno, data, to_do));
       if (count < 0)
        {
          f->_flags |= _IO_ERR_SEEN;
@@ -1270,7 +1271,7 @@ _IO_new_file_write (f, data, n)
   n -= to_do;
   if (f->_offset >= 0)
     f->_offset += n;
-  return n;
+  return count < 0 ? count : n;
 }
 
 _IO_size_t
@@ -1330,9 +1331,10 @@ _IO_new_file_xsputn (f, data, n)
       _IO_size_t block_size, do_write;
       /* Next flush the (full) buffer. */
       if (_IO_OVERFLOW (f, EOF) == EOF)
-       /* If nothing else has to be written we must not signal the
-          caller that everything has been written.  */
-       return to_do == 0 ? EOF : n - to_do;
+       /* If nothing else has to be written or nothing has been written, we
+          must not signal the caller that the call was even partially
+          successful.  */
+       return (to_do == 0 || to_do == n) ? EOF : n - to_do;
 
       /* Try to maintain alignment: write a whole number of blocks.
         dont_write is what gets left over. */
index 7e374508f0f511b8f7df795f6edc88f568821e3d..b7a4c5a739ce0602aec03d8b6af40c2d3e9420ba 100644 (file)
@@ -59,7 +59,7 @@ _IO_padn (fp, pad, count)
       w = _IO_sputn (fp, padptr, PADSIZE);
       written += w;
       if (w != PADSIZE)
-       return written;
+       return w == EOF ? w : written;
     }
 
   if (i > 0)
index 05632d5bf0f3fe24e09ae823d531b7a110e9c524..56e4b8ccb2e2fe195e82a5f70291a7d8e660018c 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1997, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1993-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
@@ -65,7 +65,7 @@ _IO_wpadn (fp, pad, count)
       w = _IO_sputn (fp, (char *) padptr, PADSIZE);
       written += w;
       if (w != PADSIZE)
-       return written;
+       return w == EOF ? w : written;
     }
 
   if (i > 0)
index fe81115094295a070feb6a97d60a58d6d0b56f27..a402958b9c5df08a3e93183fe57bf118974f1ffd 100644 (file)
@@ -1,5 +1,4 @@
-/* Copyright (C) 1993, 1997-2003,2004,2005,2006,2007,2012
-       Free Software Foundation, Inc.
+/* Copyright (C) 1993-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
@@ -167,7 +166,7 @@ typedef int (*_IO_pbackfail_t) (_IO_FILE *, int);
 #define _IO_WPBACKFAIL(FP, CH) WJUMP1 (__pbackfail, FP, CH)
 
 /* The 'xsputn' hook writes upto N characters from buffer DATA.
-   Returns the number of character actually written.
+   Returns EOF or the number of character actually written.
    It matches the streambuf::xsputn virtual function. */
 typedef _IO_size_t (*_IO_xsputn_t) (_IO_FILE *FP, const void *DATA,
                                    _IO_size_t N);
index 115dbd509ad701ab02def9686c8b3791e1781a1f..7b95491725a4beff44f659678c21ba3a63401c5e 100644 (file)
@@ -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;
 }
 
index 17d3f42a9752557f1db4c84e179c521cac47944e..0c1339febd967b751cecbdac86573224f52b6bbd 100644 (file)
 
 # 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
 
 # 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