summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tclIO.c26
-rw-r--r--generic/tclIO.h2
-rw-r--r--tests/io.test20
3 files changed, 37 insertions, 11 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c
index 3f7fe86..9944787 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -4914,6 +4914,19 @@ Tcl_GetsObj(
goto done;
}
goto gotEOL;
+ } else if (gs.bytesWrote == 0
+ && GotFlag(statePtr, CHANNEL_ENCODING_ERROR)
+ && !GotFlag(statePtr, CHANNEL_NONBLOCKING)) {
+ /* Set eol to the position that caused the encoding error, and then
+ * coninue to gotEOL, which stores the data that was decoded
+ * without error to objPtr. This allows the caller to do something
+ * useful with the data decoded so far, and also results in the
+ * position of the file being the first byte that was not
+ * succesfully decoded, allowing further processing at exactly that
+ * point, if desired.
+ */
+ eol = dstEnd;
+ goto gotEOL;
}
dst = dstEnd;
}
@@ -5030,6 +5043,11 @@ Tcl_GetsObj(
}
UpdateInterest(chanPtr);
TclChannelRelease((Tcl_Channel)chanPtr);
+ if (GotFlag(statePtr, CHANNEL_ENCODING_ERROR) &&
+ (copiedTotal == 0 || !GotFlag(statePtr, CHANNEL_NONBLOCKING))) {
+ Tcl_SetErrno(EILSEQ);
+ copiedTotal = -1;
+ }
return copiedTotal;
}
@@ -7534,8 +7552,7 @@ Tcl_Eof(
ChannelState *statePtr = ((Channel *) chan)->state;
/* State of real channel structure. */
- if (GotFlag(statePtr, CHANNEL_NONBLOCKING|CHANNEL_FCOPY)
- && GotFlag(statePtr, CHANNEL_ENCODING_ERROR)) {
+ if (GotFlag(statePtr, CHANNEL_ENCODING_ERROR)) {
return 0;
}
return GotFlag(statePtr, CHANNEL_EOF) ? 1 : 0;
@@ -9751,7 +9768,6 @@ CopyData(
* the bottom of the stack.
*/
- SetFlag(inStatePtr, CHANNEL_FCOPY);
inBinary = (inStatePtr->encoding == NULL);
outBinary = (outStatePtr->encoding == NULL);
sameEncoding = inStatePtr->encoding == outStatePtr->encoding
@@ -9867,7 +9883,6 @@ CopyData(
TclDecrRefCount(bufObj);
bufObj = NULL;
}
- ResetFlag(inStatePtr, CHANNEL_FCOPY);
return TCL_OK;
}
}
@@ -9959,7 +9974,6 @@ CopyData(
TclDecrRefCount(bufObj);
bufObj = NULL;
}
- ResetFlag(inStatePtr, CHANNEL_FCOPY);
return TCL_OK;
}
@@ -9982,7 +9996,6 @@ CopyData(
TclDecrRefCount(bufObj);
bufObj = NULL;
}
- ResetFlag(inStatePtr, CHANNEL_FCOPY);
return TCL_OK;
}
} /* while */
@@ -10035,7 +10048,6 @@ CopyData(
}
}
}
- ResetFlag(inStatePtr, CHANNEL_FCOPY);
return result;
}
diff --git a/generic/tclIO.h b/generic/tclIO.h
index 109c770..cdd96ff 100644
--- a/generic/tclIO.h
+++ b/generic/tclIO.h
@@ -236,8 +236,6 @@ typedef struct ChannelState {
* flushed after every newline. */
#define CHANNEL_UNBUFFERED (1<<5) /* Output to the channel must always
* be flushed immediately. */
-#define CHANNEL_FCOPY (1<<6) /* Channel is currently doing an fcopy
- * mode. */
#define BG_FLUSH_SCHEDULED (1<<7) /* A background flush of the queued
* output buffers has been
* scheduled. */
diff --git a/tests/io.test b/tests/io.test
index c3c0cdd..cf90936 100644
--- a/tests/io.test
+++ b/tests/io.test
@@ -9155,6 +9155,22 @@ 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 {
+ set fn [makeFile {} io-75.6]
+ set f [open $fn w+]
+ fconfigure $f -encoding binary
+ # \x81 is invalid 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
+} -body {
+ gets $f
+} -cleanup {
+ close $f
+ removeFile io-75.6
+} -match glob -returnCodes 1 -result {error reading "*": illegal byte sequence}
+
test io-75.8 {invalid utf-8 encoding eof handling (-profile strict)} -setup {
set fn [makeFile {} io-75.8]
set f [open $fn w+]
@@ -9243,10 +9259,10 @@ test io-75.12 {invalid utf-8 encoding read is ignored} -setup {
fconfigure $f -encoding utf-8 -buffering none -eofchar "" -translation lf
} -body {
set d [read $f]
- close $f
binary scan $d H* hd
set hd
} -cleanup {
+ close $f
removeFile io-75.12
} -result 4181
test io-75.13 {invalid utf-8 encoding read is not ignored (-profile strict)} -setup {
@@ -9262,9 +9278,9 @@ test io-75.13 {invalid utf-8 encoding read is not ignored (-profile strict)} -se
set d [read $f]
binary scan $d H* hd
lappend hd [catch {read $f} msg]
- close $f
lappend hd $msg
} -cleanup {
+ close $f
removeFile io-75.13
} -match glob -result {41 1 {error reading "*": illegal byte sequence}}