summaryrefslogtreecommitdiff
path: root/libgfortran/io/format.c
diff options
context:
space:
mode:
authorJerry DeLisle <jvdelisle@gcc.gnu.org>2014-07-20 20:03:41 +0000
committerJerry DeLisle <jvdelisle@gcc.gnu.org>2014-07-20 20:03:41 +0000
commitdbb400d7076fb71c447a342f561aecbf57dd87ad (patch)
tree2247aa9ad49d39cb0c7106492783f37bd4981e2b /libgfortran/io/format.c
parentfbd86cc6a12a6ee77a808c0d08b4c55869aa19e1 (diff)
downloadgcc-dbb400d7076fb71c447a342f561aecbf57dd87ad.tar.gz
re PR fortran/61632 (Improve error locus on large format strings)
2014-07-20 Jerry DeLisle <jvdelisle@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. (parse_format): Allocate the null terminator for the format string. From-SVN: r212875
Diffstat (limited to 'libgfortran/io/format.c')
-rw-r--r--libgfortran/io/format.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/libgfortran/io/format.c b/libgfortran/io/format.c
index 83f291ec2de..6e326065531 100644
--- a/libgfortran/io/format.c
+++ b/libgfortran/io/format.c
@@ -1117,25 +1117,26 @@ parse_format_list (st_parameter_dt *dtp, bool *seen_dd)
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;
if (f != NULL)
- fmt->format_string = f->source;
+ p = f->source;
+ else /* This should not happen. */
+ p = dtp->format;
if (message == unexpected_element)
snprintf (buffer, BUFLEN, message, fmt->error_element);
else
snprintf (buffer, BUFLEN, "%s\n", message);
- j = fmt->format_string - dtp->format;
+ /* Get the offset into the format string where the error occurred. */
+ offset = dtp->format_len - (fmt->reversion_ok ?
+ (int) strlen(p) : fmt->format_string_len);
- offset = (j > 60) ? j - 40 : 0;
-
- j -= offset;
- width = dtp->format_len - offset;
+ width = dtp->format_len;
if (width > 80)
width = 80;
@@ -1144,14 +1145,14 @@ format_error (st_parameter_dt *dtp, const fnode *f, const char *message)
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++ = '^';
@@ -1219,9 +1220,10 @@ parse_format (st_parameter_dt *dtp)
if (format_cache_ok)
{
- char *fmt_string = xmalloc (dtp->format_len);
+ char *fmt_string = xmalloc (dtp->format_len + 1);
memcpy (fmt_string, dtp->format, dtp->format_len);
dtp->format = fmt_string;
+ dtp->format[dtp->format_len] = '\0';
}
dtp->u.p.fmt = fmt = xmalloc (sizeof (format_data));