diff options
| author | dkf <donal.k.fellows@manchester.ac.uk> | 2019-01-25 13:43:59 (GMT) |
|---|---|---|
| committer | dkf <donal.k.fellows@manchester.ac.uk> | 2019-01-25 13:43:59 (GMT) |
| commit | 523ea309ce99ee289cf8bea083fbc10f7d0f5320 (patch) | |
| tree | 8c7cd51ad05fb516ed256ffea26e8d0e4d968ca1 | |
| parent | b4745088b1dad2c57d04048297da3e302f3bf011 (diff) | |
| download | tcl-523ea309ce99ee289cf8bea083fbc10f7d0f5320.zip tcl-523ea309ce99ee289cf8bea083fbc10f7d0f5320.tar.gz tcl-523ea309ce99ee289cf8bea083fbc10f7d0f5320.tar.bz2 | |
Do not assume that literals have a non-NULL bytes field; user code could purge it.
| -rw-r--r-- | generic/tclLiteral.c | 41 |
1 files 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) { |
