summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorfvogel <fvogel@noemail.net>2012-01-31 22:24:11 (GMT)
committerfvogel <fvogel@noemail.net>2012-01-31 22:24:11 (GMT)
commit0a90b7349c87edae79c18fe8cac946d9cdfab966 (patch)
tree1f9ca7098989620146558e0736d079e2bad9d81f /generic
parenta69d2cc51d6f0f7df371c26072d91b7f8b9c3b99 (diff)
downloadtk-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.c43
-rw-r--r--generic/tkTextBTree.c11
-rw-r--r--generic/tkTextDisp.c32
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) {