backport: re PR libfortran/81937 (stack-buffer-overflow on memcpy in libgfortran/io/unix.c on character(kind=4))

2017-12-16  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

        Backport from trunk
        PR libgfortran/81937
        * io/list_read.c (next_char_internal): Don't attempt to read
        from the internal unit stream if no bytes are left. Decrement
        bytes_left in the right place.

From-SVN: r255752
This commit is contained in:
Jerry DeLisle 2017-12-16 21:57:17 +00:00
parent 703106c36e
commit 4429163edf
2 changed files with 21 additions and 9 deletions

View File

@ -1,3 +1,11 @@
2017-12-16 Jerry DeLisle <jvdelisle@gcc.gnu.org>
Backport from trunk
PR libgfortran/81937
* io/list_read.c (next_char_internal): Don't attempt to read
from the internal unit stream if no bytes are left. Decrement
bytes_left in the right place.
2017-12-16 Jerry DeLisle <jvdelisle@gcc.gnu.org>
Backport from trunk

View File

@ -266,15 +266,19 @@ next_char_internal (st_parameter_dt *dtp)
}
/* Get the next character and handle end-of-record conditions. */
if (is_char4_unit(dtp)) /* Check for kind=4 internal unit. */
length = sread (dtp->u.p.current_unit->s, &c, 1);
if (likely (dtp->u.p.current_unit->bytes_left > 0))
{
if (unlikely (is_char4_unit(dtp))) /* Check for kind=4 internal unit. */
length = sread (dtp->u.p.current_unit->s, &c, 1);
else
{
char cc;
length = sread (dtp->u.p.current_unit->s, &cc, 1);
c = cc;
}
}
else
{
char cc;
length = sread (dtp->u.p.current_unit->s, &cc, 1);
c = cc;
}
length = 0;
if (unlikely (length < 0))
{
@ -290,7 +294,6 @@ next_char_internal (st_parameter_dt *dtp)
generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
return '\0';
}
dtp->u.p.current_unit->bytes_left--;
}
else
{
@ -302,6 +305,7 @@ next_char_internal (st_parameter_dt *dtp)
dtp->u.p.at_eof = 1;
}
}
dtp->u.p.current_unit->bytes_left--;
done:
dtp->u.p.at_eol = (c == '\n' || c == EOF);