summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2023-03-21 08:45:56 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2023-03-21 08:45:56 (GMT)
commitafdd59e3580b6a38098fa8faac3db12052f232d8 (patch)
tree9d8e420444410dc60e1765586e7a7c13634f7507
parent6ff9d841db20402b12687f25521cedbed683deca (diff)
parent8f3fb2f85e9212f570254b21558c21ffcde26b08 (diff)
downloadtcl-afdd59e3580b6a38098fa8faac3db12052f232d8.zip
tcl-afdd59e3580b6a38098fa8faac3db12052f232d8.tar.gz
tcl-afdd59e3580b6a38098fa8faac3db12052f232d8.tar.bz2
Merge 8.7
-rw-r--r--generic/tclIO.c26
-rw-r--r--generic/tclIO.h2
-rw-r--r--tests/io.test20
-rw-r--r--tests/ioCmd.test2
4 files changed, 38 insertions, 12 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c
index bc891a2..ac624c1 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -4880,6 +4880,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;
}
@@ -4996,6 +5009,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;
}
@@ -7501,8 +7519,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;
@@ -9664,7 +9681,6 @@ CopyData(
* the bottom of the stack.
*/
- SetFlag(inStatePtr, CHANNEL_FCOPY);
inBinary = (inStatePtr->encoding == NULL);
outBinary = (outStatePtr->encoding == NULL);
sameEncoding = inStatePtr->encoding == outStatePtr->encoding
@@ -9780,7 +9796,6 @@ CopyData(
TclDecrRefCount(bufObj);
bufObj = NULL;
}
- ResetFlag(inStatePtr, CHANNEL_FCOPY);
return TCL_OK;
}
}
@@ -9872,7 +9887,6 @@ CopyData(
TclDecrRefCount(bufObj);
bufObj = NULL;
}
- ResetFlag(inStatePtr, CHANNEL_FCOPY);
return TCL_OK;
}
@@ -9895,7 +9909,6 @@ CopyData(
TclDecrRefCount(bufObj);
bufObj = NULL;
}
- ResetFlag(inStatePtr, CHANNEL_FCOPY);
return TCL_OK;
}
} /* while */
@@ -9948,7 +9961,6 @@ CopyData(
}
}
}
- ResetFlag(inStatePtr, CHANNEL_FCOPY);
return result;
}
diff --git a/generic/tclIO.h b/generic/tclIO.h
index c3b5bc3..e3eac72 100644
--- a/generic/tclIO.h
+++ b/generic/tclIO.h
@@ -238,8 +238,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 538f554..034316e 100644
--- a/tests/io.test
+++ b/tests/io.test
@@ -9218,6 +9218,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+]
@@ -9306,10 +9322,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 {
@@ -9325,9 +9341,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}}
diff --git a/tests/ioCmd.test b/tests/ioCmd.test
index 1ac5ca7..399fd95 100644
--- a/tests/ioCmd.test
+++ b/tests/ioCmd.test
@@ -369,7 +369,7 @@ test iocmd-8.20 {fconfigure command / win console channel} -constraints {nonPort
# TODO: Test parsing of serial channel options (nonPortable, since requires an
# open channel to work with).
-test iocmd-8.21 {fconfigure -profile badprofile} -body {
+test iocmd-8.23 {fconfigure -profile badprofile} -body {
fconfigure stdin -profile froboz
} -returnCodes error -result {bad profile name "froboz": must be replace, strict, or tcl8}