Commit 241cbc7a by Jerry DeLisle

re PR fortran/65089 (FAIL: gfortran.dg/io_real_boz(2|_[45]).f90 when tested with…

re PR fortran/65089 (FAIL: gfortran.dg/io_real_boz(2|_[45]).f90 when tested with -fsanitize=address)

2015-04-14 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.

From-SVN: r222111
parent 182d115c
2015-04-14 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.
2015-03-28 Jerry DeLisle <jvdelisle@gcc.gnu.org> 2015-03-28 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR libgfortran/65596 PR libgfortran/65596
......
...@@ -243,6 +243,18 @@ get_fnode (format_data *fmt, fnode **head, fnode **tail, format_token t) ...@@ -243,6 +243,18 @@ get_fnode (format_data *fmt, fnode **head, fnode **tail, format_token t)
} }
/* 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. */ /* free_format_data()-- Free all allocated format data. */
void void
...@@ -1145,7 +1157,8 @@ format_error (st_parameter_dt *dtp, const fnode *f, const char *message) ...@@ -1145,7 +1157,8 @@ format_error (st_parameter_dt *dtp, const fnode *f, const char *message)
p = strchr (buffer, '\0'); p = strchr (buffer, '\0');
memcpy (p, dtp->format, width); if (dtp->format)
memcpy (p, dtp->format, width);
p += width; p += width;
*p++ = '\n'; *p++ = '\n';
...@@ -1158,6 +1171,26 @@ format_error (st_parameter_dt *dtp, const fnode *f, const char *message) ...@@ -1158,6 +1171,26 @@ format_error (st_parameter_dt *dtp, const fnode *f, const char *message)
*p++ = '^'; *p++ = '^';
*p = '\0'; *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); generate_error (&dtp->common, LIBERROR_FORMAT, buffer);
} }
...@@ -1218,13 +1251,8 @@ parse_format (st_parameter_dt *dtp) ...@@ -1218,13 +1251,8 @@ parse_format (st_parameter_dt *dtp)
/* Not found so proceed as follows. */ /* Not found so proceed as follows. */
if (format_cache_ok) char *fmt_string = fc_strdup_notrim (dtp->format, dtp->format_len);
{ dtp->format = fmt_string;
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)); dtp->u.p.fmt = fmt = xmalloc (sizeof (format_data));
fmt->format_string = dtp->format; fmt->format_string = dtp->format;
...@@ -1256,19 +1284,13 @@ parse_format (st_parameter_dt *dtp) ...@@ -1256,19 +1284,13 @@ parse_format (st_parameter_dt *dtp)
else else
fmt->error = "Missing initial left parenthesis in format"; 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) if (format_cache_ok)
save_parsed_format (dtp); save_parsed_format (dtp);
else else
dtp->u.p.format_not_saved = 1; dtp->u.p.format_not_saved = 1;
if (fmt->error)
format_error (dtp, NULL, fmt->error);
} }
......
...@@ -132,6 +132,9 @@ internal_proto(format_error); ...@@ -132,6 +132,9 @@ internal_proto(format_error);
extern void free_format_data (struct format_data *); extern void free_format_data (struct format_data *);
internal_proto(free_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 *); extern void free_format_hash_table (gfc_unit *);
internal_proto(free_format_hash_table); internal_proto(free_format_hash_table);
......
...@@ -3711,9 +3711,15 @@ void ...@@ -3711,9 +3711,15 @@ void
st_read_done (st_parameter_dt *dtp) st_read_done (st_parameter_dt *dtp)
{ {
finalize_transfer (dtp); finalize_transfer (dtp);
if (is_internal_unit (dtp) || dtp->u.p.format_not_saved) 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); free_ionml (dtp);
if (dtp->u.p.current_unit != NULL) if (dtp->u.p.current_unit != NULL)
unlock_unit (dtp->u.p.current_unit); unlock_unit (dtp->u.p.current_unit);
...@@ -3764,8 +3770,13 @@ st_write_done (st_parameter_dt *dtp) ...@@ -3764,8 +3770,13 @@ st_write_done (st_parameter_dt *dtp)
} }
if (is_internal_unit (dtp) || dtp->u.p.format_not_saved) 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); free_ionml (dtp);
if (dtp->u.p.current_unit != NULL) if (dtp->u.p.current_unit != NULL)
unlock_unit (dtp->u.p.current_unit); unlock_unit (dtp->u.p.current_unit);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment