summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorfvogel <fvogel@noemail.net>2012-02-28 20:44:34 (GMT)
committerfvogel <fvogel@noemail.net>2012-02-28 20:44:34 (GMT)
commit11523555ded4c18418df1c1e0610dd5389984f5a (patch)
treed62de6938569517afd6274d9096c99eadec78078 /generic
parentc35176f814ffa709f3e2b939a3a13c0b62978d89 (diff)
parentd40a24882f0decaebb6acb6dfb2ca3b30379aabc (diff)
downloadtk-11523555ded4c18418df1c1e0610dd5389984f5a.zip
tk-11523555ded4c18418df1c1e0610dd5389984f5a.tar.gz
tk-11523555ded4c18418df1c1e0610dd5389984f5a.tar.bz2
[Bug-1630262], [Bug-1615425]: segfault when deleting lines or tagging outside of the -startline/-endline range with peer text widgets. [Bug-3487407]: Weird text indices.
FossilOrigin-Name: 5528cb094a83ae9ef719e4084d6b321ab347ead5
Diffstat (limited to 'generic')
-rw-r--r--generic/tkText.c47
-rw-r--r--generic/tkTextBTree.c37
-rw-r--r--generic/tkTextDisp.c6
-rw-r--r--generic/tkTextMark.c28
4 files changed, 101 insertions, 17 deletions
diff --git a/generic/tkText.c b/generic/tkText.c
index 98720d3..d1f489d 100644
--- a/generic/tkText.c
+++ b/generic/tkText.c
@@ -2119,6 +2119,10 @@ ConfigureText(
* Also, clamp the insert and current (unshared) marks to the new
* -startline/-endline range limits of the widget. All other (shared)
* marks are unchanged.
+ * The return value of TkTextMarkNameToIndex does not need to be
+ * checked: "insert" and "current" marks always exist, and the
+ * purpose of the code below precisely is to move them inside the
+ * -startline/-endline range.
*/
textPtr->sharedTextPtr->stateEpoch++;
@@ -3105,6 +3109,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) {
/*
@@ -3121,6 +3130,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;
@@ -3165,14 +3179,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 572c623..e34dae7 100644
--- a/generic/tkTextBTree.c
+++ b/generic/tkTextBTree.c
@@ -658,12 +658,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;
}
}
}
@@ -1606,7 +1606,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) {
@@ -1988,12 +1988,37 @@ TkBTreeLinesTo(
index += nodePtr2->numLines;
}
}
- if (textPtr != NULL && textPtr->start != NULL) {
- index -= TkBTreeLinesTo(NULL, textPtr->start);
+ if (textPtr != NULL) {
+ /*
+ * The index to return must be relative to textPtr, not to the entire
+ * tree. Take care to never return a negative index when linePtr
+ * denotes a line before -startline, or an index larger than the
+ * number of lines in textPtr when linePtr is a line past -endline.
+ */
+
+ int indexStart, indexEnd;
+
+ if (textPtr->start != NULL) {
+ indexStart = TkBTreeLinesTo(NULL, textPtr->start);
+ } else {
+ indexStart = 0;
+ }
+ if (textPtr->end != NULL) {
+ indexEnd = TkBTreeLinesTo(NULL, textPtr->end);
+ } else {
+ indexEnd = TkBTreeNumLines(textPtr->sharedTextPtr->tree, NULL);
+ }
+ if (index < indexStart) {
+ index = 0;
+ } else if (index > indexEnd) {
+ index = TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr);
+ } else {
+ index -= indexStart;
+ }
}
return index;
}
-
+
/*
*----------------------------------------------------------------------
*
diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c
index 249f476..b3d94ec 100644
--- a/generic/tkTextDisp.c
+++ b/generic/tkTextDisp.c
@@ -1972,7 +1972,7 @@ UpdateDisplayInfo(
if (spaceLeft <= dInfoPtr->newTopPixelOffset) {
/*
- * We can full up all the needed space just by showing more of the
+ * We can fill up all the needed space just by showing more of the
* current top line.
*/
@@ -3231,7 +3231,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;
@@ -3246,7 +3246,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) {
diff --git a/generic/tkTextMark.c b/generic/tkTextMark.c
index 9729449..76ab1a9 100644
--- a/generic/tkTextMark.c
+++ b/generic/tkTextMark.c
@@ -286,6 +286,7 @@ TkTextSetMark(
if (markPtr == textPtr->insertMarkPtr) {
TkTextIndex index, index2;
+ int nblines;
TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index);
TkTextIndexForwChars(NULL, &index, 1, &index2, COUNT_INDICES);
@@ -296,9 +297,18 @@ TkTextSetMark(
*/
TkTextChanged(NULL, textPtr, &index, &index2);
- if (TkBTreeLinesTo(textPtr, indexPtr->linePtr) ==
- TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr)) {
- TkTextIndexBackChars(NULL, indexPtr, 1, &insertIndex,
+
+ /*
+ * The number of lines in the widget is zero if and only if it is
+ * a partial peer with -startline == -endline, i.e. an empty
+ * peer. In this case the mark shall be set exactly at the given
+ * index, and not one character backwards (bug 3487407).
+ */
+
+ nblines = TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr);
+ if ((TkBTreeLinesTo(textPtr, indexPtr->linePtr) == nblines)
+ && (nblines > 0)) {
+ TkTextIndexBackChars(NULL,indexPtr, 1, &insertIndex,
COUNT_INDICES);
indexPtr = &insertIndex;
}
@@ -386,9 +396,15 @@ TkTextMarkSegToIndex(
*
* Results:
* The return value is TCL_OK if "name" exists as a mark in the text
- * widget. In this case *indexPtr is filled in with the next segment
- * whose after the mark whose size is non-zero. TCL_ERROR is returned if
- * the mark doesn't exist in the text widget.
+ * widget and is located within its -starline/-endline range. In this
+ * case *indexPtr is filled in with the next segment who is after the
+ * mark whose size is non-zero. TCL_ERROR is returned if the mark
+ * doesn't exist in the text widget, or if it is out of its -starline/
+ * -endline range. In this latter case *indexPtr still contains valid
+ * information, in particular TkTextMarkNameToIndex called with the
+ * "insert" or "current" mark name may return TCL_ERROR, but *indexPtr
+ * contains the correct index of this mark before -startline or after
+ * -endline.
*
* Side effects:
* None.