summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorjan.nijtmans <jan.nijtmans@noemail.net>2012-01-25 21:13:39 (GMT)
committerjan.nijtmans <jan.nijtmans@noemail.net>2012-01-25 21:13:39 (GMT)
commit4d325e70b2e37e1771966dbdc775bad03f256f2e (patch)
treeeecb0149dc58d041678d5df28192820f1ff55ae1 /generic
parent03fa9e7e0a8b13dca004d849d33a4fbc85b518f0 (diff)
parent3a5fb2b854a0295800e3b01287b5c5e04a3c3edf (diff)
downloadtk-4d325e70b2e37e1771966dbdc775bad03f256f2e.zip
tk-4d325e70b2e37e1771966dbdc775bad03f256f2e.tar.gz
tk-4d325e70b2e37e1771966dbdc775bad03f256f2e.tar.bz2
[Bug-1630271]: segfault/infinite loop when a mark is before -startline
FossilOrigin-Name: 61a3685ac23ed100671a4a52590a3a26dcb72a6f
Diffstat (limited to 'generic')
-rw-r--r--generic/tkText.c32
-rw-r--r--generic/tkTextMark.c25
2 files changed, 54 insertions, 3 deletions
diff --git a/generic/tkText.c b/generic/tkText.c
index 6b42489..76051da 100644
--- a/generic/tkText.c
+++ b/generic/tkText.c
@@ -2022,6 +2022,7 @@ ConfigureText(
if (mask & TK_TEXT_LINE_RANGE) {
int start, end, current;
+ TkTextIndex index1, index2, index3;
/*
* Line start and/or end have been adjusted. We need to validate the
@@ -2048,13 +2049,15 @@ ConfigureText(
return TCL_ERROR;
}
current = TkBTreeLinesTo(NULL, textPtr->topIndex.linePtr);
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, start, 0,
+ &index1);
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, end, 0,
+ &index2);
if (current < start || current > end) {
TkTextSearch search;
- TkTextIndex index1, first, last;
+ TkTextIndex first, last;
int selChanged = 0;
- TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, start, 0,
- &index1);
TkTextSetYView(textPtr, &index1, 0);
/*
@@ -2098,6 +2101,29 @@ ConfigureText(
textPtr->abortSelections = 1;
}
}
+
+ /* Indices are potentially obsolete after changing -startline and/or
+ * -endline, therefore increase the epoch.
+ * Also, clamp the insert and current (unshared) marks to the new
+ * -startline/-endline range limits of the widget. All other (shared)
+ * marks are unchanged.
+ */
+
+ textPtr->sharedTextPtr->stateEpoch++;
+ TkTextMarkNameToIndex(textPtr, "insert", &index3);
+ if (TkTextIndexCmp(&index3, &index1) < 0) {
+ textPtr->insertMarkPtr = TkTextSetMark(textPtr, "insert", &index1);
+ }
+ if (TkTextIndexCmp(&index3, &index2) > 0) {
+ textPtr->insertMarkPtr = TkTextSetMark(textPtr, "insert", &index2);
+ }
+ TkTextMarkNameToIndex(textPtr, "current", &index3);
+ if (TkTextIndexCmp(&index3, &index1) < 0) {
+ textPtr->currentMarkPtr = TkTextSetMark(textPtr, "current", &index1);
+ }
+ if (TkTextIndexCmp(&index3, &index2) > 0) {
+ textPtr->currentMarkPtr = TkTextSetMark(textPtr, "current", &index2);
+ }
textPtr->sharedTextPtr->stateEpoch++;
}
diff --git a/generic/tkTextMark.c b/generic/tkTextMark.c
index 55edb46..0e51e33 100644
--- a/generic/tkTextMark.c
+++ b/generic/tkTextMark.c
@@ -402,6 +402,8 @@ TkTextMarkNameToIndex(
TkTextIndex *indexPtr) /* Index information gets stored here. */
{
TkTextSegment *segPtr;
+ TkTextIndex index;
+ int start, end;
if (textPtr == NULL) {
return TCL_ERROR;
@@ -420,6 +422,29 @@ TkTextMarkNameToIndex(
segPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr);
}
TkTextMarkSegToIndex(textPtr, segPtr, indexPtr);
+
+ /* If indexPtr refers to somewhere outside the -startline/-endline
+ * range limits of the widget, error out since the mark indeed is not
+ * reachable from this text widget (it may be reachable from a peer)
+ * (bug 1630271).
+ */
+
+ if (textPtr->start != NULL) {
+ start = TkBTreeLinesTo(NULL, textPtr->start);
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, start, 0,
+ &index);
+ if (TkTextIndexCmp(indexPtr, &index) < 0) {
+ return TCL_ERROR;
+ }
+ }
+ if (textPtr->end != NULL) {
+ end = TkBTreeLinesTo(NULL, textPtr->end);
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, end, 0,
+ &index);
+ if (TkTextIndexCmp(indexPtr, &index) > 0) {
+ return TCL_ERROR;
+ }
+ }
return TCL_OK;
}