From 555bbc4fc9ae1d18813578c9479915349bd81591 Mon Sep 17 00:00:00 2001 From: dkf Date: Wed, 15 Sep 2010 22:11:59 +0000 Subject: * generic/tclBinary.c (TclAppendBytesToByteArray): [Bug 3067036]: Make sure we never try to double zero repeatedly to get a buffer size. Also added a check for sanity on the size of buffer being appended. --- ChangeLog | 30 ++++++++++++++++++------------ generic/tclBinary.c | 23 +++++++++++++++++++---- tests/binary.test | 25 +++++++++++++++++++++++-- 3 files changed, 60 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 15eef04..ef97787 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-09-15 Donal K. Fellows + + * generic/tclBinary.c (TclAppendBytesToByteArray): [Bug 3067036]: Make + sure we never try to double zero repeatedly to get a buffer size. Also + added a check for sanity on the size of buffer being appended. + 2010-09-15 Don Porter * unix/Makefile.in: Revise `make dist` target to tolerate the @@ -5,19 +11,19 @@ 2010-09-15 Jan Nijtmans - * tools/genStubs.tcl [Patch 3034251] backport ttkGenStubs.tcl - * generic/tcl.decls features to genStubs.tcl. Make the "generic" - * generic/tclInt.decls argument in the *.decls files optional - * generic/tclOO.decls (no change to any tcl*Decls.h files) - * generic/tclTomMath.decls - This allows genStubs.tcl to generate the ttk stub files as well, - while keeping full compatibility with existing *.decls files. + * tools/genStubs.tcl: [Patch 3034251]: Backport ttkGenStubs.tcl + * generic/tcl.decls: features to genStubs.tcl. Make the "generic" + * generic/tclInt.decls: argument in the *.decls files optional + * generic/tclOO.decls: (no change to any tcl*Decls.h files) + * generic/tclTomMath.decls: + This allows genStubs.tcl to generate the ttk stub files as well, while + keeping full compatibility with existing *.decls files. 2010-09-14 Jan Nijtmans * win/tclWinPort.h: Allow all Win2000+ API entries in Tcl - * win/tclWin32Dll.c: Eliminate dynamical loading of - advapi23 and kernal32 symbols. + * win/tclWin32Dll.c: Eliminate dynamical loading of advapi23 and + kernel32 symbols. 2010-09-13 Jan Nijtmans @@ -27,13 +33,13 @@ * win/tclWinLoad.c: * win/tclWinSerial.c: * win/tclWinSock.c: - * tools/genStubs.tcl Add scspec feature from ttkGenStubs.tcl + * tools/genStubs.tcl: Add scspec feature from ttkGenStubs.tcl (no change in output for *Decls.h files) 2010-09-10 Jan Nijtmans - * win/tclWin32Dll.c: Partly revert yesterday's change, to make it - work on VC++ 6.0 again. + * win/tclWin32Dll.c: Partly revert yesterday's change, to make it work + on VC++ 6.0 again. 2010-09-10 Donal K. Fellows diff --git a/generic/tclBinary.c b/generic/tclBinary.c index 1859c0a..de2d319 100644 --- a/generic/tclBinary.c +++ b/generic/tclBinary.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclBinary.c,v 1.65 2010/08/22 18:53:26 nijtmans Exp $ + * RCS: @(#) $Id: tclBinary.c,v 1.66 2010/09/15 22:12:00 dkf Exp $ */ #include "tclInt.h" @@ -609,6 +609,10 @@ TclAppendBytesToByteArray( if (Tcl_IsShared(objPtr)) { Tcl_Panic("%s called with shared object","TclAppendBytesToByteArray"); } + if (len < 0) { + Tcl_Panic("%s must be called with definite number of bytes to append", + "TclAppendBytesToByteArray"); + } if (objPtr->typePtr != &tclByteArrayType) { SetByteArrayFromAny(NULL, objPtr); } @@ -623,9 +627,20 @@ TclAppendBytesToByteArray( ByteArray *tmpByteArrayPtr = NULL; attempt = byteArrayPtr->allocated; - do { - attempt *= 2; - } while (attempt < used+len); + if (attempt < 1) { + /* + * No allocated bytes, so must be none used too. We use this + * method to calculate how many bytes to allocate because we can + * end up with a zero-length buffer otherwise, when doubling can + * cause trouble. [Bug 3067036] + */ + + attempt = len + 1; + } else { + do { + attempt *= 2; + } while (attempt < used+len); + } if (BYTEARRAY_SIZE(attempt) > BYTEARRAY_SIZE(used)) { tmpByteArrayPtr = (ByteArray *) diff --git a/tests/binary.test b/tests/binary.test index c6b6941..79fdb92 100644 --- a/tests/binary.test +++ b/tests/binary.test @@ -10,7 +10,7 @@ # See the file "license.terms" for information on usage and redistribution of # this file, and for a DISCLAIMER OF ALL WARRANTIES. # -# RCS: @(#) $Id: binary.test,v 1.40 2009/12/29 01:43:23 patthoyts Exp $ +# RCS: @(#) $Id: binary.test,v 1.41 2010/09/15 22:12:00 dkf Exp $ if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest @@ -76,7 +76,7 @@ proc testIEEE {} { } testConstraint ieeeFloatingPoint [testIEEE] - + # ---------------------------------------------------------------------- test binary-0.1 {DupByteArrayInternalRep} { @@ -2736,7 +2736,28 @@ test binary-75.26 {binary decode uuencode} -body { string length [binary decode uuencode " "] } -result 0 +test binary-76.1 {binary string appending growth algorithm} unix { + # Create zero-length byte array first + set f [open /dev/null rb] + chan configure $f -blocking 0 + set str [read $f 2] + close $f + # Append to it + string length [append str [binary format a* foo]] +} 3 +test binary-76.2 {binary string appending growth algorithm} win { + # Create zero-length byte array first + set f [open NUL rb] + chan configure $f -blocking 0 + set str [read $f 2] + close $f + # Append to it + string length [append str [binary format a* foo]] +} 3 + +# ---------------------------------------------------------------------- # cleanup + ::tcltest::cleanupTests return -- cgit v0.12