diff options
author | jvdelisle <jvdelisle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-07-20 20:03:41 +0000 |
---|---|---|
committer | jvdelisle <jvdelisle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-07-20 20:03:41 +0000 |
commit | 571b6ba9c767a233ac70a0ea8e404ac5eb9e4fe9 (patch) | |
tree | 2247aa9ad49d39cb0c7106492783f37bd4981e2b /libgfortran | |
parent | 85307591af184460c7699ad039e0754197dc1e89 (diff) | |
download | gcc-571b6ba9c767a233ac70a0ea8e404ac5eb9e4fe9.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@212875 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgfortran')
-rw-r--r-- | libgfortran/ChangeLog | 8 | ||||
-rw-r--r-- | libgfortran/io/format.c | 22 |
2 files changed, 20 insertions, 10 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 8a71b8046fc..80f87523a69 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,11 @@ +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. + 2014-07-12 Tobias Burnus <burnus@net-b.de> * caf/libcaf.h (_gfortran_caf_atomic_define, 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)); |