summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2023-03-21 16:28:57 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2023-03-21 16:28:57 (GMT)
commit9152d5eec0903e1bb99607fa9a87e2453a25e13d (patch)
treebfc494a5a1dfa90c45ea4c92d1878dda8a0a5471 /generic
parentd63d524e1d45f80c027a4a10aa4f2a51fd8e3f04 (diff)
parent48dcbfcc5b65ce91d157d0faa2db21f6035879e9 (diff)
downloadtcl-9152d5eec0903e1bb99607fa9a87e2453a25e13d.zip
tcl-9152d5eec0903e1bb99607fa9a87e2453a25e13d.tar.gz
tcl-9152d5eec0903e1bb99607fa9a87e2453a25e13d.tar.bz2
Fix [1bedc53c8c]: synchronous [read] with -strictencoding does not produce an error on invalid input
Diffstat (limited to 'generic')
-rw-r--r--generic/tclIO.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c
index 9944787..7f74e2e 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -6078,6 +6078,23 @@ DoReadChars(
statePtr->inQueueTail = NULL;
}
}
+
+ /*
+ * If CHANNEL_ENCODING_ERROR and CHANNEL_STICKY_EOF are both set,
+ * then CHANNEL_ENCODING_ERROR was caused by data that occurred
+ * after the EOF character was encountered, so it doesn't count as
+ * a real error.
+ */
+
+ if (GotFlag(statePtr, CHANNEL_ENCODING_ERROR)
+ && !GotFlag(statePtr, CHANNEL_STICKY_EOF)
+ && !GotFlag(statePtr, CHANNEL_NONBLOCKING)) {
+ /* Channel is blocking. Return an error so that callers
+ * like [read] can return an error.
+ */
+ Tcl_SetErrno(EILSEQ);
+ goto finish;
+ }
}
if (copiedNow < 0) {
@@ -6106,6 +6123,7 @@ DoReadChars(
}
}
+finish:
/*
* Failure to fill a channel buffer may have left channel reporting a
* "blocked" state, but so long as we fulfilled the request here, the
@@ -6139,6 +6157,11 @@ DoReadChars(
assert(!(GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED)
== (CHANNEL_EOF|CHANNEL_BLOCKED)));
UpdateInterest(chanPtr);
+ if (GotFlag(statePtr, CHANNEL_ENCODING_ERROR)
+ && (!copied || !GotFlag(statePtr, CHANNEL_NONBLOCKING))) {
+ Tcl_SetErrno(EILSEQ);
+ copied = -1;
+ }
TclChannelRelease((Tcl_Channel)chanPtr);
return copied;
}
@@ -6769,11 +6792,14 @@ TranslateInputEOL(
* EOF character was seen in EOL translated range. Leave current file
* position pointing at the EOF character, but don't store the EOF
* character in the output string.
+ *
+ * If CHANNEL_ENCODING_ERROR is set, it can only be because of data
+ * encountered after the EOF character, so it is nonsense. Unset it.
*/
SetFlag(statePtr, CHANNEL_EOF | CHANNEL_STICKY_EOF);
statePtr->inputEncodingFlags |= TCL_ENCODING_END;
- ResetFlag(statePtr, CHANNEL_BLOCKED|INPUT_SAW_CR);
+ ResetFlag(statePtr, CHANNEL_BLOCKED|INPUT_SAW_CR|CHANNEL_ENCODING_ERROR);
}
}