summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2007-03-09 16:40:17 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2007-03-09 16:40:17 (GMT)
commit5810f3ae6446903fadc9860d8ba2c24515a448b3 (patch)
tree1df01fdc89f5c4aad4ca08ce188e0a2ea9a5b651 /generic
parent8f5385f1339e582fc7a451a31f304c8e2e290130 (diff)
downloadtcl-5810f3ae6446903fadc9860d8ba2c24515a448b3.zip
tcl-5810f3ae6446903fadc9860d8ba2c24515a448b3.tar.gz
tcl-5810f3ae6446903fadc9860d8ba2c24515a448b3.tar.bz2
Fix [Bug 1675116]
Diffstat (limited to 'generic')
-rw-r--r--generic/tclCmdIL.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c
index 18de024..e71f043 100644
--- a/generic/tclCmdIL.c
+++ b/generic/tclCmdIL.c
@@ -16,7 +16,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclCmdIL.c,v 1.108 2007/03/08 11:19:32 dkf Exp $
+ * RCS: @(#) $Id: tclCmdIL.c,v 1.109 2007/03/09 16:40:21 dkf Exp $
*/
#include "tclInt.h"
@@ -3862,12 +3862,9 @@ Tcl_LsortObjCmd(
int objc, /* Number of arguments. */
Tcl_Obj *CONST objv[]) /* Argument values. */
{
- int i, index, unique, indices;
- Tcl_Obj *resultPtr;
- int length;
- Tcl_Obj *cmdPtr, **listObjPtrs;
- SortElement *elementArray;
- SortElement *elementPtr;
+ int i, index, unique, indices, length;
+ Tcl_Obj *resultPtr, *cmdPtr, **listObjPtrs, *listObj;
+ SortElement *elementArray, *elementPtr;
SortInfo sortInfo; /* Information about this sort that needs to
* be passed to the comparison function. */
static CONST char *switches[] = {
@@ -4001,6 +3998,7 @@ Tcl_LsortObjCmd(
break;
}
}
+ listObj = objv[objc-1];
if (sortInfo.sortMode == SORTMODE_COMMAND) {
/*
@@ -4024,9 +4022,18 @@ Tcl_LsortObjCmd(
}
Tcl_ListObjAppendElement(interp, newCommandPtr, Tcl_NewObj());
sortInfo.compareCmdPtr = newCommandPtr;
+
+ /*
+ * When sorting using a command, we are reentrant and therefore might
+ * have the representation of the list being sorted shimmered out from
+ * underneath our feet. Take a copy (cheap) to prevent this. [Bug
+ * 1675116]
+ */
+
+ listObj = Tcl_DuplicateObj(listObj);
}
- sortInfo.resultCode = Tcl_ListObjGetElements(interp, objv[objc-1],
+ sortInfo.resultCode = Tcl_ListObjGetElements(interp, listObj,
&length, &listObjPtrs);
if (sortInfo.resultCode != TCL_OK || length <= 0) {
goto done;
@@ -4045,27 +4052,26 @@ Tcl_LsortObjCmd(
if (indices) {
for (; elementPtr != NULL ; elementPtr = elementPtr->nextPtr){
if (elementPtr->count == 0) {
- Tcl_ListObjAppendElement(interp, resultPtr,
+ Tcl_ListObjAppendElement(NULL, resultPtr,
Tcl_NewIntObj(elementPtr - &elementArray[0]));
}
}
} else {
for (; elementPtr != NULL; elementPtr = elementPtr->nextPtr) {
if (elementPtr->count == 0) {
- Tcl_ListObjAppendElement(interp, resultPtr,
+ Tcl_ListObjAppendElement(NULL, resultPtr,
elementPtr->objPtr);
}
}
}
} else if (indices) {
for (; elementPtr != NULL ; elementPtr = elementPtr->nextPtr) {
- Tcl_ListObjAppendElement(interp, resultPtr,
+ Tcl_ListObjAppendElement(NULL, resultPtr,
Tcl_NewIntObj(elementPtr - &elementArray[0]));
}
} else {
for (; elementPtr != NULL; elementPtr = elementPtr->nextPtr) {
- Tcl_ListObjAppendElement(interp, resultPtr,
- elementPtr->objPtr);
+ Tcl_ListObjAppendElement(NULL, resultPtr, elementPtr->objPtr);
}
}
Tcl_SetObjResult(interp, resultPtr);
@@ -4075,6 +4081,7 @@ Tcl_LsortObjCmd(
done:
if (sortInfo.sortMode == SORTMODE_COMMAND) {
Tcl_DecrRefCount(sortInfo.compareCmdPtr);
+ Tcl_DecrRefCount(listObj);
sortInfo.compareCmdPtr = NULL;
}
if (sortInfo.indexc > 1) {