summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2019-01-25 14:17:56 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2019-01-25 14:17:56 (GMT)
commitd53b2ae83f6ba7aa37755dda0d38ff034c0c0ebd (patch)
tree3f53fd17cdbc1883aa3f01eb98a25cdb3a66eca0
parent4a9e46ab99089e0c1b6824078a5a460fd7529709 (diff)
parent5f4d72886372eacd51d78f6431e812a978dae48f (diff)
downloadtcl-d53b2ae83f6ba7aa37755dda0d38ff034c0c0ebd.zip
tcl-d53b2ae83f6ba7aa37755dda0d38ff034c0c0ebd.tar.gz
tcl-d53b2ae83f6ba7aa37755dda0d38ff034c0c0ebd.tar.bz2
Do not assume that literals have a non-NULL bytes field; user code could purge it.
-rw-r--r--generic/tclLiteral.c41
1 files changed, 26 insertions, 15 deletions
diff --git a/generic/tclLiteral.c b/generic/tclLiteral.c
index 003884d..577c9e5 100644
--- a/generic/tclLiteral.c
+++ b/generic/tclLiteral.c
@@ -200,25 +200,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) {