summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoroehhar <harald.oehlmann@elmicron.de>2023-11-12 18:55:01 (GMT)
committeroehhar <harald.oehlmann@elmicron.de>2023-11-12 18:55:01 (GMT)
commitb62a3d44eaf5682d190fb17bc414e45ed3b11901 (patch)
tree56f2aff334dda426611d441638fd300e2891b518
parent6e5c5c71b7d5c65534f127236932dfbaf58493d4 (diff)
downloadtcl-b62a3d44eaf5682d190fb17bc414e45ed3b11901.zip
tcl-b62a3d44eaf5682d190fb17bc414e45ed3b11901.tar.gz
tcl-b62a3d44eaf5682d190fb17bc414e45ed3b11901.tar.bz2
Bug [c4eb46a1]: endless loop on gets, non blocking, profile strict, encoding error: remove non-blocking exit condition and add test case
-rw-r--r--generic/tclIO.c13
-rw-r--r--tests/io.test25
2 files changed, 33 insertions, 5 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c
index 6461909..c92fb64 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -4918,8 +4918,17 @@ Tcl_GetsObj(
}
goto gotEOL;
} else if (gs.bytesWrote == 0
- && GotFlag(statePtr, CHANNEL_ENCODING_ERROR)
- && !GotFlag(statePtr, CHANNEL_NONBLOCKING)) {
+ && GotFlag(statePtr, CHANNEL_ENCODING_ERROR)) {
+ /* Ticket c4eb46a1 Harald Oehlmann 2023-11-12 debugging session.
+ * In non blocking mode we loop indifenitly on a decoding error in
+ * this while-loop.
+ * Removed the following from the upper condition:
+ * "&& !GotFlag(statePtr, CHANNEL_NONBLOCKING)"
+ * In case of an encoding error with leading correct bytes, we pass here
+ * two times, as gs.bytesWrote is not 0 on the first pass. This feels
+ * once to much, as the data is anyway not used.
+ */
+
/* Set eol to the position that caused the encoding error, and then
* continue to gotEOL, which stores the data that was decoded
* without error to objPtr. This allows the caller to do something
diff --git a/tests/io.test b/tests/io.test
index 9f731ad..a6683c8 100644
--- a/tests/io.test
+++ b/tests/io.test
@@ -9193,7 +9193,7 @@ test io-75.5 {invalid utf-8 encoding read is ignored (-profile tcl8)} -setup {
removeFile io-75.5
} -result 4181
-test io-75.6 {invalid utf-8 encoding, gets is not ignored (-profile strict)} -setup {
+test io-75.6 {invalid utf-8 encoding, blocking gets is not ignored (-profile strict)} -setup {
set fn [makeFile {} io-75.6]
set f [open $fn w+]
fconfigure $f -encoding binary
@@ -9211,6 +9211,25 @@ test io-75.6 {invalid utf-8 encoding, gets is not ignored (-profile strict)} -se
} -match glob -returnCodes 1 -result {error reading "file*":\
invalid or incomplete multibyte or wide character}
+# TCL ticket c4eb46a196: non blocking case had endless loop, so test it
+test io-75.6.2 {invalid utf-8 encoding, non blocking gets is not ignored (-profile strict)} -setup {
+ set fn [makeFile {} io-75.6.2]
+ set f [open $fn w+]
+ fconfigure $f -encoding binary
+ # \x81 is an incomplete byte sequence in utf-8
+ puts -nonewline $f A\x81
+ flush $f
+ seek $f 0
+ fconfigure $f -encoding utf-8 -buffering none -eofchar {} \
+ -translation lf -profile strict -blocking 0
+} -body {
+ gets $f
+} -cleanup {
+ close $f
+ removeFile io-75.6.2
+} -match glob -returnCodes 1 -result {error reading "file*":\
+ invalid or incomplete multibyte or wide character}
+
test io-75.7 {
invalid utf-8 encoding read is not ignored (-profile strict)
} -setup {
@@ -9232,7 +9251,7 @@ test io-75.7 {
} -match glob -result {1 {error reading "file*":\
invalid or incomplete multibyte or wide character}}
-test io-75.8 {invalid utf-8 encoding eof handling (-profile strict)} -setup {
+test io-75.8 {invalid utf-8 encoding eof first handling (-profile strict)} -setup {
set fn [makeFile {} io-75.8]
set f [open $fn w+]
fconfigure $f -encoding binary
@@ -9254,7 +9273,7 @@ test io-75.8 {invalid utf-8 encoding eof handling (-profile strict)} -setup {
removeFile io-75.8
} -result {41 1 {}}
-test io-75.8.eoflater {invalid utf-8 encoding eof handling (-profile strict)} -setup {
+test io-75.8.eoflater {invalid utf-8 encoding eof after handling (-profile strict)} -setup {
set fn [makeFile {} io-75.8]
set f [open $fn w+]
# This also configures the channel encoding profile as strict.