aboutsummaryrefslogtreecommitdiff
path: root/libgfortran
diff options
context:
space:
mode:
authorJerry DeLisle <jvdelisle@gcc.gnu.org>2007-07-22 04:02:57 +0000
committerJerry DeLisle <jvdelisle@gcc.gnu.org>2007-07-22 04:02:57 +0000
commit66e035199b8cb70799e985b98f70400054eaf878 (patch)
tree794d19eea0c38e2be5fc06b5a6793674a7675075 /libgfortran
parent461c794009e87b495ed30014f0328e65cd0736e5 (diff)
re PR libfortran/32752 (Segfault on WRITE with modified unix_stream structure)
2007-07-21 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR libgfortran/32752 PR libgfortran/32678 Backport from trunk. * io/transfer.c (formatted_transfer_scalar): If stream I/O, set bytes_used to zero. Fix off by one error in calculation of pos and skips. Don't allow pending_spaces to go negative. From-SVN: r126822
Diffstat (limited to 'libgfortran')
-rw-r--r--libgfortran/ChangeLog9
-rw-r--r--libgfortran/io/transfer.c15
2 files changed, 18 insertions, 6 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 1859509170d..19ec2d6238b 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,12 @@
+2007-07-21 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR libgfortran/32752
+ PR libgfortran/32678
+ Backport from trunk.
+ * io/transfer.c (formatted_transfer_scalar): If stream I/O, set
+ bytes_used to zero. Fix off by one error in calculation of pos and
+ skips. Don't allow pending_spaces to go negative.
+
2007-07-19 Release Manager
* GCC 4.2.1 released.
diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c
index d1cd01c7745..05762973108 100644
--- a/libgfortran/io/transfer.c
+++ b/libgfortran/io/transfer.c
@@ -957,7 +957,10 @@ formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int len,
}
bytes_used = (int)(dtp->u.p.current_unit->recl
- - dtp->u.p.current_unit->bytes_left);
+ - dtp->u.p.current_unit->bytes_left);
+
+ if (is_stream_io(dtp))
+ bytes_used = 0;
switch (t)
{
@@ -1154,9 +1157,9 @@ formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int len,
case FMT_TR:
consume_data_flag = 0;
- pos = bytes_used + f->u.n + dtp->u.p.skips;
- dtp->u.p.skips = f->u.n + dtp->u.p.skips;
- dtp->u.p.pending_spaces = pos - dtp->u.p.max_pos;
+ dtp->u.p.skips += f->u.n;
+ pos = bytes_used + dtp->u.p.skips - 1;
+ dtp->u.p.pending_spaces = pos - dtp->u.p.max_pos + 1;
/* Writes occur just before the switch on f->format, above, so
that trailing blanks are suppressed, unless we are doing a
@@ -1186,8 +1189,6 @@ formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int len,
if (bytes_used == 0)
{
dtp->u.p.pending_spaces -= f->u.n;
- dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0 ? 0
- : dtp->u.p.pending_spaces;
dtp->u.p.skips -= f->u.n;
dtp->u.p.skips = dtp->u.p.skips < 0 ? 0 : dtp->u.p.skips;
}
@@ -1211,6 +1212,8 @@ formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int len,
dtp->u.p.skips = dtp->u.p.skips + pos - bytes_used;
dtp->u.p.pending_spaces = dtp->u.p.pending_spaces
+ pos - dtp->u.p.max_pos;
+ dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0
+ ? 0 : dtp->u.p.pending_spaces;
if (dtp->u.p.skips == 0)
break;