diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | generic/tclEncoding.c | 39 | ||||
-rw-r--r-- | tests/encoding.test | 52 | ||||
-rw-r--r-- | tests/io.test | 4 |
4 files changed, 82 insertions, 23 deletions
@@ -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 |