summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2012-04-09 21:38:27 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2012-04-09 21:38:27 (GMT)
commitba795792d6185008b4de5f9c0463f26fa2ddab0a (patch)
treebbf70e95747797972530e153c0ffee4c8c954486 /generic
parent4d8a945fc474dc4d42a6c0903f3eb2e0b62bd9a4 (diff)
downloadtcl-ba795792d6185008b4de5f9c0463f26fa2ddab0a.zip
tcl-ba795792d6185008b4de5f9c0463f26fa2ddab0a.tar.gz
tcl-ba795792d6185008b4de5f9c0463f26fa2ddab0a.tar.bz2
Fix [Bug 3396896]
Diffstat (limited to 'generic')
-rw-r--r--generic/tclOODefineCmds.c52
1 files changed, 47 insertions, 5 deletions
diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c
index 926966b..3d72690 100644
--- a/generic/tclOODefineCmds.c
+++ b/generic/tclOODefineCmds.c
@@ -2306,11 +2306,32 @@ ClassVarsSet(
ckalloc(sizeof(Tcl_Obj *) * varc);
}
}
+
+ oPtr->classPtr->variables.num = 0;
if (varc > 0) {
- memcpy(oPtr->classPtr->variables.list, varv,
- sizeof(Tcl_Obj *) * varc);
+ int created, n;
+ Tcl_HashTable uniqueTable;
+
+ Tcl_InitObjHashTable(&uniqueTable);
+ for (i=n=0 ; i<varc ; i++) {
+ Tcl_CreateHashEntry(&uniqueTable, varv[i], &created);
+ if (created) {
+ oPtr->classPtr->variables.list[n++] = varv[i];
+ } else {
+ Tcl_DecrRefCount(varv[i]);
+ }
+ }
+ oPtr->classPtr->variables.num = n;
+
+ /*
+ * Shouldn't be necessary, but maintain num/list invariant.
+ */
+
+ oPtr->classPtr->variables.list = (Tcl_Obj **)
+ ckrealloc((char *) oPtr->classPtr->variables.list,
+ sizeof(Tcl_Obj *) * n);
+ Tcl_DeleteHashTable(&uniqueTable);
}
- oPtr->classPtr->variables.num = varc;
return TCL_OK;
}
@@ -2563,10 +2584,31 @@ ObjVarsSet(
ckalloc(sizeof(Tcl_Obj *) * varc);
}
}
+ oPtr->variables.num = 0;
if (varc > 0) {
- memcpy(oPtr->variables.list, varv, sizeof(Tcl_Obj *)*varc);
+ int created, n;
+ Tcl_HashTable uniqueTable;
+
+ Tcl_InitObjHashTable(&uniqueTable);
+ for (i=n=0 ; i<varc ; i++) {
+ Tcl_CreateHashEntry(&uniqueTable, varv[i], &created);
+ if (created) {
+ oPtr->variables.list[n++] = varv[i];
+ } else {
+ Tcl_DecrRefCount(varv[i]);
+ }
+ }
+ oPtr->variables.num = n;
+
+ /*
+ * Shouldn't be necessary, but maintain num/list invariant.
+ */
+
+ oPtr->variables.list = (Tcl_Obj **)
+ ckrealloc((char *) oPtr->variables.list,
+ sizeof(Tcl_Obj *) * n);
+ Tcl_DeleteHashTable(&uniqueTable);
}
- oPtr->variables.num = varc;
return TCL_OK;
}