diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2016-02-08 16:39:34 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2016-02-08 16:39:34 (GMT) |
commit | 9b3fefa1f082d55d68361c9d4e2f39efec3bc214 (patch) | |
tree | 3f98a9633db0d43b0c50e3f1c952735bda497222 | |
parent | 9425cf81e4e73cf2c80e940a811967e58abdc054 (diff) | |
parent | 3b67157554ddf66b9d0fafeda1944869ed881b13 (diff) | |
download | tk-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.n | 6 | ||||
-rw-r--r-- | generic/tkOption.c | 40 | ||||
-rwxr-xr-x | tests/option.file3 | 2 |
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 \ |