summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2012-02-29 21:56:20 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2012-02-29 21:56:20 (GMT)
commit336410f92239eecba4d739de6e5b67cf02990694 (patch)
tree982b5959dd17b61c8f3b21f473dfbe426b40cfb6 /generic
parentf3bdd208ac10cfe9a475b0689677acd542debee2 (diff)
parent6ad807858b1217d40a9e5a2c1d5bf241625971ca (diff)
downloadtcl-336410f92239eecba4d739de6e5b67cf02990694.zip
tcl-336410f92239eecba4d739de6e5b67cf02990694.tar.gz
tcl-336410f92239eecba4d739de6e5b67cf02990694.tar.bz2
[Bug 3466099] BOM in Unicode
Diffstat (limited to 'generic')
-rw-r--r--generic/tclEncoding.c4
-rw-r--r--generic/tclIOUtil.c36
2 files changed, 36 insertions, 4 deletions
diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c
index 15411d8..49418c9 100644
--- a/generic/tclEncoding.c
+++ b/generic/tclEncoding.c
@@ -979,13 +979,13 @@ Tcl_GetEncodingNames(
int
Tcl_SetSystemEncoding(
Tcl_Interp *interp, /* Interp for error reporting, if not NULL. */
- const char *name) /* The name of the desired encoding, or NULL
+ const char *name) /* The name of the desired encoding, or NULL/""
* to reset to default encoding. */
{
Tcl_Encoding encoding;
Encoding *encodingPtr;
- if (name == NULL) {
+ if (!name || !*name) {
Tcl_MutexLock(&encodingMutex);
encoding = defaultEncoding;
encodingPtr = (Encoding *) encoding;
diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c
index fa616b3..62553f2 100644
--- a/generic/tclIOUtil.c
+++ b/generic/tclIOUtil.c
@@ -1729,7 +1729,22 @@ Tcl_FSEvalFileEx(
objPtr = Tcl_NewObj();
Tcl_IncrRefCount(objPtr);
- if (Tcl_ReadChars(chan, objPtr, -1, 0) < 0) {
+ /* Try to read first character of stream, so we can
+ * check for utf-8 BOM to be handled especially.
+ */
+ if (Tcl_ReadChars(chan, objPtr, 1, 0) < 0) {
+ Tcl_Close(interp, chan);
+ Tcl_AppendResult(interp, "couldn't read file \"",
+ Tcl_GetString(pathPtr), "\": ", Tcl_PosixError(interp), NULL);
+ goto end;
+ }
+ string = Tcl_GetString(objPtr);
+ /*
+ * If first character is not a BOM, append the remaining characters,
+ * otherwise replace them [Bug 3466099].
+ */
+ if (Tcl_ReadChars(chan, objPtr, -1,
+ memcmp(string, "\xef\xbf\xbe", 3)) < 0) {
Tcl_Close(interp, chan);
Tcl_AppendResult(interp, "couldn't read file \"",
Tcl_GetString(pathPtr), "\": ", Tcl_PosixError(interp), NULL);
@@ -1798,6 +1813,7 @@ TclNREvalFile(
Tcl_Obj *oldScriptFile, *objPtr;
Interp *iPtr;
Tcl_Channel chan;
+ const char *string;
if (Tcl_FSGetNormalizedPath(interp, pathPtr) == NULL) {
return TCL_ERROR;
@@ -1839,13 +1855,29 @@ TclNREvalFile(
objPtr = Tcl_NewObj();
Tcl_IncrRefCount(objPtr);
- if (Tcl_ReadChars(chan, objPtr, -1, 0) < 0) {
+ /* Try to read first character of stream, so we can
+ * check for utf-8 BOM to be handled especially.
+ */
+ if (Tcl_ReadChars(chan, objPtr, 1, 0) < 0) {
Tcl_Close(interp, chan);
Tcl_AppendResult(interp, "couldn't read file \"",
Tcl_GetString(pathPtr), "\": ", Tcl_PosixError(interp), NULL);
Tcl_DecrRefCount(objPtr);
return TCL_ERROR;
}
+ string = Tcl_GetString(objPtr);
+ /*
+ * If first character is not a BOM, append the remaining characters,
+ * otherwise replace them [Bug 3466099].
+ */
+ if (Tcl_ReadChars(chan, objPtr, -1,
+ memcmp(string, "\xef\xbf\xbe", 3)) < 0) {
+ Tcl_Close(interp, chan);
+ Tcl_AppendResult(interp, "couldn't read file \"",
+ Tcl_GetString(pathPtr), "\": ", Tcl_PosixError(interp), NULL);
+ Tcl_DecrRefCount(objPtr);
+ return TCL_ERROR;
+ }
if (Tcl_Close(interp, chan) != TCL_OK) {
Tcl_DecrRefCount(objPtr);