mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-29 11:41:21 +03:00
printf should return negative value on error
[BZ #11741] Fixed bug where printf and family may return a spurious success when printing padded formats.
This commit is contained in:
16
ChangeLog
16
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>
|
2012-11-16 Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||||
|
|
||||||
* libio/libioP.h: Add comment note that the references to C++
|
* libio/libioP.h: Add comment note that the references to C++
|
||||||
|
22
NEWS
22
NEWS
@ -10,17 +10,17 @@ Version 2.17
|
|||||||
* The following bugs are resolved with this release:
|
* The following bugs are resolved with this release:
|
||||||
|
|
||||||
1349, 3439, 3479, 3665, 5044, 5246, 5298, 5400, 6530, 6778, 6808, 9685,
|
1349, 3439, 3479, 3665, 5044, 5246, 5298, 5400, 6530, 6778, 6808, 9685,
|
||||||
9914, 10014, 10038, 10631, 10873, 11438, 11607, 11638, 12140, 13412,
|
9914, 10014, 10038, 10631, 10873, 11438, 11607, 11638, 11741, 12140,
|
||||||
13542, 13601, 13603, 13604, 13629, 13679, 13696, 13698, 13717, 13741,
|
13412, 13542, 13601, 13603, 13604, 13629, 13679, 13696, 13698, 13717,
|
||||||
13939, 13950, 13952, 13966, 14042, 14047, 14090, 14150, 14151, 14152,
|
13741, 13939, 13950, 13952, 13966, 14042, 14047, 14090, 14150, 14151,
|
||||||
14154, 14157, 14166, 14173, 14195, 14237, 14251, 14252, 14283, 14298,
|
14152, 14154, 14157, 14166, 14173, 14195, 14237, 14251, 14252, 14283,
|
||||||
14303, 14307, 14328, 14331, 14336, 14337, 14347, 14349, 14376, 14417,
|
14298, 14303, 14307, 14328, 14331, 14336, 14337, 14347, 14349, 14376,
|
||||||
14459, 14476, 14477, 14501, 14505, 14510, 14516, 14518, 14519, 14530,
|
14417, 14459, 14476, 14477, 14501, 14505, 14510, 14516, 14518, 14519,
|
||||||
14532, 14538, 14543, 14544, 14545, 14557, 14562, 14568, 14576, 14579,
|
14530, 14532, 14538, 14543, 14544, 14545, 14557, 14562, 14568, 14576,
|
||||||
14583, 14587, 14595, 14602, 14610, 14621, 14638, 14645, 14648, 14652,
|
14579, 14583, 14587, 14595, 14602, 14610, 14621, 14638, 14645, 14648,
|
||||||
14660, 14661, 14669, 14683, 14694, 14716, 14743, 14767, 14783, 14784,
|
14652, 14660, 14661, 14669, 14683, 14694, 14716, 14743, 14767, 14783,
|
||||||
14785, 14793, 14796, 14797, 14801, 14805, 14807, 14809, 14811, 14815,
|
14784, 14785, 14793, 14796, 14797, 14801, 14805, 14807, 14809, 14811,
|
||||||
14821, 14824, 14828, 14831, 14838.
|
14815, 14821, 14824, 14828, 14831, 14838.
|
||||||
|
|
||||||
* Port to ARM AArch64 contributed by Linaro.
|
* Port to ARM AArch64 contributed by Linaro.
|
||||||
|
|
||||||
|
@ -1253,12 +1253,13 @@ _IO_new_file_write (f, data, n)
|
|||||||
_IO_ssize_t n;
|
_IO_ssize_t n;
|
||||||
{
|
{
|
||||||
_IO_ssize_t to_do = n;
|
_IO_ssize_t to_do = n;
|
||||||
|
_IO_ssize_t count = 0;
|
||||||
while (to_do > 0)
|
while (to_do > 0)
|
||||||
{
|
{
|
||||||
_IO_ssize_t count = (__builtin_expect (f->_flags2
|
count = (__builtin_expect (f->_flags2
|
||||||
& _IO_FLAGS2_NOTCANCEL, 0)
|
& _IO_FLAGS2_NOTCANCEL, 0)
|
||||||
? write_not_cancel (f->_fileno, data, to_do)
|
? write_not_cancel (f->_fileno, data, to_do)
|
||||||
: write (f->_fileno, data, to_do));
|
: write (f->_fileno, data, to_do));
|
||||||
if (count < 0)
|
if (count < 0)
|
||||||
{
|
{
|
||||||
f->_flags |= _IO_ERR_SEEN;
|
f->_flags |= _IO_ERR_SEEN;
|
||||||
@ -1270,7 +1271,7 @@ _IO_new_file_write (f, data, n)
|
|||||||
n -= to_do;
|
n -= to_do;
|
||||||
if (f->_offset >= 0)
|
if (f->_offset >= 0)
|
||||||
f->_offset += n;
|
f->_offset += n;
|
||||||
return n;
|
return count < 0 ? count : n;
|
||||||
}
|
}
|
||||||
|
|
||||||
_IO_size_t
|
_IO_size_t
|
||||||
@ -1330,9 +1331,10 @@ _IO_new_file_xsputn (f, data, n)
|
|||||||
_IO_size_t block_size, do_write;
|
_IO_size_t block_size, do_write;
|
||||||
/* Next flush the (full) buffer. */
|
/* Next flush the (full) buffer. */
|
||||||
if (_IO_OVERFLOW (f, EOF) == EOF)
|
if (_IO_OVERFLOW (f, EOF) == EOF)
|
||||||
/* If nothing else has to be written we must not signal the
|
/* If nothing else has to be written or nothing has been written, we
|
||||||
caller that everything has been written. */
|
must not signal the caller that the call was even partially
|
||||||
return to_do == 0 ? EOF : n - to_do;
|
successful. */
|
||||||
|
return (to_do == 0 || to_do == n) ? EOF : n - to_do;
|
||||||
|
|
||||||
/* Try to maintain alignment: write a whole number of blocks.
|
/* Try to maintain alignment: write a whole number of blocks.
|
||||||
dont_write is what gets left over. */
|
dont_write is what gets left over. */
|
||||||
|
@ -59,7 +59,7 @@ _IO_padn (fp, pad, count)
|
|||||||
w = _IO_sputn (fp, padptr, PADSIZE);
|
w = _IO_sputn (fp, padptr, PADSIZE);
|
||||||
written += w;
|
written += w;
|
||||||
if (w != PADSIZE)
|
if (w != PADSIZE)
|
||||||
return written;
|
return w == EOF ? w : written;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
|
@ -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.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
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);
|
w = _IO_sputn (fp, (char *) padptr, PADSIZE);
|
||||||
written += w;
|
written += w;
|
||||||
if (w != PADSIZE)
|
if (w != PADSIZE)
|
||||||
return written;
|
return w == EOF ? w : written;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
/* Copyright (C) 1993, 1997-2003,2004,2005,2006,2007,2012
|
/* Copyright (C) 1993-2012 Free Software Foundation, Inc.
|
||||||
Free Software Foundation, Inc.
|
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
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)
|
#define _IO_WPBACKFAIL(FP, CH) WJUMP1 (__pbackfail, FP, CH)
|
||||||
|
|
||||||
/* The 'xsputn' hook writes upto N characters from buffer DATA.
|
/* 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. */
|
It matches the streambuf::xsputn virtual function. */
|
||||||
typedef _IO_size_t (*_IO_xsputn_t) (_IO_FILE *FP, const void *DATA,
|
typedef _IO_size_t (*_IO_xsputn_t) (_IO_FILE *FP, const void *DATA,
|
||||||
_IO_size_t N);
|
_IO_size_t N);
|
||||||
|
@ -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 <errno.h>
|
||||||
#include <error.h>
|
#include <error.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -26,6 +45,13 @@ do_test (void)
|
|||||||
printf ("fprintf = %d\n", n);
|
printf ("fprintf = %d\n", n);
|
||||||
if (n >= 0)
|
if (n >= 0)
|
||||||
error (EXIT_FAILURE, 0, "second fprintf succeeded");
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,8 +87,18 @@
|
|||||||
|
|
||||||
# define PUT(F, S, N) _IO_sputn ((F), (S), (N))
|
# define PUT(F, S, N) _IO_sputn ((F), (S), (N))
|
||||||
# define PAD(Padchar) \
|
# define PAD(Padchar) \
|
||||||
if (width > 0) \
|
do { \
|
||||||
done_add (_IO_padn (s, (Padchar), width))
|
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 PUTC(C, F) _IO_putc_unlocked (C, F)
|
||||||
# define ORIENT if (_IO_vtable_offset (s) == 0 && _IO_fwide (s, -1) != -1)\
|
# define ORIENT if (_IO_vtable_offset (s) == 0 && _IO_fwide (s, -1) != -1)\
|
||||||
return -1
|
return -1
|
||||||
@ -106,8 +116,18 @@
|
|||||||
|
|
||||||
# define PUT(F, S, N) _IO_sputn ((F), (S), (N))
|
# define PUT(F, S, N) _IO_sputn ((F), (S), (N))
|
||||||
# define PAD(Padchar) \
|
# define PAD(Padchar) \
|
||||||
if (width > 0) \
|
do { \
|
||||||
done_add (_IO_wpadn (s, (Padchar), width))
|
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 PUTC(C, F) _IO_putwc_unlocked (C, F)
|
||||||
# define ORIENT if (_IO_fwide (s, 1) != 1) return -1
|
# define ORIENT if (_IO_fwide (s, 1) != 1) return -1
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user