summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2016-02-08 16:39:34 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2016-02-08 16:39:34 (GMT)
commit9b3fefa1f082d55d68361c9d4e2f39efec3bc214 (patch)
tree3f98a9633db0d43b0c50e3f1c952735bda497222
parent9425cf81e4e73cf2c80e940a811967e58abdc054 (diff)
parent3b67157554ddf66b9d0fafeda1944869ed881b13 (diff)
downloadtk-9b3fefa1f082d55d68361c9d4e2f39efec3bc214.zip
tk-9b3fefa1f082d55d68361c9d4e2f39efec3bc214.tar.gz
tk-9b3fefa1f082d55d68361c9d4e2f39efec3bc214.tar.bz2
Fix [0a3d799a6d]: option db rc files in non utf-8 encoding are not portable.
-rw-r--r--doc/option.n6
-rw-r--r--generic/tkOption.c40
-rwxr-xr-xtests/option.file32
3 files changed, 15 insertions, 33 deletions
diff --git a/doc/option.n b/doc/option.n
index 8699c0d..2763d64 100644
--- a/doc/option.n
+++ b/doc/option.n
@@ -59,6 +59,12 @@ options specified in that file to the option database. If \fIpriority\fR
is specified, it indicates the priority level at which to enter the
options; \fIpriority\fR defaults to \fBinteractive\fR.
.PP
+The file is read through a channel which is in "utf-8" encoding,
+invalid byte sequences are automatically converted to valid ones.
+This means that encodings like ISO 8859-1 or cp1252 with high
+probability will work as well, but this cannot be guaranteed.
+This cannot be changed, setting the [encoding system] has no effect.
+.PP
The \fIpriority\fR arguments to the \fBoption\fR command are
normally specified symbolically using one of the following values:
.TP
diff --git a/generic/tkOption.c b/generic/tkOption.c
index 680c9db..24e7fb3 100644
--- a/generic/tkOption.c
+++ b/generic/tkOption.c
@@ -1080,10 +1080,10 @@ ReadOptionFile(
* TK_MAX_PRIO. */
{
const char *realName;
- char *buffer;
+ Tcl_Obj *buffer;
int result, bufferSize;
Tcl_Channel chan;
- Tcl_DString newName, optString;
+ Tcl_DString newName;
/*
* Prevent file system access in a safe interpreter.
@@ -1108,24 +1108,10 @@ ReadOptionFile(
return TCL_ERROR;
}
- /*
- * Compute size of file by seeking to the end of the file. This will
- * overallocate if we are performing CRLF translation.
- */
-
- bufferSize = (int) Tcl_Seek(chan, (Tcl_WideInt) 0, SEEK_END);
- Tcl_Seek(chan, (Tcl_WideInt) 0, SEEK_SET);
-
- if (bufferSize < 0) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "error seeking to end of file \"%s\": %s",
- fileName, Tcl_PosixError(interp)));
- Tcl_Close(NULL, chan);
- return TCL_ERROR;
- }
-
- buffer = ckalloc(bufferSize + 1);
- bufferSize = Tcl_Read(chan, buffer, bufferSize);
+ buffer = Tcl_NewObj();
+ Tcl_IncrRefCount(buffer);
+ Tcl_SetChannelOption(NULL, chan, "-encoding", "utf-8");
+ bufferSize = Tcl_ReadChars(chan, buffer, -1, 0);
if (bufferSize < 0) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"error reading file \"%s\": %s",
@@ -1134,18 +1120,8 @@ ReadOptionFile(
return TCL_ERROR;
}
Tcl_Close(NULL, chan);
- buffer[bufferSize] = 0;
- if ((bufferSize>2) && !memcmp(buffer, "\357\273\277", 3)) {
- /* File starts with UTF-8 BOM */
- result = AddFromString(interp, tkwin, buffer+3, priority);
- } else {
- Tcl_DStringInit(&optString);
- Tcl_ExternalToUtfDString(NULL, buffer, bufferSize, &optString);
- result = AddFromString(interp, tkwin, Tcl_DStringValue(&optString),
- priority);
- Tcl_DStringFree(&optString);
- }
- ckfree(buffer);
+ result = AddFromString(interp, tkwin, Tcl_GetString(buffer), priority);
+ Tcl_DecrRefCount(buffer);
return result;
}
diff --git a/tests/option.file3 b/tests/option.file3
index 87f41ae..146cfd9 100755
--- a/tests/option.file3
+++ b/tests/option.file3
@@ -1,4 +1,4 @@
-! This file is a sample option (resource) database used to test
+! This file is a sample option (resource) database used to test
! Tk's option-handling capabilities.
! Comment line \