mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-21 12:30:06 +00:00
ungetc: Fix uninitialized read when putting into unused streams [BZ #27821]
When ungetc is called on an unused stream, the backup buffer is allocated without the main get area being present. This results in every subsequent ungetc (as the stream remains in the backup area) checking uninitialized memory in the backup buffer when trying to put a character back into the stream. Avoid comparing the input character with buffer contents when in backup to avoid this uninitialized read. The uninitialized read is harmless in this context since the location is promptly overwritten with the input character, thus fulfilling ungetc functionality. Also adjust wording in the manual to drop the paragraph that says glibc cannot do multiple ungetc back to back since with this change, ungetc can actually do this. Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org> Reviewed-by: Carlos O'Donell <carlos@redhat.com>
This commit is contained in:
parent
3f7df7e757
commit
cdf0f88f97
@ -662,7 +662,7 @@ _IO_sputbackc (FILE *fp, int c)
|
|||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (fp->_IO_read_ptr > fp->_IO_read_base
|
if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp)
|
||||||
&& (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
|
&& (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
|
||||||
{
|
{
|
||||||
fp->_IO_read_ptr--;
|
fp->_IO_read_ptr--;
|
||||||
|
@ -1467,11 +1467,9 @@ program; usually @code{ungetc} is used only to unread a character that
|
|||||||
was just read from the same stream. @Theglibc{} supports this
|
was just read from the same stream. @Theglibc{} supports this
|
||||||
even on files opened in binary mode, but other systems might not.
|
even on files opened in binary mode, but other systems might not.
|
||||||
|
|
||||||
@Theglibc{} only supports one character of pushback---in other
|
@Theglibc{} supports pushing back multiple characters; subsequently
|
||||||
words, it does not work to call @code{ungetc} twice without doing input
|
reading from the stream retrieves the characters in the reverse order
|
||||||
in between. Other systems might let you push back multiple characters;
|
that they were pushed.
|
||||||
then reading from the stream retrieves the characters in the reverse
|
|
||||||
order that they were pushed.
|
|
||||||
|
|
||||||
Pushing back characters doesn't alter the file; only the internal
|
Pushing back characters doesn't alter the file; only the internal
|
||||||
buffering for the stream is affected. If a file positioning function
|
buffering for the stream is affected. If a file positioning function
|
||||||
|
@ -48,6 +48,8 @@ do_test (void)
|
|||||||
TEST_VERIFY_EXIT (getc (fp) == 'b');
|
TEST_VERIFY_EXIT (getc (fp) == 'b');
|
||||||
TEST_VERIFY_EXIT (getc (fp) == 'l');
|
TEST_VERIFY_EXIT (getc (fp) == 'l');
|
||||||
TEST_VERIFY_EXIT (ungetc ('m', fp) == 'm');
|
TEST_VERIFY_EXIT (ungetc ('m', fp) == 'm');
|
||||||
|
TEST_VERIFY_EXIT (ungetc ('n', fp) == 'n');
|
||||||
|
TEST_VERIFY_EXIT (getc (fp) == 'n');
|
||||||
TEST_VERIFY_EXIT (getc (fp) == 'm');
|
TEST_VERIFY_EXIT (getc (fp) == 'm');
|
||||||
TEST_VERIFY_EXIT ((c = getc (fp)) == 'a');
|
TEST_VERIFY_EXIT ((c = getc (fp)) == 'a');
|
||||||
TEST_VERIFY_EXIT (getc (fp) == EOF);
|
TEST_VERIFY_EXIT (getc (fp) == EOF);
|
||||||
|
Loading…
Reference in New Issue
Block a user