diff options
author | Jerry DeLisle <jvdelisle@gcc.gnu.org> | 2007-07-22 04:02:57 +0000 |
---|---|---|
committer | Jerry DeLisle <jvdelisle@gcc.gnu.org> | 2007-07-22 04:02:57 +0000 |
commit | 66e035199b8cb70799e985b98f70400054eaf878 (patch) | |
tree | 794d19eea0c38e2be5fc06b5a6793674a7675075 /libgfortran | |
parent | 461c794009e87b495ed30014f0328e65cd0736e5 (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/ChangeLog | 9 | ||||
-rw-r--r-- | libgfortran/io/transfer.c | 15 |
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; |