Tk Source Code

Check-in [30db605b]
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 | trunk
Files: files | file ages | folders
SHA1: 30db605b7660d9698c206f95975c8a3f70702bf4
User & Date: jan.nijtmans 2012-01-25 21:14:19
Context
2012-01-25
21:35
Don't increase the epoch twice. check-in: 16d8b47d user: fvogel tags: trunk
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:43
patch 3476698: Patch for failing test text-31.11 check-in: b50f5f57 user: jan.nijtmans tags: trunk
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.

2030
2031
2032
2033
2034
2035
2036

2037
2038
2039
2040
2041
2042
2043
     * 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);







>







2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
     * 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);
2056
2057
2058
2059
2060
2061
2062




2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
	    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.
	     */







>
>
>
>


|


<
<







2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072


2073
2074
2075
2076
2077
2078
2079
	    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.
	     */
2106
2107
2108
2109
2110
2111
2112























2113
2114
2115
2116
2117
2118
2119
		 * partial-selections in progress.
		 */

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























        textPtr->sharedTextPtr->stateEpoch++;
    }

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








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







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
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
		 * 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.

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
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 =
		Tcl_FindHashEntry(&textPtr->sharedTextPtr->markTable, name);

	if (hPtr == NULL) {
	    return TCL_ERROR;
	}
	segPtr = Tcl_GetHashValue(hPtr);
    }
    TkTextMarkSegToIndex(textPtr, segPtr, indexPtr);























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







>
>



















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







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
455
456
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 =
		Tcl_FindHashEntry(&textPtr->sharedTextPtr->markTable, name);

	if (hPtr == NULL) {
	    return TCL_ERROR;
	}
	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;
}

/*
 *--------------------------------------------------------------
 *
 * MarkDeleteProc --

Changes to tests/textMark.test.

137
138
139
140
141
142
143


































144
145
146
147
148
149
150
test textMark-6.1 {TkTextMarkSegToIndex} -body {
    .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]
} -result {1.2 1.2 1.2 1.4}



































test textMark-7.1 {MarkFindNext - invalid mark name} -body {
    .t mark next bogus
} -returnCodes error -result {bad text index "bogus"}
test textMark-7.2 {MarkFindNext - marks at same location} -body {
    .t mark set insert 2.0
    .t mark set current 2.0







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







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
180
181
182
183
184
test textMark-6.1 {TkTextMarkSegToIndex} -body {
    .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]
} -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
} -returnCodes error -result {bad text index "bogus"}
test textMark-7.2 {MarkFindNext - marks at same location} -body {
    .t mark set insert 2.0
    .t mark set current 2.0
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
    .t mark set insert 3.0
    .t mark next insert
} -result {}
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} -body {
    .t mark prev bogus
} -returnCodes error -result {bad text index "bogus"}
test textMark-8.2 {MarkFindPrev - marks at same location} -body {
    .t mark set insert 2.0
    .t mark set current 2.0







|
|







223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
    .t mark set insert 3.0
    .t mark next insert
} -result {}
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} -body {
    .t mark prev bogus
} -returnCodes error -result {bad text index "bogus"}
test textMark-8.2 {MarkFindPrev - marks at same location} -body {
    .t mark set insert 2.0
    .t mark set current 2.0
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
    .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}

destroy .pt
destroy .t

# cleanup
cleanupTests
return

# Local Variables:
# mode: tcl
# End:







|












280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
    .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}

destroy .pt
destroy .t

# cleanup
cleanupTests
return

# Local Variables:
# mode: tcl
# End: