From 523ea309ce99ee289cf8bea083fbc10f7d0f5320 Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 25 Jan 2019 13:43:59 +0000 Subject: Do not assume that literals have a non-NULL bytes field; user code could purge it. --- generic/tclLiteral.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/generic/tclLiteral.c b/generic/tclLiteral.c index fb7c28a..b6c45ac 100644 --- a/generic/tclLiteral.c +++ b/generic/tclLiteral.c @@ -198,25 +198,36 @@ TclCreateLiteral( for (globalPtr=globalTablePtr->buckets[globalHash] ; globalPtr!=NULL; globalPtr = globalPtr->nextPtr) { objPtr = globalPtr->objPtr; - if ((globalPtr->nsPtr == nsPtr) - && (objPtr->length == length) && ((length == 0) - || ((objPtr->bytes[0] == bytes[0]) - && (memcmp(objPtr->bytes, bytes, (unsigned) length) == 0)))) { + if (globalPtr->nsPtr == nsPtr) { /* - * A literal was found: return it + * Literals should always have UTF-8 representations... but this + * is not guaranteed so we need to be careful anyway. + * + * https://stackoverflow.com/q/54337750/301832 */ - if (newPtr) { - *newPtr = 0; - } - if (globalPtrPtr) { - *globalPtrPtr = globalPtr; - } - if (flags & LITERAL_ON_HEAP) { - ckfree(bytes); + int objLength; + char *objBytes = TclGetStringFromObj(objPtr, &objLength); + + if ((objLength == length) && ((length == 0) + || ((objBytes[0] == bytes[0]) + && (memcmp(objBytes, bytes, (unsigned) length) == 0)))) { + /* + * A literal was found: return it + */ + + if (newPtr) { + *newPtr = 0; + } + if (globalPtrPtr) { + *globalPtrPtr = globalPtr; + } + if (flags & LITERAL_ON_HEAP) { + ckfree(bytes); + } + globalPtr->refCount++; + return objPtr; } - globalPtr->refCount++; - return objPtr; } } if (!newPtr) { -- cgit v0.12