diff options
author | fvogel <fvogel@noemail.net> | 2012-01-31 22:24:11 (GMT) |
---|---|---|
committer | fvogel <fvogel@noemail.net> | 2012-01-31 22:24:11 (GMT) |
commit | 0a90b7349c87edae79c18fe8cac946d9cdfab966 (patch) | |
tree | 1f9ca7098989620146558e0736d079e2bad9d81f /generic | |
parent | a69d2cc51d6f0f7df371c26072d91b7f8b9c3b99 (diff) | |
download | tk-0a90b7349c87edae79c18fe8cac946d9cdfab966.zip tk-0a90b7349c87edae79c18fe8cac946d9cdfab966.tar.gz tk-0a90b7349c87edae79c18fe8cac946d9cdfab966.tar.bz2 |
[Bug-1630262]: segfault when deleting lines with peer text widgets
FossilOrigin-Name: abca82f488b9f1f85a98b24afee698ad1d2be6d9
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tkText.c | 43 | ||||
-rw-r--r-- | generic/tkTextBTree.c | 11 | ||||
-rw-r--r-- | generic/tkTextDisp.c | 32 |
3 files changed, 79 insertions, 7 deletions
diff --git a/generic/tkText.c b/generic/tkText.c index d050170..18cbcf4 100644 --- a/generic/tkText.c +++ b/generic/tkText.c @@ -3097,6 +3097,11 @@ DeleteIndexRange( resetView = 1; line = line1; byteIndex = tPtr->topIndex.byteIndex; + } else { + /* + * Deletion range starts after the top line. This peers's view + * will not need to be reset. Nothing to do. + */ } } else if (index2.linePtr == tPtr->topIndex.linePtr) { /* @@ -3113,6 +3118,11 @@ DeleteIndexRange( } else { byteIndex -= (index2.byteIndex - index1.byteIndex); } + } else { + /* + * Deletion range ends before the top line. This peers's view + * will not need to be reset. Nothing to do. + */ } if (resetView) { lineAndByteIndex[resetViewCount] = line; @@ -3157,14 +3167,43 @@ DeleteIndexRange( TkTextIndex indexTmp; if (tPtr == textPtr) { - if (viewUpdate) { + if (viewUpdate) { + /* + * line cannot be before -startline of textPtr because + * this line corresponds to an index which is necessarily + * between "1.0" and "end" relative to textPtr. + * Therefore no need to clamp line to the -start/-end + * range. + */ + TkTextMakeByteIndex(sharedTextPtr->tree, textPtr, line, byteIndex, &indexTmp); TkTextSetYView(tPtr, &indexTmp, 0); } } else { - TkTextMakeByteIndex(sharedTextPtr->tree, NULL, line, + TkTextMakeByteIndex(sharedTextPtr->tree, tPtr, line, byteIndex, &indexTmp); + /* + * line may be before -startline of tPtr and must be + * clamped to -startline before providing it to + * TkTextSetYView otherwise lines before -startline + * would be displayed. + * There is no need to worry about -endline however, + * because the view will only be reset if the deletion + * involves the TOP line of the screen + */ + + if (tPtr->start != NULL) { + int start; + TkTextIndex indexStart; + + start = TkBTreeLinesTo(NULL, tPtr->start); + TkTextMakeByteIndex(sharedTextPtr->tree, NULL, start, + 0, &indexStart); + if (TkTextIndexCmp(&indexTmp, &indexStart) < 0) { + indexTmp = indexStart; + } + } TkTextSetYView(tPtr, &indexTmp, 0); } } diff --git a/generic/tkTextBTree.c b/generic/tkTextBTree.c index 0038e64..005ce46 100644 --- a/generic/tkTextBTree.c +++ b/generic/tkTextBTree.c @@ -662,12 +662,12 @@ AdjustStartEndRefs( if (textPtr->start != NULL) { count--; treePtr->startEnd[count] = textPtr->start; - treePtr->startEndRef[count] = treePtr->sharedTextPtr->peers; + treePtr->startEndRef[count] = textPtr; } if (textPtr->end != NULL) { count--; treePtr->startEnd[count] = textPtr->end; - treePtr->startEndRef[count] = treePtr->sharedTextPtr->peers; + treePtr->startEndRef[count] = textPtr; } } } @@ -1609,7 +1609,7 @@ TkBTreeFindLine( } /* - * Check for the any start/end offset for this text widget. + * Check for any start/end offset for this text widget. */ if (textPtr != NULL) { @@ -1993,6 +1993,11 @@ TkBTreeLinesTo( } if (textPtr != NULL && textPtr->start != NULL) { index -= TkBTreeLinesTo(NULL, textPtr->start); + if (index < 0) { + /* One should panic here! + Tcl_Panic("TkBTreeLinesTo: linePtr comes before -startline"); + */ + } } return index; } diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c index 5f30b11..f674b75 100644 --- a/generic/tkTextDisp.c +++ b/generic/tkTextDisp.c @@ -3219,6 +3219,34 @@ TextInvalidateLineMetrics( int fromLine; TextDInfo *dInfoPtr = textPtr->dInfoPtr; + /* + * All lines to invalidate must be inside the -startline/-endline range. + */ + + if (linePtr != NULL) { + int start; + TkTextLine *toLinePtr; + if (textPtr->start != NULL) { + fromLine = TkBTreeLinesTo(NULL, linePtr); + start = TkBTreeLinesTo(NULL, textPtr->start); + if (fromLine < start) { + lineCount -= start - fromLine; + linePtr = textPtr->start; + } + } + if (textPtr->end != NULL) { + int count = 0; + toLinePtr = linePtr; + while (count < lineCount && toLinePtr != NULL) { + toLinePtr = TkBTreeNextLine(textPtr, toLinePtr); + count++; + } + if (toLinePtr == NULL) { + lineCount = count; + } + } + } + if (linePtr != NULL) { int counter = lineCount; @@ -3229,7 +3257,7 @@ TextInvalidateLineMetrics( */ TkBTreeLinePixelEpoch(textPtr, linePtr) = 0; - while (counter > 0 && linePtr != 0) { + while (counter > 0 && linePtr != NULL) { linePtr = TkBTreeNextLine(textPtr, linePtr); if (linePtr != NULL) { TkBTreeLinePixelEpoch(textPtr, linePtr) = 0; @@ -3244,7 +3272,7 @@ TextInvalidateLineMetrics( * more lines than is strictly necessary (but the examination of the * extra lines should be quick, since their pixelCalculationEpoch will * be up to date). However, to keep track of that would require more - * complex record-keeping that what we have. + * complex record-keeping than what we have. */ if (dInfoPtr->lineUpdateTimer == NULL) { |