summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--generic/tkText.c30
-rw-r--r--tests/text.test11
3 files changed, 36 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index d4d1a14..4a89d0c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2007-12-11 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tkText.c (TextReplaceCmd): Added code to rebuild the from
+ index after the deletion phase so that the linePtr field is valid for
+ the insertion phase. [Bug 1602537]
+
2007-12-10 Donal K. Fellows <dkf@users.sf.net>
* doc/event.n: Clarify the fact that [event info] only returns the
diff --git a/generic/tkText.c b/generic/tkText.c
index 5c18277..ac40ac5 100644
--- a/generic/tkText.c
+++ b/generic/tkText.c
@@ -13,7 +13,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkText.c,v 1.76 2007/09/07 00:34:54 dgp Exp $
+ * RCS: @(#) $Id: tkText.c,v 1.77 2007/12/11 22:14:58 dkf Exp $
*/
#include "default.h"
@@ -1726,7 +1726,8 @@ TextReplaceCmd(
*/
int origAutoSep = textPtr->sharedTextPtr->autoSeparators;
- int result;
+ int result, lineNumber;
+ TkTextIndex indexTmp;
if (textPtr->sharedTextPtr->undo) {
textPtr->sharedTextPtr->autoSeparators = 0;
@@ -1736,9 +1737,18 @@ TextReplaceCmd(
}
}
+ /*
+ * Must save and restore line in indexFromPtr based on line number; can't
+ * keep the line itself as that might be eliminated/invalidated when
+ * deleting the range. [Bug 1602537]
+ */
+
+ indexTmp = *indexFromPtr;
+ lineNumber = TkBTreeLinesTo(textPtr, indexFromPtr->linePtr);
DeleteIndexRange(NULL, textPtr, indexFromPtr, indexToPtr, viewUpdate);
+ indexTmp.linePtr = TkBTreeFindLine(indexTmp.tree, textPtr, lineNumber);
result = TextInsertCmd(NULL, textPtr, interp, objc-4, objv+4,
- indexFromPtr, viewUpdate);
+ &indexTmp, viewUpdate);
if (textPtr->sharedTextPtr->undo) {
textPtr->sharedTextPtr->lastEditMode = TK_TEXT_EDIT_REPLACE;
@@ -3101,7 +3111,7 @@ DeleteIndexRange(
Tcl_Obj *get;
if (sharedTextPtr->autoSeparators
- && (sharedTextPtr->lastEditMode != TK_TEXT_EDIT_DELETE)) {
+ && (sharedTextPtr->lastEditMode != TK_TEXT_EDIT_DELETE)) {
TkUndoInsertUndoSeparator(sharedTextPtr->undoStack);
}
@@ -3123,17 +3133,18 @@ DeleteIndexRange(
if (line != -1) {
int byteIndex = lineAndByteIndex[resetViewCount+1];
+ TkTextIndex indexTmp;
if (tPtr == textPtr) {
if (viewUpdate) {
TkTextMakeByteIndex(sharedTextPtr->tree, textPtr, line,
- byteIndex, &index1);
- TkTextSetYView(tPtr, &index1, 0);
+ byteIndex, &indexTmp);
+ TkTextSetYView(tPtr, &indexTmp, 0);
}
} else {
- TkTextMakeByteIndex(sharedTextPtr->tree, NULL, line, byteIndex,
- &index1);
- TkTextSetYView(tPtr, &index1, 0);
+ TkTextMakeByteIndex(sharedTextPtr->tree, NULL, line,
+ byteIndex, &indexTmp);
+ TkTextSetYView(tPtr, &indexTmp, 0);
}
}
resetViewCount += 2;
@@ -3143,7 +3154,6 @@ DeleteIndexRange(
}
if (line1 >= line2) {
-
/*
* Invalidate any selection retrievals in progress, assuming we didn't
* check for this case above.
diff --git a/tests/text.test b/tests/text.test
index e115d43..6306373 100644
--- a/tests/text.test
+++ b/tests/text.test
@@ -6,7 +6,7 @@
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.
#
-# RCS: @(#) $Id: text.test,v 1.46 2006/10/17 10:21:50 patthoyts Exp $
+# RCS: @(#) $Id: text.test,v 1.47 2007/12/11 22:14:58 dkf Exp $
package require tcltest 2.1
eval tcltest::configure $argv
@@ -423,6 +423,15 @@ test text-8.24 {TextWidgetCmd procedure, "replace" option with peers, undo} {
lappend res 1
}
} {foo 0 1}
+test text-8.25 {TextWidgetCmd procedure, "replace" option crash} -setup {
+ destroy .tt
+} -body {
+ text .tt
+ .tt insert 0.0 foo\n
+ .tt replace end-1l end bar
+} -cleanup {
+ destroy .tt
+} -result {}
.t delete 1.0 end; .t insert 1.0 $prevtext