diff options
author | jan.nijtmans <jan.nijtmans@noemail.net> | 2012-01-25 21:13:39 (GMT) |
---|---|---|
committer | jan.nijtmans <jan.nijtmans@noemail.net> | 2012-01-25 21:13:39 (GMT) |
commit | 4d325e70b2e37e1771966dbdc775bad03f256f2e (patch) | |
tree | eecb0149dc58d041678d5df28192820f1ff55ae1 /generic | |
parent | 03fa9e7e0a8b13dca004d849d33a4fbc85b518f0 (diff) | |
parent | 3a5fb2b854a0295800e3b01287b5c5e04a3c3edf (diff) | |
download | tk-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.c | 32 | ||||
-rw-r--r-- | generic/tkTextMark.c | 25 |
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; } |