diff options
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | libio/Makefile | 2 | ||||
-rw-r--r-- | libio/fileops.c | 8 | ||||
-rw-r--r-- | libio/ioputs.c | 12 | ||||
-rw-r--r-- | libio/putchar.c | 6 | ||||
-rw-r--r-- | libio/putchar_u.c | 4 | ||||
-rw-r--r-- | libio/putwchar.c | 6 | ||||
-rw-r--r-- | libio/putwchar_u.c | 4 | ||||
-rw-r--r-- | libio/tst-bz24051.c | 81 | ||||
-rw-r--r-- | libio/wfileops.c | 8 |
10 files changed, 119 insertions, 25 deletions
@@ -1,3 +1,16 @@ +2019-01-31 Paul Pluzhnikov <ppluzhnikov@google.com> + + [BZ #24051] + * libio/ioputs.c (_IO_puts): Use stdout instead of _IO_stdout. + * libio/fileops.c (_IO_new_file_underflow): Likewise + * libio/wfileops.c (_IO_wfile_underflow): Likewise + * libio/putchar.c (putchar): Likewise. + * libio/putchar_u.c (putchar_unlocked): Likewise. + * libio/putwchar.c (putchar): Likewise. + * libio/putwchar_u.c (putwchar_unlocked): Likewise. + * libio/tst-bz24051.c: New test. + * libio/Makefile (tests): Add tst-bz24051 + 2019-01-31 Paul Eggert <eggert@cs.ucla.edu> regex: fix read overrun [BZ #24114] diff --git a/libio/Makefile b/libio/Makefile index 5bee83e55c..dbeba88fc0 100644 --- a/libio/Makefile +++ b/libio/Makefile @@ -65,7 +65,7 @@ tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \ tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \ tst-fwrite-error tst-ftell-partial-wide tst-ftell-active-handler \ tst-ftell-append tst-fputws tst-bz22415 tst-fgetc-after-eof \ - tst-sprintf-ub tst-sprintf-chk-ub + tst-sprintf-ub tst-sprintf-chk-ub tst-bz24051 tests-internal = tst-vtables tst-vtables-interposed tst-readline diff --git a/libio/fileops.c b/libio/fileops.c index 43e33820e3..d2070a856e 100644 --- a/libio/fileops.c +++ b/libio/fileops.c @@ -501,13 +501,13 @@ _IO_new_file_underflow (FILE *fp) traditional Unix systems did this for stdout. stderr better not be line buffered. So we do just that here explicitly. --drepper */ - _IO_acquire_lock (_IO_stdout); + _IO_acquire_lock (stdout); - if ((_IO_stdout->_flags & (_IO_LINKED | _IO_NO_WRITES | _IO_LINE_BUF)) + if ((stdout->_flags & (_IO_LINKED | _IO_NO_WRITES | _IO_LINE_BUF)) == (_IO_LINKED | _IO_LINE_BUF)) - _IO_OVERFLOW (_IO_stdout, EOF); + _IO_OVERFLOW (stdout, EOF); - _IO_release_lock (_IO_stdout); + _IO_release_lock (stdout); } _IO_switch_to_get_mode (fp); diff --git a/libio/ioputs.c b/libio/ioputs.c index 04ae323c6d..319e551de5 100644 --- a/libio/ioputs.c +++ b/libio/ioputs.c @@ -33,15 +33,15 @@ _IO_puts (const char *str) { int result = EOF; size_t len = strlen (str); - _IO_acquire_lock (_IO_stdout); + _IO_acquire_lock (stdout); - if ((_IO_vtable_offset (_IO_stdout) != 0 - || _IO_fwide (_IO_stdout, -1) == -1) - && _IO_sputn (_IO_stdout, str, len) == len - && _IO_putc_unlocked ('\n', _IO_stdout) != EOF) + if ((_IO_vtable_offset (stdout) != 0 + || _IO_fwide (stdout, -1) == -1) + && _IO_sputn (stdout, str, len) == len + && _IO_putc_unlocked ('\n', stdout) != EOF) result = MIN (INT_MAX, len + 1); - _IO_release_lock (_IO_stdout); + _IO_release_lock (stdout); return result; } diff --git a/libio/putchar.c b/libio/putchar.c index 665f46685a..a3f4200cdb 100644 --- a/libio/putchar.c +++ b/libio/putchar.c @@ -24,9 +24,9 @@ int putchar (int c) { int result; - _IO_acquire_lock (_IO_stdout); - result = _IO_putc_unlocked (c, _IO_stdout); - _IO_release_lock (_IO_stdout); + _IO_acquire_lock (stdout); + result = _IO_putc_unlocked (c, stdout); + _IO_release_lock (stdout); return result; } diff --git a/libio/putchar_u.c b/libio/putchar_u.c index 37d03ad364..1eebf0fc8f 100644 --- a/libio/putchar_u.c +++ b/libio/putchar_u.c @@ -23,6 +23,6 @@ int putchar_unlocked (int c) { - CHECK_FILE (_IO_stdout, EOF); - return _IO_putc_unlocked (c, _IO_stdout); + CHECK_FILE (stdout, EOF); + return _IO_putc_unlocked (c, stdout); } diff --git a/libio/putwchar.c b/libio/putwchar.c index 8d6b6a4df0..1f5c4176f8 100644 --- a/libio/putwchar.c +++ b/libio/putwchar.c @@ -22,8 +22,8 @@ wint_t putwchar (wchar_t wc) { wint_t result; - _IO_acquire_lock (_IO_stdout); - result = _IO_putwc_unlocked (wc, _IO_stdout); - _IO_release_lock (_IO_stdout); + _IO_acquire_lock (stdout); + result = _IO_putwc_unlocked (wc, stdout); + _IO_release_lock (stdout); return result; } diff --git a/libio/putwchar_u.c b/libio/putwchar_u.c index cfb46fc253..d943220031 100644 --- a/libio/putwchar_u.c +++ b/libio/putwchar_u.c @@ -21,6 +21,6 @@ wint_t putwchar_unlocked (wchar_t wc) { - CHECK_FILE (_IO_stdout, WEOF); - return _IO_putwc_unlocked (wc, _IO_stdout); + CHECK_FILE (stdout, WEOF); + return _IO_putwc_unlocked (wc, stdout); } diff --git a/libio/tst-bz24051.c b/libio/tst-bz24051.c new file mode 100644 index 0000000000..cf0dc8024e --- /dev/null +++ b/libio/tst-bz24051.c @@ -0,0 +1,81 @@ +/* Test that assigning to stdout redirects puts, putchar, etc (BZ#24051) + Copyright (C) 2019 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/>. */ + + +/* Prevent putchar -> _IO_putc inline expansion. */ +#define __NO_INLINE__ +#pragma GCC optimize("O0") + +#include <stdio.h> +#include <string.h> +#include <wchar.h> + +#include <array_length.h> +#include <support/check.h> +#include <support/temp_file.h> +#include <support/test-driver.h> + +#undef putchar +#undef putwchar + +static int +do_test_narrow (void) +{ + char buf[100]; + int fd = create_temp_file ("tst-bz24051", NULL); + stdout = fdopen (fd, "w+"); + TEST_VERIFY_EXIT (stdout != NULL); + + printf ("ab%s", "cd"); + putchar ('e'); + putchar_unlocked ('f'); + puts ("ghi"); + + rewind (stdout); + TEST_VERIFY_EXIT (fgets (buf, sizeof (buf), stdout) != NULL); + TEST_VERIFY (strcmp (buf, "abcdefghi\n") == 0); + + return 0; +} + +static int +do_test_wide (void) +{ + wchar_t buf[100]; + int fd = create_temp_file ("tst-bz24051w", NULL); + stdout = fdopen (fd, "w+"); + TEST_VERIFY_EXIT (stdout != NULL); + + wprintf (L"ab%ls", L"cd"); + putwchar (L'e'); + putwchar_unlocked (L'f'); + + rewind (stdout); + TEST_VERIFY_EXIT (fgetws (buf, array_length (buf), stdout) != NULL); + TEST_VERIFY (wcscmp (buf, L"abcdef") == 0); + + return 0; +} + +static int +do_test (void) +{ + return do_test_narrow () + do_test_wide (); +} + +#include <support/test-driver.c> diff --git a/libio/wfileops.c b/libio/wfileops.c index 78f20486e5..0367643703 100644 --- a/libio/wfileops.c +++ b/libio/wfileops.c @@ -208,13 +208,13 @@ _IO_wfile_underflow (FILE *fp) traditional Unix systems did this for stdout. stderr better not be line buffered. So we do just that here explicitly. --drepper */ - _IO_acquire_lock (_IO_stdout); + _IO_acquire_lock (stdout); - if ((_IO_stdout->_flags & (_IO_LINKED | _IO_NO_WRITES | _IO_LINE_BUF)) + if ((stdout->_flags & (_IO_LINKED | _IO_NO_WRITES | _IO_LINE_BUF)) == (_IO_LINKED | _IO_LINE_BUF)) - _IO_OVERFLOW (_IO_stdout, EOF); + _IO_OVERFLOW (stdout, EOF); - _IO_release_lock (_IO_stdout); + _IO_release_lock (stdout); } _IO_switch_to_get_mode (fp); |