* [patch, libgfortran] PR65089 FAIL: gfortran.dg/io_real_boz(2|_[45]).f90 when tested with -fsanitize=address
@ 2015-04-12 21:54 Jerry DeLisle
2015-04-13 18:32 ` Janne Blomqvist
0 siblings, 1 reply; 2+ messages in thread
From: Jerry DeLisle @ 2015-04-12 21:54 UTC (permalink / raw)
To: gfortran; +Cc: gcc patches
[-- Attachment #1: Type: text/plain, Size: 924 bytes --]
Hi all,
The attached patch fixes this bug. It also eliminates non-freed memory whenever
a format error occurs. Particular important when the user has use IOSTAT and
generate_error does not exit, but returns to continue program execution.
Regression tested on x86-64 and tested with -fsanitize=address and valgrind on a
number of existing test cases. Changelog is fairly clear I think.
OK for trunk?
Regards,
Jerry
2015-04-12 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR libgfortran/65089
* io/format.h (free_format): New function to free memory
allocated for building format error messages.
* io/format.c (format_error): Add checks before freeing memory
to avoid potential segfaults and free formatting data when
needed on error conditions. Always allocate and NULL terminate
the string.
* io/transfer.c (st_read_done, st_write_done): Use new
free_format function to clean up memory allocations when done.
[-- Attachment #2: pr65089.diff --]
[-- Type: text/x-patch, Size: 3932 bytes --]
Index: io/format.c
===================================================================
--- io/format.c (revision 222011)
+++ io/format.c (working copy)
@@ -243,6 +243,18 @@ get_fnode (format_data *fmt, fnode **head, fnode *
}
+/* free_format()-- Free allocated format string. */
+void
+free_format (st_parameter_dt *dtp)
+{
+ if ((dtp->common.flags & IOPARM_DT_HAS_FORMAT && dtp->format))
+ {
+ free (dtp->format);
+ dtp->format = NULL;
+ }
+}
+
+
/* free_format_data()-- Free all allocated format data. */
void
@@ -1145,7 +1157,8 @@ format_error (st_parameter_dt *dtp, const fnode *f
p = strchr (buffer, '\0');
- memcpy (p, dtp->format, width);
+ if (dtp->format)
+ memcpy (p, dtp->format, width);
p += width;
*p++ = '\n';
@@ -1158,6 +1171,26 @@ format_error (st_parameter_dt *dtp, const fnode *f
*p++ = '^';
*p = '\0';
+ /* Cleanup any left over memory allocations before calling generate
+ error. */
+ if (is_internal_unit (dtp))
+ {
+ if (dtp->format != NULL)
+ {
+ free (dtp->format);
+ dtp->format = NULL;
+ }
+
+ /* Leave these alone if IOSTAT was given because execution will
+ return from generate error in those cases. */
+ if (!(dtp->common.flags & IOPARM_HAS_IOSTAT))
+ {
+ free (dtp->u.p.fmt);
+ free_format_hash_table (dtp->u.p.current_unit);
+ free_internal_unit (dtp);
+ }
+ }
+
generate_error (&dtp->common, LIBERROR_FORMAT, buffer);
}
@@ -1218,13 +1251,10 @@ parse_format (st_parameter_dt *dtp)
/* Not found so proceed as follows. */
- if (format_cache_ok)
- {
- 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';
- }
+ 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));
fmt->format_string = dtp->format;
@@ -1256,19 +1286,13 @@ parse_format (st_parameter_dt *dtp)
else
fmt->error = "Missing initial left parenthesis in format";
- if (fmt->error)
- {
- format_error (dtp, NULL, fmt->error);
- if (format_cache_ok)
- free (dtp->format);
- free_format_hash_table (dtp->u.p.current_unit);
- return;
- }
-
if (format_cache_ok)
save_parsed_format (dtp);
else
dtp->u.p.format_not_saved = 1;
+
+ if (fmt->error)
+ format_error (dtp, NULL, fmt->error);
}
Index: io/format.h
===================================================================
--- io/format.h (revision 222011)
+++ io/format.h (working copy)
@@ -132,6 +132,9 @@ internal_proto(format_error);
extern void free_format_data (struct format_data *);
internal_proto(free_format_data);
+extern void free_format (st_parameter_dt *);
+internal_proto(free_format);
+
extern void free_format_hash_table (gfc_unit *);
internal_proto(free_format_hash_table);
Index: io/transfer.c
===================================================================
--- io/transfer.c (revision 222011)
+++ io/transfer.c (working copy)
@@ -3711,9 +3711,15 @@ void
st_read_done (st_parameter_dt *dtp)
{
finalize_transfer (dtp);
+
if (is_internal_unit (dtp) || dtp->u.p.format_not_saved)
- free_format_data (dtp->u.p.fmt);
+ {
+ free_format_data (dtp->u.p.fmt);
+ free_format (dtp);
+ }
+
free_ionml (dtp);
+
if (dtp->u.p.current_unit != NULL)
unlock_unit (dtp->u.p.current_unit);
@@ -3764,8 +3770,13 @@ st_write_done (st_parameter_dt *dtp)
}
if (is_internal_unit (dtp) || dtp->u.p.format_not_saved)
- free_format_data (dtp->u.p.fmt);
+ {
+ free_format_data (dtp->u.p.fmt);
+ free_format (dtp);
+ }
+
free_ionml (dtp);
+
if (dtp->u.p.current_unit != NULL)
unlock_unit (dtp->u.p.current_unit);
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [patch, libgfortran] PR65089 FAIL: gfortran.dg/io_real_boz(2|_[45]).f90 when tested with -fsanitize=address
2015-04-12 21:54 [patch, libgfortran] PR65089 FAIL: gfortran.dg/io_real_boz(2|_[45]).f90 when tested with -fsanitize=address Jerry DeLisle
@ 2015-04-13 18:32 ` Janne Blomqvist
0 siblings, 0 replies; 2+ messages in thread
From: Janne Blomqvist @ 2015-04-13 18:32 UTC (permalink / raw)
To: Jerry DeLisle; +Cc: gfortran, gcc patches
On Mon, Apr 13, 2015 at 12:54 AM, Jerry DeLisle <jvdelisle@charter.net> wrote:
> Hi all,
>
> The attached patch fixes this bug. It also eliminates non-freed memory
> whenever
> a format error occurs. Particular important when the user has use IOSTAT
> and generate_error does not exit, but returns to continue program execution.
>
> Regression tested on x86-64 and tested with -fsanitize=address and valgrind
> on a number of existing test cases. Changelog is fairly clear I think.
>
> OK for trunk?
Instead of xmalloc + memcpy + null-terminating, please use fc_strdup
(or fc_strdup_notrim if you want to retain trailing spaces) in order
to create a heap-allocated null-terminated copy of a
non-null-terminated string.
WIth that change, Ok for trunk and affected branches.
Since it doesn't seem to be über-critical, I suggest you wait with
backporting to the 5.x branch until after the imminent release of 5.1
(if I understand the new numbering scheme correctly).
Thanks.
--
Janne Blomqvist
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2015-04-13 18:32 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-12 21:54 [patch, libgfortran] PR65089 FAIL: gfortran.dg/io_real_boz(2|_[45]).f90 when tested with -fsanitize=address Jerry DeLisle
2015-04-13 18:32 ` Janne Blomqvist
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).