From df0ddd7b9b44266ea375ae17eec07ebb21c1157c Mon Sep 17 00:00:00 2001 From: pooryorick Date: Tue, 18 Apr 2023 22:00:10 +0000 Subject: Fix for [25cdcb7e8fb381fb]: Incomplete utf-8 sequence followed by eofchar results in failed assertion. --- generic/tclIO.c | 7 ++++++- tests/io.test | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 36ae16e..bf28508 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -6310,7 +6310,12 @@ ReadChars( flags, &statePtr->inputEncodingState, dst, dstLimit, &srcRead, &dstDecoded, &numChars); - if (code == TCL_CONVERT_UNKNOWN || code == TCL_CONVERT_SYNTAX) { + if (code == TCL_CONVERT_UNKNOWN || code == TCL_CONVERT_SYNTAX + || ( + code == TCL_CONVERT_MULTIBYTE + && GotFlag(statePtr, CHANNEL_EOF + )) + ) { SetFlag(statePtr, CHANNEL_ENCODING_ERROR); code = TCL_OK; } diff --git a/tests/io.test b/tests/io.test index 3ab09e8..dfa015f 100644 --- a/tests/io.test +++ b/tests/io.test @@ -9326,25 +9326,51 @@ test io-75.8.eoflater {invalid utf-8 encoding eof handling (-profile strict)} -s set res {} set fn [makeFile {} io-75.8] set f [open $fn w+] + # This also configures the channel encoding profile as strict. fconfigure $f -encoding binary # \x81 is invalid in utf-8. -eofchar is not detected, because it comes later. - puts -nonewline $f A\x81\x1A + puts -nonewline $f A\x81\x81\x1A flush $f seek $f 0 fconfigure $f -encoding utf-8 -buffering none -eofchar \x1A \ -translation lf -profile strict } -body { - after 1 set status [catch {read $f} cres copts] lappend res $status lappend res [eof $f] chan configure $f -encoding iso8859-1 - lappend res [read $f] + lappend res [read $f 1] + chan configure $f -encoding utf-8 + catch {read $f 1} cres + lappend res $cres close $f set res } -cleanup { removeFile io-75.8 -} -result "1 0 \x81" +} -match glob -result "1 0 \x81 {error reading \"*\":\ + invalid or incomplete multibyte or wide character}" + + +test io-strict-multibyte-eof { + incomplete utf-8 sequence immediately prior to eof character + + See issue 25cdcb7e8fb381fb +} -setup { + set res {} + set chan [file tempfile]; + fconfigure $chan -encoding binary + puts -nonewline $chan \x81\x1A + flush $chan + seek $chan 0 + chan configure $chan -encoding utf-8 -profile strict +} -body { + set status [catch {read $chan 1} cres] + lappend res $status $cres +} -cleanup { + close $chan + unset res +} -match glob -result {1 {error reading "*":\ + invalid or incomplete multibyte or wide character}} test io-75.9 {unrepresentable character write passes and is replaced by ?} -setup { set fn [makeFile {} io-75.9] -- cgit v0.12