Tk Source Code

Check-in [61a3685a]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:[Bug-1630271]: segfault/infinite loop when a mark is before -startline
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | core-8-5-branch
Files: files | file ages | folders
SHA1: 61a3685ac23ed100671a4a52590a3a26dcb72a6f
User & Date: jan.nijtmans 2012-01-25 21:13:39
Context
2012-01-25
21:33
Don't increase the epoch twice. check-in: a26d55ff user: fvogel tags: core-8-5-branch
21:14
[Bug-1630271]: segfault/infinite loop when a mark is before -startline check-in: 30db605b user: jan.nijtmans tags: trunk
21:13
[Bug-1630271]: segfault/infinite loop when a mark is before -startline check-in: 61a3685a user: jan.nijtmans tags: core-8-5-branch
05:42
patch 3476698: Patch for failing test text-31.11 check-in: 193eb89c user: jan.nijtmans tags: core-8-5-branch
2012-01-23
20:56
patch-3477449: segfault when mark out of -startline/-endline range Closed-Leaf check-in: 45f3f06d user: jan.nijtmans tags: bug-1630271
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ChangeLog.







1
2
3
4
5
6
7






2012-01-25  Francois Vogel  <[email protected]>

	* generic/tkText.c: [Bug-3475627]: Test text-31.11 fails

2012-01-22  Francois Vogel  <[email protected]>

	* generic/tkTextMark.c: [Bug-3288113,3288121]: Missing marks/endless 
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
2012-01-25  Francois Vogel  <[email protected]>

	* 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  <[email protected]>

	* generic/tkText.c: [Bug-3475627]: Test text-31.11 fails

2012-01-22  Francois Vogel  <[email protected]>

	* generic/tkTextMark.c: [Bug-3288113,3288121]: Missing marks/endless 

Changes to generic/tkText.c.

2018
2019
2020
2021
2022
2023
2024

2025
2026
2027
2028
2029
2030
2031
     * geometry and setting the background from a 3-D border.
     */

    Tk_SetBackgroundFromBorder(textPtr->tkwin, textPtr->border);

    if (mask & TK_TEXT_LINE_RANGE) {
	int start, end, current;


	/*
	 * Line start and/or end have been adjusted. We need to validate the
	 * first displayed line and arrange for re-layout.
	 */

	TkBTreeClientRangeChanged(textPtr, textPtr->charHeight);







>







2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
     * geometry and setting the background from a 3-D border.
     */

    Tk_SetBackgroundFromBorder(textPtr->tkwin, textPtr->border);

    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
	 * first displayed line and arrange for re-layout.
	 */

	TkBTreeClientRangeChanged(textPtr, textPtr->charHeight);
2044
2045
2046
2047
2048
2049
2050




2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
	    Tcl_AppendResult(interp,
		    "-startline must be less than or equal to -endline",
		    NULL);
	    Tk_RestoreSavedOptions(&savedOptions);
	    return TCL_ERROR;
	}
	current = TkBTreeLinesTo(NULL, textPtr->topIndex.linePtr);




	if (current < start || current > end) {
	    TkTextSearch search;
	    TkTextIndex index1, first, last;
	    int selChanged = 0;

	    TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, start, 0,
		    &index1);
	    TkTextSetYView(textPtr, &index1, 0);

	    /*
	     * We may need to adjust the selection. So we have to check
	     * whether the "sel" tag was applied to anything outside the
	     * current start,end.
	     */







>
>
>
>


|


<
<







2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060


2061
2062
2063
2064
2065
2066
2067
	    Tcl_AppendResult(interp,
		    "-startline must be less than or equal to -endline",
		    NULL);
	    Tk_RestoreSavedOptions(&savedOptions);
	    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 first, last;
	    int selChanged = 0;



	    TkTextSetYView(textPtr, &index1, 0);

	    /*
	     * We may need to adjust the selection. So we have to check
	     * whether the "sel" tag was applied to anything outside the
	     * current start,end.
	     */
2094
2095
2096
2097
2098
2099
2100























2101
2102
2103
2104
2105
2106
2107
		 * partial-selections in progress.
		 */

		TkTextSelectionEvent(textPtr);
		textPtr->abortSelections = 1;
	    }
	}























        textPtr->sharedTextPtr->stateEpoch++;
    }

    /*
     * Don't allow negative spacings.
     */








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
		 * partial-selections in progress.
		 */

		TkTextSelectionEvent(textPtr);
		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++;
    }

    /*
     * Don't allow negative spacings.
     */

Changes to generic/tkTextMark.c.

398
399
400
401
402
403
404


405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422























423
424
425
426
427
428
429
int
TkTextMarkNameToIndex(
    TkText *textPtr,		/* Text widget containing mark. */
    const char *name,		/* Name of mark. */
    TkTextIndex *indexPtr)	/* Index information gets stored here. */
{
    TkTextSegment *segPtr;



    if (textPtr == NULL) {
        return TCL_ERROR;
    }

    if (!strcmp(name, "insert")) {
	segPtr = textPtr->insertMarkPtr;
    } else if (!strcmp(name, "current")) {
	segPtr = textPtr->currentMarkPtr;
    } else {
	Tcl_HashEntry *hPtr;
	hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->markTable, name);
	if (hPtr == NULL) {
	    return TCL_ERROR;
	}
	segPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr);
    }
    TkTextMarkSegToIndex(textPtr, segPtr, indexPtr);























    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * MarkDeleteProc --







>
>


















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
int
TkTextMarkNameToIndex(
    TkText *textPtr,		/* Text widget containing mark. */
    const char *name,		/* Name of mark. */
    TkTextIndex *indexPtr)	/* Index information gets stored here. */
{
    TkTextSegment *segPtr;
    TkTextIndex index;
    int start, end;

    if (textPtr == NULL) {
        return TCL_ERROR;
    }

    if (!strcmp(name, "insert")) {
	segPtr = textPtr->insertMarkPtr;
    } else if (!strcmp(name, "current")) {
	segPtr = textPtr->currentMarkPtr;
    } else {
	Tcl_HashEntry *hPtr;
	hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->markTable, name);
	if (hPtr == NULL) {
	    return TCL_ERROR;
	}
	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;
}

/*
 *--------------------------------------------------------------
 *
 * MarkDeleteProc --

Changes to tests/textMark.test.

132
133
134
135
136
137
138


































139
140
141
142
143
144
145
test textMark-6.1 {TkTextMarkSegToIndex} haveCourier12 {
    .t mark set a 1.2
    .t mark set b 1.2
    .t mark set c 1.2
    .t mark set d 1.4
    list [.t index a] [.t index b] [.t index c ] [.t index d]
} {1.2 1.2 1.2 1.4}



































catch {eval {.t mark unset} [.t mark names]}
test textMark-7.1 {MarkFindNext - invalid mark name} haveCourier12 {
    catch {.t mark next bogus} x
    set x
} {bad text index "bogus"}
test textMark-7.2 {MarkFindNext - marks at same location} haveCourier12 {







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
test textMark-6.1 {TkTextMarkSegToIndex} haveCourier12 {
    .t mark set a 1.2
    .t mark set b 1.2
    .t mark set c 1.2
    .t mark set d 1.4
    list [.t index a] [.t index b] [.t index c ] [.t index d]
} {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"}}

catch {eval {.t mark unset} [.t mark names]}
test textMark-7.1 {MarkFindNext - invalid mark name} haveCourier12 {
    catch {.t mark next bogus} x
    set x
} {bad text index "bogus"}
test textMark-7.2 {MarkFindNext - marks at same location} haveCourier12 {
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
    .t mark set insert 3.0
    .t mark next insert
} {}
test textMark-7.9 {MarkFindNext - mark set in a text widget and retrieved from a peer} -setup {
    .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}

test textMark-8.1 {MarkFindPrev - invalid mark name} -constraints haveCourier12 -setup {
    .t mark unset {*}[.t mark names]
} -body {
    catch {.t mark prev bogus} x
    set x
} -result {bad text index "bogus"}







|
|







210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
    .t mark set insert 3.0
    .t mark next insert
} {}
test textMark-7.9 {MarkFindNext - mark set in a text widget and retrieved from a peer} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set mymark 1.0
    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} -constraints haveCourier12 -setup {
    .t mark unset {*}[.t mark names]
} -body {
    catch {.t mark prev bogus} x
    set x
} -result {bad text index "bogus"}
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
    .t mark set insert 3.0
    .t mark prev current
} -result {}
test textMark-8.9 {MarkFindPrev - mark set in a text widget and retrieved from a peer} -setup {
    .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]]
} -result {current insert mymark}

catch {destroy .t}
catch {destroy .pt}

# cleanup
cleanupTests
return







|








272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
    .t mark set insert 3.0
    .t mark prev current
} -result {}
test textMark-8.9 {MarkFindPrev - mark set in a text widget and retrieved from a peer} -setup {
    .t mark unset {*}[.t mark names]
} -body {
    .t mark set mymark 1.0
    lsort [list [.pt mark prev end] [.pt mark prev current] [.pt mark prev insert]]
} -result {current insert mymark}

catch {destroy .t}
catch {destroy .pt}

# cleanup
cleanupTests
return