Hi all,

This bug was caused by an access to an invalid pointer offset to the format
string. This was only a problem on the second error using the same format
string.  I suspect it has to do with caching the format strings.  Regardless,
the patch fixes this by using the fortran style string lengths to calculate the
position in the string where the error occurs.

Test case attached.

Regression tested on x86-64.

OK for trunk?

2014-07-12  Jerry DeLisle  <jvdeli...@gcc.gnu.org>

        PR libgfortran/61632
        * io/format.c (format_error): Avoid invalid string pointer by
        using the fortran string length values to generate error string.
Index: format.c
===================================================================
--- format.c	(revision 212420)
+++ format.c	(working copy)
@@ -1117,7 +1117,7 @@ parse_format_list (st_parameter_dt *dtp, bool *see
 void
 format_error (st_parameter_dt *dtp, const fnode *f, const char *message)
 {
-  int width, i, j, offset;
+  int width, i, offset;
 #define BUFLEN 300
   char *p, buffer[BUFLEN];
   format_data *fmt = dtp->u.p.fmt;
@@ -1130,13 +1130,10 @@ format_error (st_parameter_dt *dtp, const fnode *f
   else
     snprintf (buffer, BUFLEN, "%s\n", message);
 
-  j = fmt->format_string - dtp->format;
+  offset = dtp->format_len - fmt->format_string_len;
 
-  offset = (j > 60) ? j - 40 : 0;
+  width = dtp->format_len;
 
-  j -= offset;
-  width = dtp->format_len - offset;
-
   if (width > 80)
     width = 80;
 
@@ -1144,14 +1141,14 @@ format_error (st_parameter_dt *dtp, const fnode *f
 
   p = strchr (buffer, '\0');
 
-  memcpy (p, dtp->format + offset, width);
+  memcpy (p, dtp->format, width);
 
   p += width;
   *p++ = '\n';
 
   /* Show where the problem is */
 
-  for (i = 1; i < j; i++)
+  for (i = 1; i < offset; i++)
     *p++ = ' ';
 
   *p++ = '^';
! { dg-do run }
! Bug 61632 - memory corruption writing formatted data in error
      program p
      CHARACTER(3), save :: ZTYP(3)
      DATA ZTYP /'XXX','YYY','ZZZ'/
      write(10,600,IOSTAT=iosta) 0.0,ZTYP
      write(10,600,IOSTAT=iosta) 0.0,ZTYP
      close(10, status='delete')
 600  FORMAT(1PE13.5,4X,A3)
      end program p

Reply via email to