summaryrefslogtreecommitdiffstats
path: root/generic/tclStringObj.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclStringObj.c')
-rw-r--r--generic/tclStringObj.c408
1 files changed, 223 insertions, 185 deletions
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c
index bb2cddf..3063ea3 100644
--- a/generic/tclStringObj.c
+++ b/generic/tclStringObj.c
@@ -45,28 +45,28 @@
static void AppendPrintfToObjVA(Tcl_Obj *objPtr,
const char *format, va_list argList);
static void AppendUnicodeToUnicodeRep(Tcl_Obj *objPtr,
- const Tcl_UniChar *unicode, size_t appendNumChars);
+ const Tcl_UniChar *unicode, Tcl_Size appendNumChars);
static void AppendUnicodeToUtfRep(Tcl_Obj *objPtr,
- const Tcl_UniChar *unicode, size_t numChars);
+ const Tcl_UniChar *unicode, Tcl_Size numChars);
static void AppendUtfToUnicodeRep(Tcl_Obj *objPtr,
- const char *bytes, size_t numBytes);
+ const char *bytes, Tcl_Size numBytes);
static void AppendUtfToUtfRep(Tcl_Obj *objPtr,
- const char *bytes, size_t numBytes);
+ const char *bytes, Tcl_Size numBytes);
static void DupStringInternalRep(Tcl_Obj *objPtr,
Tcl_Obj *copyPtr);
-static size_t ExtendStringRepWithUnicode(Tcl_Obj *objPtr,
- const Tcl_UniChar *unicode, size_t numChars);
+static Tcl_Size ExtendStringRepWithUnicode(Tcl_Obj *objPtr,
+ const Tcl_UniChar *unicode, Tcl_Size numChars);
static void ExtendUnicodeRepWithString(Tcl_Obj *objPtr,
- const char *bytes, size_t numBytes,
- size_t numAppendChars);
+ const char *bytes, Tcl_Size numBytes,
+ Tcl_Size numAppendChars);
static void FillUnicodeRep(Tcl_Obj *objPtr);
static void FreeStringInternalRep(Tcl_Obj *objPtr);
static void GrowStringBuffer(Tcl_Obj *objPtr, size_t needed, int flag);
static void GrowUnicodeBuffer(Tcl_Obj *objPtr, size_t needed);
static int SetStringFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static void SetUnicodeObj(Tcl_Obj *objPtr,
- const Tcl_UniChar *unicode, size_t numChars);
-static size_t UnicodeLength(const Tcl_UniChar *unicode);
+ const Tcl_UniChar *unicode, Tcl_Size numChars);
+static Tcl_Size UnicodeLength(const Tcl_UniChar *unicode);
static void UpdateStringOfString(Tcl_Obj *objPtr);
#if TCL_UTF_MAX > 3
@@ -257,7 +257,7 @@ Tcl_Obj *
Tcl_NewStringObj(
const char *bytes, /* Points to the first of the length bytes
* used to initialize the new object. */
- size_t length) /* The number of bytes to copy from "bytes"
+ Tcl_Size length) /* The number of bytes to copy from "bytes"
* when initializing the new object. If
* TCL_INDEX_NONE, use bytes up to the first NUL
* byte. */
@@ -269,13 +269,13 @@ Tcl_Obj *
Tcl_NewStringObj(
const char *bytes, /* Points to the first of the length bytes
* used to initialize the new object. */
- size_t length) /* The number of bytes to copy from "bytes"
+ Tcl_Size length) /* The number of bytes to copy from "bytes"
* when initializing the new object. If -1,
* use bytes up to the first NUL byte. */
{
Tcl_Obj *objPtr;
- if (length == TCL_INDEX_NONE) {
+ if (length < 0) {
length = (bytes? strlen(bytes) : 0);
}
TclNewStringObj(objPtr, bytes, length);
@@ -317,7 +317,7 @@ Tcl_Obj *
Tcl_DbNewStringObj(
const char *bytes, /* Points to the first of the length bytes
* used to initialize the new object. */
- size_t length, /* The number of bytes to copy from "bytes"
+ Tcl_Size length, /* The number of bytes to copy from "bytes"
* when initializing the new object. If -1,
* use bytes up to the first NUL byte. */
const char *file, /* The name of the source file calling this
@@ -339,7 +339,7 @@ Tcl_Obj *
Tcl_DbNewStringObj(
const char *bytes, /* Points to the first of the length bytes
* used to initialize the new object. */
- size_t length, /* The number of bytes to copy from "bytes"
+ Tcl_Size length, /* The number of bytes to copy from "bytes"
* when initializing the new object. If -1,
* use bytes up to the first NUL byte. */
TCL_UNUSED(const char *) /*file*/,
@@ -372,7 +372,7 @@ Tcl_Obj *
Tcl_NewUnicodeObj(
const Tcl_UniChar *unicode, /* The unicode string used to initialize the
* new object. */
- size_t numChars) /* Number of characters in the unicode
+ Tcl_Size numChars) /* Number of characters in the unicode
* string. */
{
Tcl_Obj *objPtr;
@@ -399,13 +399,13 @@ Tcl_NewUnicodeObj(
*----------------------------------------------------------------------
*/
-size_t
+Tcl_Size
Tcl_GetCharLength(
Tcl_Obj *objPtr) /* The String object to get the num chars
* of. */
{
String *stringPtr;
- size_t numChars = 0;
+ Tcl_Size numChars = 0;
/*
* Quick, no-shimmer return for short string reps.
@@ -444,19 +444,19 @@ Tcl_GetCharLength(
* If numChars is unknown, compute it.
*/
- if (numChars == TCL_INDEX_NONE) {
+ if (numChars < 0) {
TclNumUtfCharsM(numChars, objPtr->bytes, objPtr->length);
stringPtr->numChars = numChars;
}
return numChars;
}
-size_t
+Tcl_Size
TclGetCharLength(
Tcl_Obj *objPtr) /* The String object to get the num chars
* of. */
{
- size_t numChars = 0;
+ Tcl_Size numChars = 0;
/*
* Quick, no-shimmer return for short string reps.
@@ -509,7 +509,7 @@ int
TclCheckEmptyString(
Tcl_Obj *objPtr)
{
- size_t length = TCL_INDEX_NONE;
+ Tcl_Size length = TCL_INDEX_NONE;
if (objPtr->bytes == &tclEmptyString) {
return TCL_EMPTYSTRING_YES;
@@ -553,18 +553,22 @@ int
Tcl_GetUniChar(
Tcl_Obj *objPtr, /* The object to get the Unicode charater
* from. */
- size_t index) /* Get the index'th Unicode character. */
+ Tcl_Size index) /* Get the index'th Unicode character. */
{
String *stringPtr;
int ch;
+ if (index < 0) {
+ return -1;
+ }
+
/*
* Optimize the case where we're really dealing with a ByteArray object
* we don't need to convert to a string to perform the indexing operation.
*/
if (TclIsPureByteArray(objPtr)) {
- size_t length = 0;
+ Tcl_Size length = 0;
unsigned char *bytes = Tcl_GetByteArrayFromObj(objPtr, &length);
if (index >= length) {
return -1;
@@ -622,17 +626,21 @@ int
TclGetUniChar(
Tcl_Obj *objPtr, /* The object to get the Unicode charater
* from. */
- size_t index) /* Get the index'th Unicode character. */
+ Tcl_Size index) /* Get the index'th Unicode character. */
{
int ch = 0;
+ if (index < 0) {
+ return -1;
+ }
+
/*
* Optimize the ByteArray case: N need need to convert to a string to
* perform the indexing operation.
*/
if (TclIsPureByteArray(objPtr)) {
- size_t length = 0;
+ Tcl_Size length = 0;
unsigned char *bytes = Tcl_GetByteArrayFromObj(objPtr, &length);
if (index >= length) {
return -1;
@@ -641,7 +649,7 @@ TclGetUniChar(
return bytes[index];
}
- size_t numChars = TclNumUtfChars(objPtr->bytes, objPtr->length);
+ Tcl_Size numChars = TclNumUtfChars(objPtr->bytes, objPtr->length);
if (index >= numChars) {
return -1;
@@ -694,7 +702,7 @@ TclGetUnicodeFromObj(
if (lengthPtr != NULL) {
if (stringPtr->numChars > INT_MAX) {
Tcl_Panic("Tcl_GetUnicodeFromObj with 'int' lengthPtr"
- " cannot handle such long strings. Please use 'size_t'");
+ " cannot handle such long strings. Please use 'Tcl_Size'");
}
*lengthPtr = (int)stringPtr->numChars;
}
@@ -706,7 +714,7 @@ Tcl_UniChar *
Tcl_GetUnicodeFromObj(
Tcl_Obj *objPtr, /* The object to find the unicode string
* for. */
- size_t *lengthPtr) /* If non-NULL, the location where the string
+ Tcl_Size *lengthPtr) /* If non-NULL, the location where the string
* rep's unichar length should be stored. If
* NULL, no length is stored. */
{
@@ -749,14 +757,14 @@ Tcl_GetUnicodeFromObj(
Tcl_Obj *
Tcl_GetRange(
Tcl_Obj *objPtr, /* The Tcl object to find the range of. */
- size_t first, /* First index of the range. */
- size_t last) /* Last index of the range. */
+ Tcl_Size first, /* First index of the range. */
+ Tcl_Size last) /* Last index of the range. */
{
Tcl_Obj *newObjPtr; /* The Tcl object to find the range of. */
String *stringPtr;
- size_t length = 0;
+ Tcl_Size length = 0;
- if (first == TCL_INDEX_NONE) {
+ if (first < 0) {
first = TCL_INDEX_START;
}
@@ -768,10 +776,10 @@ Tcl_GetRange(
if (TclIsPureByteArray(objPtr)) {
unsigned char *bytes = Tcl_GetByteArrayFromObj(objPtr, &length);
- if (last >= length) {
+ if (last < 0 || last >= length) {
last = length - 1;
}
- if (last + 1 < first + 1) {
+ if (last < first) {
TclNewObj(newObjPtr);
return newObjPtr;
}
@@ -794,10 +802,10 @@ Tcl_GetRange(
TclNumUtfCharsM(stringPtr->numChars, objPtr->bytes, objPtr->length);
}
if (stringPtr->numChars == objPtr->length) {
- if (last >= stringPtr->numChars) {
+ if (last < 0 || last >= stringPtr->numChars) {
last = stringPtr->numChars - 1;
}
- if (last + 1 < first + 1) {
+ if (last < first) {
TclNewObj(newObjPtr);
return newObjPtr;
}
@@ -815,20 +823,20 @@ Tcl_GetRange(
FillUnicodeRep(objPtr);
stringPtr = GET_STRING(objPtr);
}
- if (last >= stringPtr->numChars) {
+ if (last < 0 || last >= stringPtr->numChars) {
last = stringPtr->numChars - 1;
}
- if (last + 1 < first + 1) {
+ if (last < first) {
TclNewObj(newObjPtr);
return newObjPtr;
}
#if TCL_UTF_MAX < 4
/* See: bug [11ae2be95dac9417] */
- if ((first + 1 > 1) && ((stringPtr->unicode[first] & 0xFC00) == 0xDC00)
+ if ((first > 0) && ((stringPtr->unicode[first] & 0xFC00) == 0xDC00)
&& ((stringPtr->unicode[first-1] & 0xFC00) == 0xD800)) {
++first;
}
- if ((last + 2 < stringPtr->numChars + 1)
+ if ((last + 1 < stringPtr->numChars)
&& ((stringPtr->unicode[last+1] & 0xFC00) == 0xDC00)
&& ((stringPtr->unicode[last] & 0xFC00) == 0xD800)) {
++last;
@@ -840,13 +848,13 @@ Tcl_GetRange(
Tcl_Obj *
TclGetRange(
Tcl_Obj *objPtr, /* The Tcl object to find the range of. */
- size_t first, /* First index of the range. */
- size_t last) /* Last index of the range. */
+ Tcl_Size first, /* First index of the range. */
+ Tcl_Size last) /* Last index of the range. */
{
Tcl_Obj *newObjPtr; /* The Tcl object to find the range of. */
- size_t length = 0;
+ Tcl_Size length = 0;
- if (first == TCL_INDEX_NONE) {
+ if (first < 0) {
first = TCL_INDEX_START;
}
@@ -858,22 +866,22 @@ TclGetRange(
if (TclIsPureByteArray(objPtr)) {
unsigned char *bytes = Tcl_GetByteArrayFromObj(objPtr, &length);
- if (last >= length) {
+ if (last < 0 || last >= length) {
last = length - 1;
}
- if (last + 1 < first + 1) {
+ if (last < first) {
TclNewObj(newObjPtr);
return newObjPtr;
}
return Tcl_NewByteArrayObj(bytes + first, last - first + 1);
}
- size_t numChars = TclNumUtfChars(objPtr->bytes, objPtr->length);
+ Tcl_Size numChars = TclNumUtfChars(objPtr->bytes, objPtr->length);
- if (last >= numChars) {
+ if (last < 0 || last >= numChars) {
last = numChars - 1;
}
- if (last + 1 < first + 1) {
+ if (last < first) {
TclNewObj(newObjPtr);
return newObjPtr;
}
@@ -908,7 +916,7 @@ Tcl_SetStringObj(
Tcl_Obj *objPtr, /* Object whose internal rep to init. */
const char *bytes, /* Points to the first of the length bytes
* used to initialize the object. */
- size_t length) /* The number of bytes to copy from "bytes"
+ Tcl_Size length) /* The number of bytes to copy from "bytes"
* when initializing the object. If -1,
* use bytes up to the first NUL byte.*/
{
@@ -960,12 +968,16 @@ void
Tcl_SetObjLength(
Tcl_Obj *objPtr, /* Pointer to object. This object must not
* currently be shared. */
- size_t length) /* Number of bytes desired for string
+ Tcl_Size length) /* Number of bytes desired for string
* representation of object, not including
* terminating null byte. */
{
String *stringPtr;
+ if (length < 0) {
+ Tcl_Panic("Tcl_SetObjLength: length requested is negative: "
+ "%" TCL_SIZE_MODIFIER "d (integer overflow?)", length);
+ }
if (Tcl_IsShared(objPtr)) {
Tcl_Panic("%s called with shared object", "Tcl_SetObjLength");
}
@@ -1051,12 +1063,17 @@ int
Tcl_AttemptSetObjLength(
Tcl_Obj *objPtr, /* Pointer to object. This object must not
* currently be shared. */
- size_t length) /* Number of bytes desired for string
+ Tcl_Size length) /* Number of bytes desired for string
* representation of object, not including
* terminating null byte. */
{
String *stringPtr;
+ if (length < 0) {
+ /* Negative lengths => most likely integer overflow */
+ return 0;
+ }
+
if (Tcl_IsShared(objPtr)) {
Tcl_Panic("%s called with shared object", "Tcl_AttemptSetObjLength");
}
@@ -1150,7 +1167,7 @@ Tcl_SetUnicodeObj(
Tcl_Obj *objPtr, /* The object to set the string of. */
const Tcl_UniChar *unicode, /* The Unicode string used to initialize the
* object. */
- size_t numChars) /* Number of characters in the Unicode
+ Tcl_Size numChars) /* Number of characters in the Unicode
* string. */
{
if (Tcl_IsShared(objPtr)) {
@@ -1160,14 +1177,15 @@ Tcl_SetUnicodeObj(
SetUnicodeObj(objPtr, unicode, numChars);
}
-static size_t
+static Tcl_Size
UnicodeLength(
const Tcl_UniChar *unicode)
{
- size_t numChars = 0;
+ Tcl_Size numChars = 0;
if (unicode) {
- while ((numChars != TCL_INDEX_NONE) && (unicode[numChars] != 0)) {
+ /* TODO - is this overflow check really necessary? */
+ while ((numChars >= 0) && (unicode[numChars] != 0)) {
numChars++;
}
}
@@ -1179,11 +1197,12 @@ SetUnicodeObj(
Tcl_Obj *objPtr, /* The object to set the string of. */
const Tcl_UniChar *unicode, /* The Unicode string used to initialize the
* object. */
- size_t numChars) /* Number of characters in unicode. */
+ Tcl_Size numChars) /* Number of characters in the Unicode
+ * string. */
{
String *stringPtr;
- if (numChars == TCL_INDEX_NONE) {
+ if (numChars < 0) {
numChars = UnicodeLength(unicode);
}
@@ -1228,20 +1247,20 @@ Tcl_AppendLimitedToObj(
Tcl_Obj *objPtr, /* Points to the object to append to. */
const char *bytes, /* Points to the bytes to append to the
* object. */
- size_t length, /* The number of bytes available to be
+ Tcl_Size length, /* The number of bytes available to be
* appended from "bytes". If -1, then
* all bytes up to a NUL byte are available. */
- size_t limit, /* The maximum number of bytes to append to
+ Tcl_Size limit, /* The maximum number of bytes to append to
* the object. */
const char *ellipsis) /* Ellipsis marker string, appended to the
* object to indicate not all available bytes
* at "bytes" were appended. */
{
String *stringPtr;
- size_t toCopy = 0;
- size_t eLen = 0;
+ Tcl_Size toCopy = 0;
+ Tcl_Size eLen = 0;
- if (length == TCL_INDEX_NONE) {
+ if (length < 0) {
length = (bytes ? strlen(bytes) : 0);
}
if (length == 0) {
@@ -1324,11 +1343,11 @@ Tcl_AppendToObj(
Tcl_Obj *objPtr, /* Points to the object to append to. */
const char *bytes, /* Points to the bytes to append to the
* object. */
- size_t length) /* The number of bytes to append from "bytes".
+ Tcl_Size length) /* The number of bytes to append from "bytes".
* If TCL_INDEX_NONE, then append all bytes up to NUL
* byte. */
{
- Tcl_AppendLimitedToObj(objPtr, bytes, length, TCL_INDEX_NONE, NULL);
+ Tcl_AppendLimitedToObj(objPtr, bytes, length, TCL_SIZE_MAX, NULL);
}
/*
@@ -1337,7 +1356,7 @@ Tcl_AppendToObj(
* Tcl_AppendUnicodeToObj --
*
* This function appends a Unicode string to an object in the most
- * efficient manner possible. Length must be >= 0.
+ * efficient manner possible.
*
* Results:
* None.
@@ -1353,7 +1372,8 @@ Tcl_AppendUnicodeToObj(
Tcl_Obj *objPtr, /* Points to the object to append to. */
const Tcl_UniChar *unicode, /* The Unicode string to append to the
* object. */
- size_t length) /* Number of chars in unicode. */
+ Tcl_Size length) /* Number of chars in Unicode. Negative
+ * lengths means nul terminated */
{
String *stringPtr;
@@ -1407,8 +1427,8 @@ Tcl_AppendObjToObj(
Tcl_Obj *appendObjPtr) /* Object to append. */
{
String *stringPtr;
- size_t length = 0, numChars;
- size_t appendNumChars = TCL_INDEX_NONE;
+ Tcl_Size length = 0, numChars;
+ Tcl_Size appendNumChars = TCL_INDEX_NONE;
const char *bytes;
/*
@@ -1448,7 +1468,7 @@ Tcl_AppendObjToObj(
* First, get the lengths.
*/
- size_t lengthSrc = 0;
+ Tcl_Size lengthSrc = 0;
(void) Tcl_GetByteArrayFromObj(objPtr, &length);
(void) Tcl_GetByteArrayFromObj(appendObjPtr, &lengthSrc);
@@ -1471,7 +1491,7 @@ Tcl_AppendObjToObj(
*/
TclAppendBytesToByteArray(objPtr,
- Tcl_GetByteArrayFromObj(appendObjPtr, (size_t *)NULL), lengthSrc);
+ Tcl_GetByteArrayFromObj(appendObjPtr, (Tcl_Size *) NULL), lengthSrc);
return;
}
@@ -1520,7 +1540,7 @@ Tcl_AppendObjToObj(
bytes = Tcl_GetStringFromObj(appendObjPtr, &length);
numChars = stringPtr->numChars;
- if ((numChars != TCL_INDEX_NONE) && TclHasInternalRep(appendObjPtr, &tclStringType)) {
+ if ((numChars >= 0) && TclHasInternalRep(appendObjPtr, &tclStringType)) {
String *appendStringPtr = GET_STRING(appendObjPtr);
appendNumChars = appendStringPtr->numChars;
@@ -1528,7 +1548,7 @@ Tcl_AppendObjToObj(
AppendUtfToUtfRep(objPtr, bytes, length);
- if ((numChars != TCL_INDEX_NONE) && (appendNumChars != TCL_INDEX_NONE)) {
+ if ((numChars >= 0) && (appendNumChars >= 0)) {
stringPtr->numChars = numChars + appendNumChars;
}
}
@@ -1554,12 +1574,12 @@ static void
AppendUnicodeToUnicodeRep(
Tcl_Obj *objPtr, /* Points to the object to append to. */
const Tcl_UniChar *unicode, /* String to append. */
- size_t appendNumChars) /* Number of chars of "unicode" to append. */
+ Tcl_Size appendNumChars) /* Number of chars of "unicode" to append. */
{
String *stringPtr;
- size_t numChars;
+ Tcl_Size numChars;
- if (appendNumChars == TCL_INDEX_NONE) {
+ if (appendNumChars < 0) {
appendNumChars = UnicodeLength(unicode);
}
if (appendNumChars == 0) {
@@ -1580,7 +1600,7 @@ AppendUnicodeToUnicodeRep(
numChars = stringPtr->numChars + appendNumChars;
if (numChars > stringPtr->maxChars) {
- size_t index = TCL_INDEX_NONE;
+ Tcl_Size offset = -1;
/*
* Protect against case where Unicode points into the existing
@@ -1590,7 +1610,7 @@ AppendUnicodeToUnicodeRep(
if (unicode && unicode >= stringPtr->unicode
&& unicode <= stringPtr->unicode + stringPtr->maxChars) {
- index = unicode - stringPtr->unicode;
+ offset = unicode - stringPtr->unicode;
}
GrowUnicodeBuffer(objPtr, numChars);
@@ -1600,8 +1620,8 @@ AppendUnicodeToUnicodeRep(
* Relocate Unicode if needed; see above.
*/
- if (index != TCL_INDEX_NONE) {
- unicode = stringPtr->unicode + index;
+ if (offset >= 0) {
+ unicode = stringPtr->unicode + offset;
}
}
@@ -1642,7 +1662,7 @@ static void
AppendUnicodeToUtfRep(
Tcl_Obj *objPtr, /* Points to the object to append to. */
const Tcl_UniChar *unicode, /* String to convert to UTF. */
- size_t numChars) /* Number of chars of unicode to convert. */
+ Tcl_Size numChars) /* Number of chars of Unicode to convert. */
{
String *stringPtr = GET_STRING(objPtr);
@@ -1675,7 +1695,7 @@ static void
AppendUtfToUnicodeRep(
Tcl_Obj *objPtr, /* Points to the object to append to. */
const char *bytes, /* String to convert to Unicode. */
- size_t numBytes) /* Number of bytes of "bytes" to convert. */
+ Tcl_Size numBytes) /* Number of bytes of "bytes" to convert. */
{
String *stringPtr;
@@ -1683,7 +1703,7 @@ AppendUtfToUnicodeRep(
return;
}
- ExtendUnicodeRepWithString(objPtr, bytes, numBytes, TCL_INDEX_NONE);
+ ExtendUnicodeRepWithString(objPtr, bytes, numBytes, -1);
TclInvalidateStringRep(objPtr);
stringPtr = GET_STRING(objPtr);
stringPtr->allocated = 0;
@@ -1711,10 +1731,10 @@ static void
AppendUtfToUtfRep(
Tcl_Obj *objPtr, /* Points to the object to append to. */
const char *bytes, /* String to append. */
- size_t numBytes) /* Number of bytes of "bytes" to append. */
+ Tcl_Size numBytes) /* Number of bytes of "bytes" to append. */
{
String *stringPtr;
- size_t newLength, oldLength;
+ Tcl_Size newLength, oldLength;
if (numBytes == 0) {
return;
@@ -1729,11 +1749,14 @@ AppendUtfToUtfRep(
objPtr->length = 0;
}
oldLength = objPtr->length;
+ if (numBytes > TCL_SIZE_MAX - oldLength) {
+ Tcl_Panic("max size for a Tcl value (%" TCL_SIZE_MODIFIER "d bytes) exceeded", TCL_SIZE_MAX);
+ }
newLength = numBytes + oldLength;
stringPtr = GET_STRING(objPtr);
if (newLength > stringPtr->allocated) {
- size_t offset = TCL_INDEX_NONE;
+ Tcl_Size offset = -1;
/*
* Protect against case where unicode points into the existing
@@ -1757,7 +1780,7 @@ AppendUtfToUtfRep(
* Relocate bytes if needed; see above.
*/
- if (offset != TCL_INDEX_NONE) {
+ if (offset >= 0) {
bytes = objPtr->bytes + offset;
}
}
@@ -1766,7 +1789,7 @@ AppendUtfToUtfRep(
* Invalidate the unicode data.
*/
- stringPtr->numChars = TCL_INDEX_NONE;
+ stringPtr->numChars = -1;
stringPtr->hasUnicode = 0;
if (bytes) {
@@ -1812,7 +1835,7 @@ Tcl_AppendStringsToObj(
if (bytes == NULL) {
break;
}
- Tcl_AppendToObj(objPtr, bytes, TCL_INDEX_NONE);
+ Tcl_AppendToObj(objPtr, bytes, -1);
}
va_end(argList);
}
@@ -1842,12 +1865,12 @@ Tcl_AppendFormatToObj(
Tcl_Interp *interp,
Tcl_Obj *appendObj,
const char *format,
- size_t objc,
+ Tcl_Size objc,
Tcl_Obj *const objv[])
{
const char *span = format, *msg, *errCode;
int gotXpg = 0, gotSequential = 0;
- size_t objIndex = 0, originalLength, limit, numBytes = 0;
+ Tcl_Size objIndex = 0, originalLength, limit, numBytes = 0;
Tcl_UniChar ch = 0;
static const char *mixedXPG =
"cannot mix \"%\" and \"%n$\" conversion specifiers";
@@ -1861,7 +1884,7 @@ Tcl_AppendFormatToObj(
Tcl_Panic("%s called with shared object", "Tcl_AppendFormatToObj");
}
(void)Tcl_GetStringFromObj(appendObj, &originalLength);
- limit = (size_t)INT_MAX - originalLength;
+ limit = TCL_SIZE_MAX - originalLength;
/*
* Format string is NUL-terminated.
@@ -1870,12 +1893,13 @@ Tcl_AppendFormatToObj(
while (*format != '\0') {
char *end;
int gotMinus = 0, gotHash = 0, gotZero = 0, gotSpace = 0, gotPlus = 0;
- int width, gotPrecision, precision, sawFlag, useShort = 0, useBig = 0;
+ int gotPrecision, sawFlag, useShort = 0, useBig = 0;
+ Tcl_Size width, precision;
#ifndef TCL_WIDE_INT_IS_LONG
int useWide = 0;
#endif
- int newXpg, numChars, allocSegment = 0, segmentLimit;
- size_t segmentNumBytes;
+ int newXpg, allocSegment = 0;
+ Tcl_Size numChars, segmentLimit, segmentNumBytes;
Tcl_Obj *segment;
int step = TclUtfToUniChar(format, &ch);
@@ -1939,7 +1963,7 @@ Tcl_AppendFormatToObj(
}
gotSequential = 1;
}
- if (objIndex >= objc) {
+ if (objIndex < 0 || objIndex >= objc) {
msg = badIndex[gotXpg];
errCode = gotXpg ? "INDEXRANGE" : "FIELDVARMISMATCH";
goto errorMsg;
@@ -1996,7 +2020,7 @@ Tcl_AppendFormatToObj(
errCode = gotXpg ? "INDEXRANGE" : "FIELDVARMISMATCH";
goto errorMsg;
}
- if (TclGetIntFromObj(interp, objv[objIndex], &width) != TCL_OK) {
+ if (TclGetSizeIntFromObj(interp, objv[objIndex], &width) != TCL_OK) {
goto error;
}
if (width < 0) {
@@ -2007,7 +2031,7 @@ Tcl_AppendFormatToObj(
format += step;
step = TclUtfToUniChar(format, &ch);
}
- if (width > (int) limit) {
+ if (width > limit) {
msg = overflow;
errCode = "OVERFLOW";
goto errorMsg;
@@ -2033,7 +2057,7 @@ Tcl_AppendFormatToObj(
errCode = gotXpg ? "INDEXRANGE" : "FIELDVARMISMATCH";
goto errorMsg;
}
- if (TclGetIntFromObj(interp, objv[objIndex], &precision)
+ if (TclGetSizeIntFromObj(interp, objv[objIndex], &precision)
!= TCL_OK) {
goto error;
}
@@ -2159,7 +2183,8 @@ Tcl_AppendFormatToObj(
long l;
Tcl_WideInt w;
mp_int big;
- int toAppend, isNegative = 0;
+ int isNegative = 0;
+ Tcl_Size toAppend;
#ifndef TCL_WIDE_INT_IS_LONG
if (ch == 'p') {
@@ -2217,7 +2242,7 @@ Tcl_AppendFormatToObj(
TclNewObj(segment);
allocSegment = 1;
- segmentLimit = INT_MAX;
+ segmentLimit = TCL_SIZE_MAX;
Tcl_IncrRefCount(segment);
if ((isNegative || gotPlus || gotSpace) && (useBig || ch=='d')) {
@@ -2247,7 +2272,7 @@ Tcl_AppendFormatToObj(
switch (ch) {
case 'd': {
- size_t length;
+ Tcl_Size length;
Tcl_Obj *pure;
const char *bytes;
@@ -2282,10 +2307,10 @@ Tcl_AppendFormatToObj(
*/
if (gotPrecision) {
- if (length < (size_t)precision) {
+ if (length < precision) {
segmentLimit -= precision - length;
}
- while (length < (size_t)precision) {
+ while (length < precision) {
Tcl_AppendToObj(segment, "0", 1);
length++;
}
@@ -2293,10 +2318,10 @@ Tcl_AppendFormatToObj(
}
if (gotZero) {
length += Tcl_GetCharLength(segment);
- if (length < (size_t)width) {
+ if (length < width) {
segmentLimit -= width - length;
}
- while (length < (size_t)width) {
+ while (length < width) {
Tcl_AppendToObj(segment, "0", 1);
length++;
}
@@ -2320,7 +2345,7 @@ Tcl_AppendFormatToObj(
Tcl_WideUInt bits = 0;
Tcl_WideInt numDigits = 0;
int numBits = 4, base = 16, index = 0, shift = 0;
- size_t length;
+ Tcl_Size length;
Tcl_Obj *pure;
char *bytes;
@@ -2414,10 +2439,10 @@ Tcl_AppendFormatToObj(
mp_clear(&big);
}
if (gotPrecision) {
- if (length < (size_t)precision) {
+ if (length < precision) {
segmentLimit -= precision - length;
}
- while (length < (size_t)precision) {
+ while (length < precision) {
Tcl_AppendToObj(segment, "0", 1);
length++;
}
@@ -2425,10 +2450,10 @@ Tcl_AppendFormatToObj(
}
if (gotZero) {
length += Tcl_GetCharLength(segment);
- if (length < (size_t)width) {
+ if (length < width) {
segmentLimit -= width - length;
}
- while (length < (size_t)width) {
+ while (length < width) {
Tcl_AppendToObj(segment, "0", 1);
length++;
}
@@ -2481,15 +2506,17 @@ Tcl_AppendFormatToObj(
*p++ = '+';
}
if (width) {
- p += snprintf(p, TCL_INTEGER_SPACE, "%d", width);
+ p += snprintf(
+ p, TCL_INTEGER_SPACE, "%" TCL_SIZE_MODIFIER "d", width);
if (width > length) {
length = width;
}
}
if (gotPrecision) {
*p++ = '.';
- p += snprintf(p, TCL_INTEGER_SPACE, "%d", precision);
- if (precision > INT_MAX - length) {
+ p += snprintf(
+ p, TCL_INTEGER_SPACE, "%" TCL_SIZE_MODIFIER "d", precision);
+ if (precision > TCL_SIZE_MAX - length) {
msg = overflow;
errCode = "OVERFLOW";
goto errorMsg;
@@ -2512,7 +2539,7 @@ Tcl_AppendFormatToObj(
goto errorMsg;
}
bytes = TclGetString(segment);
- if (!Tcl_AttemptSetObjLength(segment, snprintf(bytes, segment->length, spec, d))) {
+ if (!Tcl_AttemptSetObjLength(segment, sprintf(bytes, spec, d))) {
msg = overflow;
errCode = "OVERFLOW";
goto errorMsg;
@@ -2588,7 +2615,7 @@ Tcl_AppendFormatToObj(
errorMsg:
if (interp != NULL) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(msg, TCL_INDEX_NONE));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(msg, -1));
Tcl_SetErrorCode(interp, "TCL", "FORMAT", errCode, NULL);
}
error:
@@ -2614,7 +2641,7 @@ Tcl_Obj *
Tcl_Format(
Tcl_Interp *interp,
const char *format,
- size_t objc,
+ Tcl_Size objc,
Tcl_Obj *const objv[])
{
int result;
@@ -2648,7 +2675,7 @@ AppendPrintfToObjVA(
va_list argList)
{
int code;
- size_t objc;
+ Tcl_Size objc;
Tcl_Obj **objv, *list;
const char *p;
@@ -2895,7 +2922,7 @@ Tcl_ObjPrintf(
char *
TclGetStringStorage(
Tcl_Obj *objPtr,
- size_t *sizePtr)
+ Tcl_Size *sizePtr)
{
String *stringPtr;
@@ -2929,14 +2956,16 @@ Tcl_Obj *
TclStringRepeat(
Tcl_Interp *interp,
Tcl_Obj *objPtr,
- size_t count,
+ Tcl_Size count,
int flags)
{
Tcl_Obj *objResultPtr;
int inPlace = flags & TCL_STRING_IN_PLACE;
- size_t length = 0, unichar = 0, done = 1;
+ Tcl_Size length = 0;
+ int unichar = 0;
+ Tcl_Size done = 1;
int binary = TclIsPureByteArray(objPtr);
- size_t maxCount;
+ Tcl_Size maxCount;
/* assert (count >= 2) */
@@ -2959,15 +2988,15 @@ TclStringRepeat(
if (binary) {
/* Result will be pure byte array. Pre-size it */
(void)Tcl_GetByteArrayFromObj(objPtr, &length);
- maxCount = TCL_SIZE_SMAX;
+ maxCount = TCL_SIZE_MAX;
} else if (unichar) {
/* Result will be pure Tcl_UniChar array. Pre-size it. */
(void)Tcl_GetUnicodeFromObj(objPtr, &length);
- maxCount = TCL_SIZE_SMAX/sizeof(Tcl_UniChar);
+ maxCount = TCL_SIZE_MAX/sizeof(Tcl_UniChar);
} else {
/* Result will be concat of string reps. Pre-size it. */
(void)Tcl_GetStringFromObj(objPtr, &length);
- maxCount = TCL_SIZE_SMAX;
+ maxCount = TCL_SIZE_MAX;
}
if (length == 0) {
@@ -2980,9 +3009,9 @@ TclStringRepeat(
if (interp) {
Tcl_SetObjResult(
interp,
- Tcl_ObjPrintf("max size for a Tcl value (%" TCL_Z_MODIFIER
- "u bytes) exceeded",
- TCL_SIZE_SMAX));
+ Tcl_ObjPrintf("max size for a Tcl value (%" TCL_SIZE_MODIFIER
+ "d bytes) exceeded",
+ TCL_SIZE_MAX));
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
}
return NULL;
@@ -3001,7 +3030,7 @@ TclStringRepeat(
done *= 2;
}
TclAppendBytesToByteArray(objResultPtr,
- Tcl_GetByteArrayFromObj(objResultPtr, (size_t *)NULL),
+ Tcl_GetByteArrayFromObj(objResultPtr, (Tcl_Size *) NULL),
(count - done) * length);
} else if (unichar) {
/*
@@ -3015,11 +3044,12 @@ TclStringRepeat(
objResultPtr = objPtr;
}
+ /* TODO - overflow check */
if (0 == Tcl_AttemptSetObjLength(objResultPtr, count*length)) {
if (interp) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"string size overflow: unable to alloc %"
- TCL_Z_MODIFIER "u bytes",
+ TCL_SIZE_MODIFIER "d bytes",
STRING_SIZE(count*length)));
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
}
@@ -3043,10 +3073,11 @@ TclStringRepeat(
TclFreeInternalRep(objPtr);
objResultPtr = objPtr;
}
+ /* TODO - overflow check */
if (0 == Tcl_AttemptSetObjLength(objResultPtr, count*length)) {
if (interp) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "string size overflow: unable to alloc %" TCL_Z_MODIFIER "u bytes",
+ "string size overflow: unable to alloc %" TCL_SIZE_MODIFIER "d bytes",
count*length));
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
}
@@ -3090,7 +3121,7 @@ TclStringCat(
{
Tcl_Obj *objResultPtr, * const *ov;
int oc, binary = 1;
- size_t length = 0;
+ Tcl_Size length = 0;
int allowUniChar = 1, requestUniChar = 0, forceUniChar = 0;
int first = objc - 1; /* Index of first value possibly not empty */
int last = 0; /* Index of last value possibly not empty */
@@ -3152,7 +3183,7 @@ TclStringCat(
* Result will be pure byte array. Pre-size it
*/
- size_t numBytes = 0;
+ Tcl_Size numBytes = 0;
ov = objv;
oc = objc;
do {
@@ -3172,7 +3203,7 @@ TclStringCat(
if (length == 0) {
first = last;
}
- if (length > (TCL_SIZE_SMAX-numBytes)) {
+ if (length > (TCL_SIZE_MAX-numBytes)) {
goto overflow;
}
length += numBytes;
@@ -3190,7 +3221,7 @@ TclStringCat(
Tcl_Obj *objPtr = *ov++;
if ((objPtr->bytes == NULL) || (objPtr->length)) {
- size_t numChars;
+ Tcl_Size numChars;
(void)Tcl_GetUnicodeFromObj(objPtr, &numChars); /* PANIC? */
if (numChars) {
@@ -3198,7 +3229,7 @@ TclStringCat(
if (length == 0) {
first = last;
}
- if (length > ((TCL_SIZE_SMAX/sizeof(Tcl_UniChar))-numChars)) {
+ if (length > (Tcl_Size) ((TCL_SIZE_MAX/sizeof(Tcl_UniChar))-numChars)) {
goto overflow;
}
length += numChars;
@@ -3240,7 +3271,7 @@ TclStringCat(
first = last = objc - oc - 1;
if (oc && (length == 0)) {
- size_t numBytes;
+ Tcl_Size numBytes;
/* assert ( pendingPtr != NULL ) */
@@ -3265,7 +3296,7 @@ TclStringCat(
if (numBytes) {
first = last;
}
- } else if (numBytes > (TCL_SIZE_SMAX - length)) {
+ } else if (numBytes > (TCL_SIZE_MAX - length)) {
goto overflow;
}
length += numBytes;
@@ -3273,7 +3304,7 @@ TclStringCat(
} while (oc && (length == 0));
while (oc) {
- size_t numBytes;
+ Tcl_Size numBytes;
Tcl_Obj *objPtr = *ov++;
/* assert ( length > 0 && pendingPtr == NULL ) */
@@ -3282,7 +3313,7 @@ TclStringCat(
numBytes = objPtr->length;
if (numBytes) {
last = objc - oc;
- if (numBytes > (TCL_SIZE_SMAX - length)) {
+ if (numBytes > (TCL_SIZE_MAX - length)) {
goto overflow;
}
length += numBytes;
@@ -3309,7 +3340,7 @@ TclStringCat(
*/
if (inPlace && !Tcl_IsShared(*objv)) {
- size_t start = 0;
+ Tcl_Size start = 0;
objResultPtr = *objv++; objc--;
(void)Tcl_GetByteArrayFromObj(objResultPtr, &start);
@@ -3328,7 +3359,7 @@ TclStringCat(
*/
if (TclIsPureByteArray(objPtr)) {
- size_t more = 0;
+ Tcl_Size more = 0;
unsigned char *src = Tcl_GetByteArrayFromObj(objPtr, &more);
memcpy(dst, src, more);
dst += more;
@@ -3339,7 +3370,7 @@ TclStringCat(
Tcl_UniChar *dst;
if (inPlace && !Tcl_IsShared(*objv)) {
- size_t start;
+ Tcl_Size start;
objResultPtr = *objv++; objc--;
@@ -3379,7 +3410,7 @@ TclStringCat(
Tcl_Obj *objPtr = *objv++;
if ((objPtr->bytes == NULL) || (objPtr->length)) {
- size_t more;
+ Tcl_Size more;
Tcl_UniChar *src = Tcl_GetUnicodeFromObj(objPtr, &more);
memcpy(dst, src, more * sizeof(Tcl_UniChar));
dst += more;
@@ -3390,7 +3421,7 @@ TclStringCat(
char *dst;
if (inPlace && !Tcl_IsShared(*objv)) {
- size_t start;
+ Tcl_Size start;
objResultPtr = *objv++; objc--;
@@ -3426,7 +3457,7 @@ TclStringCat(
Tcl_Obj *objPtr = *objv++;
if ((objPtr->bytes == NULL) || (objPtr->length)) {
- size_t more;
+ Tcl_Size more;
char *src = Tcl_GetStringFromObj(objPtr, &more);
memcpy(dst, src, more);
@@ -3441,7 +3472,7 @@ TclStringCat(
overflow:
if (interp) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "max size for a Tcl value (%" TCL_Z_MODIFIER "u bytes) exceeded", TCL_SIZE_SMAX));
+ "max size for a Tcl value (%" TCL_SIZE_MODIFIER "d bytes) exceeded", TCL_SIZE_MAX));
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
}
return NULL;
@@ -3469,12 +3500,12 @@ TclStringCmp(
Tcl_Obj *value2Ptr,
int checkEq, /* comparison is only for equality */
int nocase, /* comparison is not case sensitive */
- size_t reqlength) /* requested length in characters;
+ Tcl_Size reqlength) /* requested length in characters;
* TCL_INDEX_NONE to compare whole strings */
{
const char *s1, *s2;
int empty, match;
- size_t length, s1len = 0, s2len = 0;
+ Tcl_Size length, s1len = 0, s2len = 0;
memCmpFn_t memCmpFn;
if ((reqlength == 0) || (value1Ptr == value2Ptr)) {
@@ -3663,14 +3694,14 @@ Tcl_Obj *
TclStringFirst(
Tcl_Obj *needle,
Tcl_Obj *haystack,
- size_t start)
+ Tcl_Size start)
{
- size_t lh = 0, ln = Tcl_GetCharLength(needle);
- size_t value = TCL_INDEX_NONE;
+ Tcl_Size lh = 0, ln = Tcl_GetCharLength(needle);
+ Tcl_Size value = -1;
Tcl_UniChar *checkStr, *endStr, *uh, *un;
Tcl_Obj *obj;
- if (start == TCL_INDEX_NONE) {
+ if (start < 0) {
start = 0;
}
if (ln == 0) {
@@ -3770,10 +3801,10 @@ Tcl_Obj *
TclStringLast(
Tcl_Obj *needle,
Tcl_Obj *haystack,
- size_t last)
+ Tcl_Size last)
{
- size_t lh = 0, ln = Tcl_GetCharLength(needle);
- size_t value = TCL_INDEX_NONE;
+ Tcl_Size lh = 0, ln = Tcl_GetCharLength(needle);
+ Tcl_Size value = -1;
Tcl_UniChar *checkStr, *uh, *un;
Tcl_Obj *obj;
@@ -3791,7 +3822,7 @@ TclStringLast(
unsigned char *check, *bh = Tcl_GetByteArrayFromObj(haystack, &lh);
unsigned char *bn = Tcl_GetByteArrayFromObj(needle, &ln);
- if (last + 1 >= lh + 1) {
+ if (last >= lh) {
last = lh - 1;
}
if (last + 1 < ln) {
@@ -3814,7 +3845,7 @@ TclStringLast(
uh = Tcl_GetUnicodeFromObj(haystack, &lh);
un = Tcl_GetUnicodeFromObj(needle, &ln);
- if (last + 1 >= lh + 1) {
+ if (last >= lh) {
last = lh - 1;
}
if (last + 1 < ln) {
@@ -3857,7 +3888,7 @@ static void
ReverseBytes(
unsigned char *to, /* Copy bytes into here... */
unsigned char *from, /* ...from here... */
- size_t count) /* Until this many are copied, */
+ Tcl_Size count) /* Until this many are copied, */
/* reversing as you go. */
{
unsigned char *src = from + count;
@@ -3890,13 +3921,13 @@ TclStringReverse(
#endif
if (TclIsPureByteArray(objPtr)) {
- size_t numBytes = 0;
+ Tcl_Size numBytes = 0;
unsigned char *from = Tcl_GetByteArrayFromObj(objPtr, &numBytes);
if (!inPlace || Tcl_IsShared(objPtr)) {
objPtr = Tcl_NewByteArrayObj(NULL, numBytes);
}
- ReverseBytes(Tcl_GetByteArrayFromObj(objPtr, (size_t *)NULL), from, numBytes);
+ ReverseBytes(Tcl_GetByteArrayFromObj(objPtr, (Tcl_Size *)NULL), from, numBytes);
return objPtr;
}
@@ -3971,8 +4002,8 @@ TclStringReverse(
}
if (objPtr->bytes) {
- size_t numChars = stringPtr->numChars;
- size_t numBytes = objPtr->length;
+ Tcl_Size numChars = stringPtr->numChars;
+ Tcl_Size numBytes = objPtr->length;
char *to, *from = objPtr->bytes;
if (!inPlace || Tcl_IsShared(objPtr)) {
@@ -3981,7 +4012,7 @@ TclStringReverse(
}
to = objPtr->bytes;
- if ((numChars == TCL_INDEX_NONE) || (numChars < numBytes)) {
+ if (numChars < numBytes) {
/*
* Either numChars == -1 and we don't know how many chars are
* represented by objPtr->bytes and we need Pass 1 just in case,
@@ -3991,7 +4022,7 @@ TclStringReverse(
* Pass 1. Reverse the bytes of each multi-byte character.
*/
- size_t bytesLeft = numBytes;
+ Tcl_Size bytesLeft = numBytes;
int chw;
while (bytesLeft) {
@@ -4001,7 +4032,7 @@ TclStringReverse(
* skip calling Tcl_UtfCharComplete() here.
*/
- size_t bytesInChar = TclUtfToUCS4(from, &chw);
+ int bytesInChar = TclUtfToUCS4(from, &chw);
ReverseBytes((unsigned char *)to, (unsigned char *)from,
bytesInChar);
@@ -4049,8 +4080,8 @@ Tcl_Obj *
TclStringReplace(
Tcl_Interp *interp, /* For error reporting, may be NULL */
Tcl_Obj *objPtr, /* String to act upon */
- size_t first, /* First index to replace */
- size_t count, /* How many chars to replace */
+ Tcl_Size first, /* First index to replace */
+ Tcl_Size count, /* How many chars to replace */
Tcl_Obj *insertPtr, /* Replacement string, may be NULL */
int flags) /* TCL_STRING_IN_PLACE => attempt in-place */
{
@@ -4058,13 +4089,16 @@ TclStringReplace(
Tcl_Obj *result;
/* Replace nothing with nothing */
- if ((insertPtr == NULL) && (count == 0)) {
+ if ((insertPtr == NULL) && (count <= 0)) {
if (inPlace) {
return objPtr;
} else {
return Tcl_DuplicateObj(objPtr);
}
}
+ if (first < 0) {
+ first = 0;
+ }
/*
* The caller very likely had to call Tcl_GetCharLength() or similar
@@ -4074,7 +4108,7 @@ TclStringReplace(
*/
if (TclIsPureByteArray(objPtr)) {
- size_t numBytes = 0;
+ Tcl_Size numBytes = 0;
unsigned char *bytes = Tcl_GetByteArrayFromObj(objPtr, &numBytes);
if (insertPtr == NULL) {
@@ -4097,7 +4131,7 @@ TclStringReplace(
}
if (TclIsPureByteArray(insertPtr)) {
- size_t newBytes = 0;
+ Tcl_Size newBytes = 0;
unsigned char *iBytes
= Tcl_GetByteArrayFromObj(insertPtr, &newBytes);
@@ -4112,11 +4146,11 @@ TclStringReplace(
return objPtr;
}
- if (newBytes > (TCL_SIZE_SMAX - (numBytes - count))) {
+ if (newBytes > (TCL_SIZE_MAX - (numBytes - count))) {
if (interp) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "max size for a Tcl value (%" TCL_Z_MODIFIER "u bytes) exceeded",
- TCL_SIZE_SMAX));
+ "max size for a Tcl value (%" TCL_SIZE_MODIFIER "d bytes) exceeded",
+ TCL_SIZE_MAX));
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
}
return NULL;
@@ -4142,7 +4176,7 @@ TclStringReplace(
/* The traditional implementation... */
{
- size_t numChars;
+ Tcl_Size numChars;
Tcl_UniChar *ustring = Tcl_GetUnicodeFromObj(objPtr, &numChars);
/* TODO: Is there an in-place option worth pursuing here? */
@@ -4192,11 +4226,11 @@ static void
ExtendUnicodeRepWithString(
Tcl_Obj *objPtr,
const char *bytes,
- size_t numBytes,
- size_t numAppendChars)
+ Tcl_Size numBytes,
+ Tcl_Size numAppendChars)
{
String *stringPtr = GET_STRING(objPtr);
- size_t needed, numOrigChars = 0;
+ Tcl_Size needed, numOrigChars = 0;
Tcl_UniChar *dst, unichar = 0;
if (stringPtr->hasUnicode) {
@@ -4394,21 +4428,21 @@ UpdateStringOfString(
}
}
-static size_t
+static Tcl_Size
ExtendStringRepWithUnicode(
Tcl_Obj *objPtr,
const Tcl_UniChar *unicode,
- size_t numChars)
+ Tcl_Size numChars)
{
/*
* Precondition: this is the "string" Tcl_ObjType.
*/
- size_t i, origLength, size = 0;
+ Tcl_Size i, origLength, size = 0;
char *dst;
String *stringPtr = GET_STRING(objPtr);
- if (numChars == TCL_INDEX_NONE) {
+ if (numChars < 0) {
numChars = UnicodeLength(unicode);
}
@@ -4425,14 +4459,18 @@ ExtendStringRepWithUnicode(
* Quick cheap check in case we have more than enough room.
*/
- if (numChars <= (INT_MAX - size)/TCL_UTF_MAX
+ if (numChars <= (TCL_SIZE_MAX - size)/TCL_UTF_MAX
&& stringPtr->allocated >= size + numChars * TCL_UTF_MAX) {
goto copyBytes;
}
- for (i = 0; i < numChars; i++) {
+ for (i = 0; i < numChars && size >= 0; i++) {
+ /* TODO - overflow check! I don't think check below at end suffices */
size += TclUtfCount(unicode[i]);
}
+ if (size < 0) {
+ Tcl_Panic("max size for a Tcl value (%" TCL_SIZE_MODIFIER "d bytes) exceeded", TCL_SIZE_MAX);
+ }
/*
* Grow space if needed.