summaryrefslogtreecommitdiffstats
path: root/generic/tclListObj.c
diff options
context:
space:
mode:
authorMiguel Sofer <miguel.sofer@gmail.com>2005-10-20 12:21:43 (GMT)
committerMiguel Sofer <miguel.sofer@gmail.com>2005-10-20 12:21:43 (GMT)
commit1d7b878a5cc101b9dab71fc0041c7c6bcd18e3f5 (patch)
tree142f7dd620b40e8168ca34cef822e5c4576d8484 /generic/tclListObj.c
parent21b328fdbad15a78e6f77c80092e7bab72f42ae7 (diff)
downloadtcl-1d7b878a5cc101b9dab71fc0041c7c6bcd18e3f5.zip
tcl-1d7b878a5cc101b9dab71fc0041c7c6bcd18e3f5.tar.gz
tcl-1d7b878a5cc101b9dab71fc0041c7c6bcd18e3f5.tar.bz2
* generic/tclListObj.c (TclLsetFlat):
* tests/lset.test (lset-10.3): fixed handling of unshared lists with shared sublists, [Bug 1333036] reported by neuronstorm.
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) {
/*