]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR libfortran/81937 (stack-buffer-overflow on memcpy in libgfortran...
authorJerry DeLisle <jvdelisle@gcc.gnu.org>
Sat, 16 Dec 2017 22:41:13 +0000 (22:41 +0000)
committerJerry DeLisle <jvdelisle@gcc.gnu.org>
Sat, 16 Dec 2017 22:41:13 +0000 (22:41 +0000)
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: r255754

libgfortran/ChangeLog
libgfortran/io/list_read.c

index dd0eb9c720ee15e11cc9dae99abad8d6b3d7bea9..2e73dd1002d964112ae4a6fb9ddfe82aecd6ad59 100644 (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-10-22  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
        Backport from trunk
index 244430d9765bee1919eb26f585a02cba2a4c9ccc..986a0714cb9cd32d0bbd1a48a42306c8d45bd39e 100644 (file)
@@ -266,15 +266,19 @@ next_char_internal (st_parameter_dt *dtp)
     }
 
   /* Get the next character and handle end-of-record conditions.  */
-
-  if (dtp->common.unit) /* 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 (dtp->common.unit) /* 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);