summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--generic/tkText.c32
-rw-r--r--generic/tkTextMark.c25
-rw-r--r--tests/textMark.test40
4 files changed, 97 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 109dd2d..4a594bb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2012-01-25 Francois Vogel <fvogelnew1@free.fr>
+ * generic/tkText.c: [Bug-1630271]: segfault/infinite loop
+ * generic/tkTextMark.c: when a mark is before -startline
+ * tests/textMark.test:
+
+2012-01-25 Francois Vogel <fvogelnew1@free.fr>
+
* generic/tkText.c: [Bug-3475627]: Test text-31.11 fails
2012-01-22 Francois Vogel <fvogelnew1@free.fr>
diff --git a/generic/tkText.c b/generic/tkText.c
index fe358b6..9e14de9 100644
--- a/generic/tkText.c
+++ b/generic/tkText.c
@@ -2034,6 +2034,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
@@ -2060,13 +2061,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);
/*
@@ -2110,6 +2113,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 6117127..026ca33 100644
--- a/generic/tkTextMark.c
+++ b/generic/tkTextMark.c
@@ -403,6 +403,8 @@ TkTextMarkNameToIndex(
TkTextIndex *indexPtr) /* Index information gets stored here. */
{
TkTextSegment *segPtr;
+ TkTextIndex index;
+ int start, end;
if (textPtr == NULL) {
return TCL_ERROR;
@@ -422,6 +424,29 @@ TkTextMarkNameToIndex(
segPtr = 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;
}
diff --git a/tests/textMark.test b/tests/textMark.test
index a412574..6e0f8a0 100644
--- a/tests/textMark.test
+++ b/tests/textMark.test
@@ -141,6 +141,40 @@ test textMark-6.1 {TkTextMarkSegToIndex} -body {
.t mark set d 1.4
list [.t index a] [.t index b] [.t index c ] [.t index d]
} -result {1.2 1.2 1.2 1.4}
+test textMark-6.2 {TkTextMarkNameToIndex, with mark outside -startline/-endline range - bug 1630271} -body {
+ .t mark set insert 1.0
+ .t configure -startline 2
+ set res [list [.t index insert] [.t index insert-1c] [.t get insert]]
+ .t mark set insert end
+ .t configure -endline 4
+ lappend res [.t index insert]
+} -cleanup {
+ .t configure -startline {} -endline {}
+} -result {1.0 1.0 a 2.5}
+test textMark-6.3 {TkTextMarkNameToIndex, with mark outside -startline/-endline range - bug 1630271} -body {
+ .t mark set mymark 1.0
+ .t configure -startline 2
+ list [catch {.t index mymark} msg] $msg
+} -cleanup {
+ .t configure -startline {} -endline {}
+ .t mark unset mymark
+} -result {1 {bad text index "mymark"}}
+test textMark-6.4 {TkTextMarkNameToIndex, with mark outside -startline/-endline range - bug 1630271} -body {
+ .t mark set mymark 1.0
+ .t configure -startline 2
+ set res [list [catch {.t index mymark} msg] $msg]
+ lappend res [.pt index mymark]
+ .t configure -startline {}
+ .pt configure -startline 4
+ lappend res [.t index mymark]
+ lappend res [catch {.pt index mymark} msg] $msg
+ lappend res [.t get mymark]
+ lappend res [catch {.pt get mymark} msg] $msg
+} -cleanup {
+ .t configure -startline {} -endline {}
+ .pt configure -startline {} -endline {}
+ .t mark unset mymark
+} -result {1 {bad text index "mymark"} 1.0 1.0 1 {bad text index "mymark"} L 1 {bad text index "mymark"}}
test textMark-7.1 {MarkFindNext - invalid mark name} -body {
.t mark next bogus
@@ -193,8 +227,8 @@ test textMark-7.9 {MarkFindNext - mark set in a text widget and retrieved from a
.t mark unset {*}[.t mark names]
} -body {
.t mark set mymark 1.0
- set res [list [.pt mark next 1.0] [.pt mark next mymark] [.pt mark next insert]]
-} -result {mymark insert current}
+ lsort [list [.pt mark next 1.0] [.pt mark next mymark] [.pt mark next insert]]
+} -result {current insert mymark}
test textMark-8.1 {MarkFindPrev - invalid mark name} -body {
.t mark prev bogus
@@ -250,7 +284,7 @@ test textMark-8.9 {MarkFindPrev - mark set in a text widget and retrieved from a
.t mark unset {*}[.t mark names]
} -body {
.t mark set mymark 1.0
- set res [list [.pt mark prev end] [.pt mark prev current] [.pt mark prev insert]]
+ lsort [list [.pt mark prev end] [.pt mark prev current] [.pt mark prev insert]]
} -result {current insert mymark}
destroy .pt