summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--generic/tclEncoding.c39
-rw-r--r--tests/encoding.test52
-rw-r--r--tests/io.test4
4 files changed, 82 insertions, 23 deletions
diff --git a/ChangeLog b/ChangeLog
index be0ce13..d0a354b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2002-03-04 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * tests/io.test:
+ * tests/encoding.test: corrected iso2022 encoding results.
+ added encoding-24.*
+ * generic/tclEncoding.c (EscapeFromUtfProc): corrected output of
+ escape codes as per RFC 1468. [Patch #474358] (taguchi)
+ (TclFinalizeEncodingSubsystem): corrected potential double-free
+ when encodings were finalized on exit. [Bug #219314, #524674]
+
2002-03-01 Jeff Hobbs <jeffh@ActiveState.com>
* library/encoding/iso2022-jp.enc:
diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c
index c42d899..b974e04 100644
--- a/generic/tclEncoding.c
+++ b/generic/tclEncoding.c
@@ -8,7 +8,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclEncoding.c,v 1.10 2002/02/08 02:52:54 dgp Exp $
+ * RCS: @(#) $Id: tclEncoding.c,v 1.11 2002/03/04 22:00:39 hobbs Exp $
*/
#include "tclInt.h"
@@ -310,18 +310,16 @@ TclFinalizeEncodingSubsystem()
{
Tcl_HashSearch search;
Tcl_HashEntry *hPtr;
- Encoding *encodingPtr;
Tcl_MutexLock(&encodingMutex);
encodingsInitialized = 0;
hPtr = Tcl_FirstHashEntry(&encodingTable, &search);
while (hPtr != NULL) {
- encodingPtr = (Encoding *) Tcl_GetHashValue(hPtr);
- if (encodingPtr->freeProc != NULL) {
- (*encodingPtr->freeProc)(encodingPtr->clientData);
- }
- ckfree((char *) encodingPtr->name);
- ckfree((char *) encodingPtr);
+ /*
+ * Call FreeEncoding instead of doing it directly to handle refcounts
+ * like escape encodings use. [Bug #524674]
+ */
+ FreeEncoding((Tcl_Encoding) Tcl_GetHashValue(hPtr));
hPtr = Tcl_NextHashEntry(&search);
}
Tcl_DeleteHashTable(&encodingTable);
@@ -2206,6 +2204,10 @@ TableFreeProc(clientData)
{
TableEncodingData *dataPtr;
+ /*
+ * Make sure we aren't freeing twice on shutdown. [Bug #219314]
+ */
+
dataPtr = (TableEncodingData *) clientData;
ckfree((char *) dataPtr->toUnicode);
ckfree((char *) dataPtr->fromUnicode);
@@ -2491,12 +2493,14 @@ EscapeFromUtfProc(clientData, src, srcLen, flags, statePtr, dst, dstLen,
dstStart = dst;
dstEnd = dst + dstLen - 1;
+ /*
+ * RFC1468 states that the text starts in ASCII, and switches to Japanese
+ * characters, and that the text must end in ASCII. [Patch #474358]
+ */
+
if (flags & TCL_ENCODING_START) {
- unsigned int len;
-
state = 0;
- len = dataPtr->subTables[0].sequenceLen;
- if (dst + dataPtr->initLen + len > dstEnd) {
+ if (dst + dataPtr->initLen > dstEnd) {
*srcReadPtr = 0;
*dstWrotePtr = 0;
return TCL_CONVERT_NOSPACE;
@@ -2504,9 +2508,6 @@ EscapeFromUtfProc(clientData, src, srcLen, flags, statePtr, dst, dstLen,
memcpy((VOID *) dst, (VOID *) dataPtr->init,
(size_t) dataPtr->initLen);
dst += dataPtr->initLen;
- memcpy((VOID *) dst, (VOID *) dataPtr->subTables[0].sequence,
- (size_t) len);
- dst += len;
} else {
state = (int) *statePtr;
}
@@ -2591,9 +2592,15 @@ EscapeFromUtfProc(clientData, src, srcLen, flags, statePtr, dst, dstLen,
}
if ((result == TCL_OK) && (flags & TCL_ENCODING_END)) {
- if (dst + dataPtr->finalLen > dstEnd) {
+ unsigned int len = dataPtr->subTables[0].sequenceLen;
+ if (dst + dataPtr->finalLen + (state?len:0) > dstEnd) {
result = TCL_CONVERT_NOSPACE;
} else {
+ if (state) {
+ memcpy((VOID *) dst, (VOID *) dataPtr->subTables[0].sequence,
+ (size_t) len);
+ dst += len;
+ }
memcpy((VOID *) dst, (VOID *) dataPtr->final,
(size_t) dataPtr->finalLen);
dst += dataPtr->finalLen;
diff --git a/tests/encoding.test b/tests/encoding.test
index bfe7e3c..6753833 100644
--- a/tests/encoding.test
+++ b/tests/encoding.test
@@ -8,7 +8,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: encoding.test,v 1.9 2002/03/02 04:55:31 hobbs Exp $
+# RCS: @(#) $Id: encoding.test,v 1.10 2002/03/04 22:00:40 hobbs Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest
@@ -199,7 +199,7 @@ test encoding-10.1 {Tcl_UtfToExternal} {
proc viewable {str} {
set res ""
foreach c [split $str {}] {
- if {[string is print $c]} {
+ if {[string is print $c] && [string is ascii $c]} {
append res $c
} else {
append res "\\u[format %4.4x [scan $c %c]]"
@@ -229,10 +229,10 @@ test encoding-11.4 {LoadEncodingFile: multi-byte} {
} "\u4e4e"
test encoding-11.5 {LoadEncodingFile: escape file} {
viewable [encoding convertto iso2022 \u4e4e]
-} [viewable "\x1b(B\x1b\$B8C"]
+} [viewable "\x1b\$B8C\x1b(B"]
test encoding-11.5.1 {LoadEncodingFile: escape file} {
viewable [encoding convertto iso2022-jp \u4e4e]
-} [viewable "\x1b(B\x1b\$B8C"]
+} [viewable "\x1b\$B8C\x1b(B"]
test encoding-11.6 {LoadEncodingFile: invalid file} {testencoding} {
set system [encoding system]
set path [testencoding path]
@@ -278,7 +278,7 @@ test encoding-12.5 {LoadTableEncoding: symbol encoding} {
test encoding-13.1 {LoadEscapeTable} {
viewable [set x [encoding convertto iso2022 ab\u4e4e\u68d9g]]
-} [viewable "\x1b(Bab\x1b\$B8C\x1b\$\(DD%\x1b(Bg"]
+} [viewable "ab\x1b\$B8C\x1b\$\(DD%\x1b(Bg"]
test encoding-14.1 {BinaryProc} {
encoding convertto identity \x12\x34\x56\xff\x69
@@ -361,7 +361,49 @@ test encoding-23.3 {iso2022-jp escape encoding test} {
set data
} [string range $::iso2022uniData 0 49] ; # 0 .. 49 inclusive == 50
+test encoding-24.1 {EscapeFreeProc on open channels} {
+ # Bug #524674 input
+ set f [open iso2022.tcl w]
+ puts $f {
+ set f [open iso2022.txt]
+ fconfigure $f -encoding iso2022-jp
+ gets $f
+ }
+ close $f
+ exec [list $::tcltest::tcltest] iso2022.tcl
+} {}
+
+test encoding-24.2 {EscapeFreeProc on open channels} {
+ # Bug #524674 output
+ set f [open iso2022.tcl w]
+ puts $f {
+ fconfigure stdout -encoding iso2022-jp
+ puts ab\u4e4e\u68d9g
+ exit
+ }
+ close $f
+ viewable [exec [list $::tcltest::tcltest] iso2022.tcl]
+} "ab\x1b\$B8C\x1b\$(DD%\x1b(Bg (ab\\u001b\$B8C\\u001b\$(DD%\\u001b(Bg)"
+
+test encoding-24.3 {EscapeFreeProc on open channels} {
+ # Bug #219314 - if we don't free escape encodings correctly on
+ # channel closure, we go boom
+ set f [open iso2022.tcl w]
+ puts $f {
+ encoding system iso2022-jp
+ set a "\u4e4e\u4e5e\u4e5f"; # 3 Japanese Kanji letters
+ puts $a
+ }
+ close $f
+ set f [open "|[list $::tcltest::tcltest iso2022.tcl]"]
+ fconfigure $f -encoding iso2022-jp
+ set count [gets $f line]
+ close $f
+ list $count [viewable $line]
+} [list 3 "\u4e4e\u4e5e\u4e5f (\\u4e4e\\u4e5e\\u4e5f)"]
+
::tcltest::removeFile iso2022.txt
+::tcltest::removeFile iso2022.tcl
# EscapeFreeProc, GetTableEncoding, unilen
# are fully tested by the rest of this file
diff --git a/tests/io.test b/tests/io.test
index 43c4072..d3d167f 100644
--- a/tests/io.test
+++ b/tests/io.test
@@ -12,7 +12,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: io.test,v 1.27 2002/03/02 04:57:29 hobbs Exp $
+# RCS: @(#) $Id: io.test,v 1.28 2002/03/04 22:00:40 hobbs Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest
@@ -101,7 +101,7 @@ test io-1.8 {Tcl_WriteChars: WriteChars} {
puts -nonewline $f [format %s%c [string repeat " " 4] 12399]
close $f
contents test2
-} "\x1b(B \x1b\$B\$O"
+} " \x1b\$B\$O\x1b(B"
test io-2.1 {WriteBytes} {
# loop until all bytes are written