diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2010-09-15 22:11:59 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2010-09-15 22:11:59 (GMT) |
commit | 555bbc4fc9ae1d18813578c9479915349bd81591 (patch) | |
tree | 90b78e5031bf8450c6b60d11a0d5357a48718853 /generic | |
parent | 049dfbc90f9aea5bc4cd4e02bc9cf4c774ea4f8a (diff) | |
download | tcl-555bbc4fc9ae1d18813578c9479915349bd81591.zip tcl-555bbc4fc9ae1d18813578c9479915349bd81591.tar.gz tcl-555bbc4fc9ae1d18813578c9479915349bd81591.tar.bz2 |
* 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.
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tclBinary.c | 23 |
1 files changed, 19 insertions, 4 deletions
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 *) |