diff options
| author | apnadkarni <apnmbx-wits@yahoo.com> | 2023-05-20 16:39:50 (GMT) |
|---|---|---|
| committer | apnadkarni <apnmbx-wits@yahoo.com> | 2023-05-20 16:39:50 (GMT) |
| commit | f19e2665d309df5a484a53ea6d9b1098275e33db (patch) | |
| tree | 6906aa04fcb87740b514d40f1b4c83435a53a645 /generic/tclUtil.c | |
| parent | 72dfeb60e23c679d2c7258db4eb9ccce0a0661fa (diff) | |
| parent | 96d441c29a2a47269655285a02c546765c163fd2 (diff) | |
| download | tcl-f19e2665d309df5a484a53ea6d9b1098275e33db.zip tcl-f19e2665d309df5a484a53ea6d9b1098275e33db.tar.gz tcl-f19e2665d309df5a484a53ea6d9b1098275e33db.tar.bz2 | |
Fix [c9663296fd]. Also refactor memory reallocation.
Diffstat (limited to 'generic/tclUtil.c')
| -rw-r--r-- | generic/tclUtil.c | 63 |
1 files changed, 33 insertions, 30 deletions
diff --git a/generic/tclUtil.c b/generic/tclUtil.c index a195c10..67c7bc1 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -2606,34 +2606,35 @@ Tcl_DStringAppend( if (length < 0) { length = strlen(bytes); } - newSize = length + dsPtr->length; - /* - * Allocate a larger buffer for the string if the current one isn't large - * enough. Allocate extra space in the new buffer so that there will be - * room to grow before we have to allocate again. - */ + if (length > (TCL_SIZE_MAX - dsPtr->length - 1)) { + Tcl_Panic("max size for a Tcl value (%" TCL_SIZE_MODIFIER + "d bytes) exceeded", + TCL_SIZE_MAX); + return NULL; /* NOTREACHED */ + } + newSize = length + dsPtr->length + 1; - if (newSize >= dsPtr->spaceAvl) { - dsPtr->spaceAvl = newSize * 2; - if (dsPtr->string == dsPtr->staticSpace) { - char *newString = (char *)Tcl_Alloc(dsPtr->spaceAvl); + if (newSize > dsPtr->spaceAvl) { + if (dsPtr->string == dsPtr->staticSpace) { + char *newString; + newString = (char *) TclAllocEx(newSize, &dsPtr->spaceAvl); memcpy(newString, dsPtr->string, dsPtr->length); dsPtr->string = newString; } else { - Tcl_Size index = TCL_INDEX_NONE; + Tcl_Size offset = -1; /* See [16896d49fd] */ if (bytes >= dsPtr->string && bytes <= dsPtr->string + dsPtr->length) { - index = bytes - dsPtr->string; + /* Source string is within this DString. Note offset */ + offset = bytes - dsPtr->string; } - - dsPtr->string = (char *)Tcl_Realloc(dsPtr->string, dsPtr->spaceAvl); - - if (index >= 0) { - bytes = dsPtr->string + index; + dsPtr->string = + (char *)TclReallocEx(dsPtr->string, newSize, &dsPtr->spaceAvl); + if (offset >= 0) { + bytes = dsPtr->string + offset; } } } @@ -2745,12 +2746,11 @@ Tcl_DStringAppendElement( * memcpy, not strcpy, to copy the string to a larger buffer, since there * may be embedded NULLs in the string in some cases. */ - - if (newSize >= dsPtr->spaceAvl) { - dsPtr->spaceAvl = newSize * 2; + newSize += 1; /* For terminating nul */ + if (newSize > dsPtr->spaceAvl) { if (dsPtr->string == dsPtr->staticSpace) { - char *newString = (char *)Tcl_Alloc(dsPtr->spaceAvl); - + char *newString; + newString = (char *) TclAllocEx(newSize, &dsPtr->spaceAvl); memcpy(newString, dsPtr->string, dsPtr->length); dsPtr->string = newString; } else { @@ -2759,11 +2759,11 @@ Tcl_DStringAppendElement( /* See [16896d49fd] */ if (element >= dsPtr->string && element <= dsPtr->string + dsPtr->length) { + /* Source string is within this DString. Note offset */ offset = element - dsPtr->string; } - - dsPtr->string = (char *)Tcl_Realloc(dsPtr->string, dsPtr->spaceAvl); - + dsPtr->string = + (char *)TclReallocEx(dsPtr->string, newSize, &dsPtr->spaceAvl); if (offset >= 0) { element = dsPtr->string + offset; } @@ -2822,13 +2822,16 @@ Tcl_DStringSetLength( * would be wasteful to overallocate that buffer, so we just allocate * enough for the requested size plus the trailing null byte. In the * second case, we are growing the buffer incrementally, so we need - * behavior similar to Tcl_DStringAppend. The requested length will - * usually be a small delta above the current spaceAvl, so we'll end - * up doubling the old size. This won't grow the buffer quite as - * quickly, but it should be close enough. + * behavior similar to Tcl_DStringAppend. + * TODO - the above makes no sense to me. How does the code below + * translate into distinguishing the two cases above? IMO, if caller + * specifically sets the length, there is no cause for overallocation. */ - newsize = dsPtr->spaceAvl * 2; + if (length >= TCL_SIZE_MAX) { + Tcl_Panic("Tcl_Concat: max size of Tcl value exceeded"); + } + newsize = TclUpsizeAlloc(dsPtr->spaceAvl, length + 1, TCL_SIZE_MAX); if (length < newsize) { dsPtr->spaceAvl = newsize; } else { |
