diff options
author | dgp <dgp@users.sourceforge.net> | 2014-06-05 15:17:29 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2014-06-05 15:17:29 (GMT) |
commit | 5e12990261375322a279069b4bc5110233068335 (patch) | |
tree | ac34e58ae45bc9c662b94326b71d2b603b0c753d /generic | |
parent | 22e5e3f23f66d83f09a06b80a22a8215ab1dfc24 (diff) | |
download | tcl-5e12990261375322a279069b4bc5110233068335.zip tcl-5e12990261375322a279069b4bc5110233068335.tar.gz tcl-5e12990261375322a279069b4bc5110233068335.tar.bz2 |
When too many chars are read by ReadChars() and we trim the limits to
get it right on the next pass, don't forget the TCL_UTF_MAX padding
demanded by Tcl_ExternalToUtf(). (Thanks for finding that, aku!)
Fix the factorPtr management. It was just totaly wrong. The factor should
be a ratio of the record of bytes read to the record of chars read.
With those fixes, new test io-12.6 covers the "too many chars" code.
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tclIO.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c index b7135e9..308e7a9 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5595,10 +5595,13 @@ ReadChars( /* * We read more chars than allowed. Reset limits to - * prevent that and try again. + * prevent that and try again. Don't forget the extra + * padding of TCL_UTF_MAX - 1 bytes demanded by the + * Tcl_ExternalToUtf() call! */ - dstLimit = Tcl_UtfAtIndex(dst, charsToRead + 1) - dst; + dstLimit = Tcl_UtfAtIndex(dst, charsToRead + 1) + + TCL_UTF_MAX - 1 - dst; statePtr->flags = savedFlags; statePtr->inputEncodingFlags = savedIEFlags; statePtr->inputEncodingState = savedState; @@ -5676,8 +5679,12 @@ ReadChars( consume: bufPtr->nextRemoved += srcRead; - if (dstWrote > srcRead + 1) { - *factorPtr = dstWrote * UTF_EXPANSION_FACTOR / srcRead; + /* + * If this read contained multibyte characters, revise factorPtr + * so the next read will allocate bigger buffers. + */ + if (numChars && numChars < srcRead) { + *factorPtr = srcRead * UTF_EXPANSION_FACTOR / numChars; } Tcl_SetObjLength(objPtr, numBytes + dstWrote); return numChars; |