PR 60324 Unbounded stack allocations in libgfortran.
[platform/upstream/gcc.git] / libgfortran / io / read.c
index 64f2ddf..5c56dc2 100644 (file)
@@ -881,6 +881,9 @@ read_radix (st_parameter_dt *dtp, const fnode *f, char *dest, int length,
 void
 read_f (st_parameter_dt *dtp, const fnode *f, char *dest, int length)
 {
+#define READF_TMP 50
+  char tmp[READF_TMP];
+  size_t buf_size = 0;
   int w, seen_dp, exponent;
   int exponent_sign;
   const char *p;
@@ -895,6 +898,7 @@ read_f (st_parameter_dt *dtp, const fnode *f, char *dest, int length)
   exponent_sign = 1;
   exponent = 0;
   w = f->u.w;
+  buffer = tmp;
 
   /* Read in the next block.  */
   p = read_block_form (dtp, &w);
@@ -911,7 +915,10 @@ read_f (st_parameter_dt *dtp, const fnode *f, char *dest, int length)
      exponent because of an implicit decimal point or the like.  Thus allocating
      strlen ("+0.0e-1000") == 10 characters plus one for NUL more than the
      original buffer had should be enough.  */
-  buffer = gfc_alloca (w + 11);
+  buf_size = w + 11;
+  if (buf_size > READF_TMP)
+    buffer = xmalloc (buf_size);
+
   out = buffer;
 
   /* Optional sign */
@@ -984,6 +991,8 @@ read_f (st_parameter_dt *dtp, const fnode *f, char *dest, int length)
        goto bad_float;
 
       convert_infnan (dtp, dest, buffer, length);
+      if (buf_size > READF_TMP)
+       free (buffer);
       return;
     }
 
@@ -1170,7 +1179,8 @@ done:
 
   /* Do the actual conversion.  */
   convert_real (dtp, dest, buffer, length);
-
+  if (buf_size > READF_TMP)
+    free (buffer);
   return;
 
   /* The value read is zero.  */
@@ -1203,6 +1213,8 @@ zero:
   return;
 
 bad_float:
+  if (buf_size > READF_TMP)
+    free (buffer);
   generate_error (&dtp->common, LIBERROR_READ_VALUE,
                  "Bad value during floating point read");
   next_record (dtp, 1);