Mercurial > octave
diff libinterp/corefcn/oct-stream.cc @ 33124:9c08824262af stable
Fix duplicate final value in scanf function (bug #65390, bug #63467).
* oct-stream.cc (octave_scan): Don't check whether input stream "is" has hit
EOF after skipping whitespace. Instead, call read_value() and let error
propagate up through "is" state to this function. Check state of stream
and either pass on a correctly-read value, or clear EOF bit and propagate
up failure status in stream status bits.
* io.tst: Add regression indicator to solved bug #63383. Add BIST tests
for bug #63467 and bug #65390
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Sat, 02 Mar 2024 13:54:06 -0800 |
parents | 2e484f9f1f18 |
children | fc467370dacb |
line wrap: on
line diff
--- a/libinterp/corefcn/oct-stream.cc Thu Feb 29 08:18:25 2024 -0500 +++ b/libinterp/corefcn/oct-stream.cc Sat Mar 02 13:54:06 2024 -0800 @@ -4400,8 +4400,6 @@ octave_scan<> (std::istream& is, const scanf_format_elt& fmt, double *valptr) { - double& ref = *valptr; - switch (fmt.type) { case 'e': @@ -4411,19 +4409,24 @@ case 'G': { is >> std::ws; // skip through whitespace and advance stream pointer - if (is.good ()) + + std::streampos pos = is.tellg (); + + double value = read_value<double> (is); + + std::ios::iostate status = is.rdstate (); + if (! (status & std::ios::failbit)) { - std::streampos pos = is.tellg (); - - ref = read_value<double> (is); - - std::ios::iostate status = is.rdstate (); - if (status & std::ios::failbit) - { - is.clear (); - is.seekg (pos); - is.setstate (status & ~std::ios_base::eofbit); - } + // Copy the converted value if the stream is in a good state + *valptr = value; + } + else + { + // True error. + // Reset stream to original position, clear eof bit, pass status on. + is.clear (); + is.seekg (pos); + is.setstate (status & ~std::ios_base::eofbit); } } break;