From 52875fedbaf361884d806f4c695114bb457a5f6f Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 11 Dec 2007 22:14:57 +0000 Subject: Added code to rebuild the from index after the deletion phase so that the linePtr field is valid for the insertion phase. [Bug 1602537] --- ChangeLog | 6 ++++++ generic/tkText.c | 30 ++++++++++++++++++++---------- tests/text.test | 11 ++++++++++- 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 + + * 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 * 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 -- cgit v0.12