summaryrefslogtreecommitdiffstats
path: root/generic/tclListObj.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclListObj.c')
-rw-r--r--generic/tclListObj.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/generic/tclListObj.c b/generic/tclListObj.c
index e83a8f4..2c5c4d4 100644
--- a/generic/tclListObj.c
+++ b/generic/tclListObj.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclListObj.c,v 1.27 2005/09/06 14:40:11 dkf Exp $
+ * RCS: @(#) $Id: tclListObj.c,v 1.28 2005/10/20 12:21:44 msofer Exp $
*/
#include "tclInt.h"
@@ -1112,12 +1112,21 @@ TclLsetFlat(interp, listPtr, indexCount, indexArray, valuePtr)
}
/*
- * If the list is shared, make a private copy.
+ * If the list is shared, make a private copy. Duplicate the intrep to
+ * insure that it is modifyable [Bug 1333036]. A plain Tcl_DuplicateObj
+ * will just increase the intrep's refCount without upping the sublists'
+ * refCount, so that their true shared status cannot be determined from
+ * their refCount.
*/
if (Tcl_IsShared(listPtr)) {
duplicated = 1;
- listPtr = Tcl_DuplicateObj(listPtr);
+ if (listPtr->typePtr == &tclListType) {
+ result = Tcl_ListObjGetElements(interp, listPtr, &elemCount, &elemPtrs);
+ listPtr = Tcl_NewListObj(elemCount, elemPtrs);
+ } else {
+ listPtr = Tcl_DuplicateObj(listPtr);
+ }
Tcl_IncrRefCount(listPtr);
} else {
duplicated = 0;
@@ -1182,12 +1191,20 @@ TclLsetFlat(interp, listPtr, indexCount, indexArray, valuePtr)
}
/*
- * Extract the appropriate sublist, and make sure that it is unshared.
+ * Extract the appropriate sublist, and make sure that it is unshared.
+ * If it is a list, duplicate the intrep to avoid [Bug 1333036], as
+ * per the previous comment.
*/
subListPtr = elemPtrs[index];
if (Tcl_IsShared(subListPtr)) {
- subListPtr = Tcl_DuplicateObj(subListPtr);
+ if (subListPtr->typePtr == &tclListType) {
+ result = Tcl_ListObjGetElements(interp, subListPtr, &elemCount,
+ &elemPtrs);
+ subListPtr = Tcl_NewListObj(elemCount, elemPtrs);
+ } else {
+ subListPtr = Tcl_DuplicateObj(subListPtr);
+ }
result = TclListObjSetElement(interp, listPtr, index, subListPtr);
if (result != TCL_OK) {
/*