Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | [Bug-1630262]: segfault when deleting lines with peer text widgets |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | bug-1630262 |
Files: | files | file ages | folders |
SHA1: |
abca82f488b9f1f85a98b24afee698ad |
User & Date: | fvogel 2012-01-31 22:24:11 |
Context
2012-02-02
| ||
10:40 | Better fix for bug-1630262, also fixing bug-1615425 check-in: 1cb7c1e0 user: fvogel tags: bug-1630262 | |
2012-01-31
| ||
22:24 | [Bug-1630262]: segfault when deleting lines with peer text widgets check-in: abca82f4 user: fvogel tags: bug-1630262 | |
2012-01-30
| ||
19:44 | ttk::combobox::Press: Don't take focus in disabled state [Bug 2925561]. check-in: dfb108b6 user: jenglish tags: core-8-5-branch | |
Changes
Changes to ChangeLog.
1 2 3 4 5 6 7 | 2012-01-29 Jan Nijtmans <[email protected]> * win/tkImgPhoto.c: [Bug 3480634]: PNG Images missing in menus on Mac 2012-01-27 Jan Nijtmans <[email protected]> * win/tkWinDialog.c: [Bug 3480471]: tk_getOpenFile crashes on Win64 | > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 2012-01-?? Francois Vogel <[email protected]> * generic/tkText.c: [Bug-1630262]: segfault when deleting lines * generic/tkTextBTree.c with peer text widgets * generic/tkTextDisp.c * tests/text.test 2012-01-29 Jan Nijtmans <[email protected]> * win/tkImgPhoto.c: [Bug 3480634]: PNG Images missing in menus on Mac 2012-01-27 Jan Nijtmans <[email protected]> * win/tkWinDialog.c: [Bug 3480471]: tk_getOpenFile crashes on Win64 |
︙ | ︙ |
Changes to generic/tkText.c.
︙ | ︙ | |||
3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 | * Deletion range starts on top line but after topIndex. Use * the current topIndex as the new one. */ resetView = 1; line = line1; byteIndex = tPtr->topIndex.byteIndex; } } else if (index2.linePtr == tPtr->topIndex.linePtr) { /* * Deletion range ends on top line but before topIndex. Figure out * what will be the new character index for the character * currently pointed to by topIndex. */ resetView = 1; line = line2; byteIndex = tPtr->topIndex.byteIndex; if (index1.linePtr != index2.linePtr) { byteIndex -= index2.byteIndex; } else { byteIndex -= (index2.byteIndex - index1.byteIndex); } } if (resetView) { lineAndByteIndex[resetViewCount] = line; lineAndByteIndex[resetViewCount+1] = byteIndex; } else { lineAndByteIndex[resetViewCount] = -1; } | > > > > > > > > > > | 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 | * Deletion range starts on top line but after topIndex. Use * the current topIndex as the new one. */ resetView = 1; line = line1; byteIndex = tPtr->topIndex.byteIndex; } else { /* * Deletion range starts after the top line. This peers's view * will not need to be reset. Nothing to do. */ } } else if (index2.linePtr == tPtr->topIndex.linePtr) { /* * Deletion range ends on top line but before topIndex. Figure out * what will be the new character index for the character * currently pointed to by topIndex. */ resetView = 1; line = line2; byteIndex = tPtr->topIndex.byteIndex; if (index1.linePtr != index2.linePtr) { byteIndex -= index2.byteIndex; } else { byteIndex -= (index2.byteIndex - index1.byteIndex); } } else { /* * Deletion range ends before the top line. This peers's view * will not need to be reset. Nothing to do. */ } if (resetView) { lineAndByteIndex[resetViewCount] = line; lineAndByteIndex[resetViewCount+1] = byteIndex; } else { lineAndByteIndex[resetViewCount] = -1; } |
︙ | ︙ | |||
3153 3154 3155 3156 3157 3158 3159 | int line = lineAndByteIndex[resetViewCount]; if (line != -1) { int byteIndex = lineAndByteIndex[resetViewCount+1]; TkTextIndex indexTmp; if (tPtr == textPtr) { | | > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > | 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 | int line = lineAndByteIndex[resetViewCount]; if (line != -1) { int byteIndex = lineAndByteIndex[resetViewCount+1]; TkTextIndex indexTmp; if (tPtr == textPtr) { if (viewUpdate) { /* * line cannot be before -startline of textPtr because * this line corresponds to an index which is necessarily * between "1.0" and "end" relative to textPtr. * Therefore no need to clamp line to the -start/-end * range. */ TkTextMakeByteIndex(sharedTextPtr->tree, textPtr, line, byteIndex, &indexTmp); TkTextSetYView(tPtr, &indexTmp, 0); } } else { TkTextMakeByteIndex(sharedTextPtr->tree, tPtr, line, byteIndex, &indexTmp); /* * line may be before -startline of tPtr and must be * clamped to -startline before providing it to * TkTextSetYView otherwise lines before -startline * would be displayed. * There is no need to worry about -endline however, * because the view will only be reset if the deletion * involves the TOP line of the screen */ if (tPtr->start != NULL) { int start; TkTextIndex indexStart; start = TkBTreeLinesTo(NULL, tPtr->start); TkTextMakeByteIndex(sharedTextPtr->tree, NULL, start, 0, &indexStart); if (TkTextIndexCmp(&indexTmp, &indexStart) < 0) { indexTmp = indexStart; } } TkTextSetYView(tPtr, &indexTmp, 0); } } resetViewCount += 2; } if (sharedTextPtr->refCount > PIXEL_CLIENTS) { ckfree((char *) lineAndByteIndex); |
︙ | ︙ |
Changes to generic/tkTextBTree.c.
︙ | ︙ | |||
658 659 660 661 662 663 664 | treePtr->startEndRef = (TkText **) ckrealloc((char *) treePtr->startEndRef, sizeof(TkText *) * count); if (textPtr->start != NULL) { count--; treePtr->startEnd[count] = textPtr->start; | | | | 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 | treePtr->startEndRef = (TkText **) ckrealloc((char *) treePtr->startEndRef, sizeof(TkText *) * count); if (textPtr->start != NULL) { count--; treePtr->startEnd[count] = textPtr->start; treePtr->startEndRef[count] = textPtr; } if (textPtr->end != NULL) { count--; treePtr->startEnd[count] = textPtr->end; treePtr->startEndRef[count] = textPtr; } } } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
1605 1606 1607 1608 1609 1610 1611 | nodePtr = treePtr->rootPtr; if ((line < 0) || (line >= nodePtr->numLines)) { return NULL; } /* | | | 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 | nodePtr = treePtr->rootPtr; if ((line < 0) || (line >= nodePtr->numLines)) { return NULL; } /* * Check for any start/end offset for this text widget. */ if (textPtr != NULL) { if (textPtr->start != NULL) { line += TkBTreeLinesTo(NULL, textPtr->start); if (line >= nodePtr->numLines) { return NULL; |
︙ | ︙ | |||
1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 | Tcl_Panic("TkBTreeLinesTo couldn't find node"); } index += nodePtr2->numLines; } } if (textPtr != NULL && textPtr->start != NULL) { index -= TkBTreeLinesTo(NULL, textPtr->start); } return index; } /* *---------------------------------------------------------------------- * | > > > > > | 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 | Tcl_Panic("TkBTreeLinesTo couldn't find node"); } index += nodePtr2->numLines; } } if (textPtr != NULL && textPtr->start != NULL) { index -= TkBTreeLinesTo(NULL, textPtr->start); if (index < 0) { /* One should panic here! Tcl_Panic("TkBTreeLinesTo: linePtr comes before -startline"); */ } } return index; } /* *---------------------------------------------------------------------- * |
︙ | ︙ |
Changes to generic/tkTextDisp.c.
︙ | ︙ | |||
3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 | TkTextLine *linePtr, /* Invalidation starts from this line. */ int lineCount, /* And includes this many following lines. */ int action) /* Indicates what type of invalidation * occurred (insert, delete, or simple). */ { int fromLine; TextDInfo *dInfoPtr = textPtr->dInfoPtr; if (linePtr != NULL) { int counter = lineCount; fromLine = TkBTreeLinesTo(textPtr, linePtr); /* * Invalidate the height calculations of each line in the given range. */ TkBTreeLinePixelEpoch(textPtr, linePtr) = 0; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 | TkTextLine *linePtr, /* Invalidation starts from this line. */ int lineCount, /* And includes this many following lines. */ int action) /* Indicates what type of invalidation * occurred (insert, delete, or simple). */ { int fromLine; TextDInfo *dInfoPtr = textPtr->dInfoPtr; /* * All lines to invalidate must be inside the -startline/-endline range. */ if (linePtr != NULL) { int start; TkTextLine *toLinePtr; if (textPtr->start != NULL) { fromLine = TkBTreeLinesTo(NULL, linePtr); start = TkBTreeLinesTo(NULL, textPtr->start); if (fromLine < start) { lineCount -= start - fromLine; linePtr = textPtr->start; } } if (textPtr->end != NULL) { int count = 0; toLinePtr = linePtr; while (count < lineCount && toLinePtr != NULL) { toLinePtr = TkBTreeNextLine(textPtr, toLinePtr); count++; } if (toLinePtr == NULL) { lineCount = count; } } } if (linePtr != NULL) { int counter = lineCount; fromLine = TkBTreeLinesTo(textPtr, linePtr); /* * Invalidate the height calculations of each line in the given range. */ TkBTreeLinePixelEpoch(textPtr, linePtr) = 0; while (counter > 0 && linePtr != NULL) { linePtr = TkBTreeNextLine(textPtr, linePtr); if (linePtr != NULL) { TkBTreeLinePixelEpoch(textPtr, linePtr) = 0; } counter--; } /* * Now schedule an examination of each line in the union of the old * and new update ranges, including the (possibly empty) range in * between. If that between range is not-empty, then we are examining * more lines than is strictly necessary (but the examination of the * extra lines should be quick, since their pixelCalculationEpoch will * be up to date). However, to keep track of that would require more * complex record-keeping than what we have. */ if (dInfoPtr->lineUpdateTimer == NULL) { dInfoPtr->currentMetricUpdateLine = fromLine; if (action == TK_TEXT_INVALIDATE_DELETE) { lineCount = 0; } |
︙ | ︙ |
Changes to tests/text.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # This file is a Tcl script to test the code in the file tkText.c. # This file is organized in the standard fashion for Tcl tests. # # Copyright (c) 1992-1994 The Regents of the University of California. # Copyright (c) 1994-1996 Sun Microsystems, Inc. # Copyright (c) 1998-1999 by Scriptics Corporation. # All rights reserved. package require tcltest 2.1 eval tcltest::configure $argv tcltest::loadTestedCommands namespace import -force tcltest::test | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # This file is a Tcl script to test the code in the file tkText.c. # This file is organized in the standard fashion for Tcl tests. # # Copyright (c) 1992-1994 The Regents of the University of California. # Copyright (c) 1994-1996 Sun Microsystems, Inc. # Copyright (c) 1998-1999 by Scriptics Corporation. # All rights reserved. package require tcltest 2.1 eval tcltest::configure $argv tcltest::loadTestedCommands namespace import -force tcltest::test # Create entries in the odeption database to be sure that geometry options # like border width have predictable values. option add *Text.borderWidth 2 option add *Text.highlightThickness 2 option add *Text.font {Courier -12} text .t -width 20 -height 10 |
︙ | ︙ | |||
3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 | lappend res [.t tag ranges sel] .t configure -start 25 -end 30 lappend res [.t tag ranges sel] .t configure -start {} -end {} lappend res [.t tag ranges sel] set res } {{10.0 20.0} {6.0 16.0} {6.0 11.0} {1.0 6.0} {1.0 2.0} {} {10.0 20.0}} test text-33.1 {widget dump -command alters tags} { .t delete 1.0 end .t insert end "abc\n" a "---" {} "def" b " \n" {} "ghi\n" c .t tag configure b -background red proc Dumpy {key value index} { #puts "KK: $key, $value" | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 | lappend res [.t tag ranges sel] .t configure -start 25 -end 30 lappend res [.t tag ranges sel] .t configure -start {} -end {} lappend res [.t tag ranges sel] set res } {{10.0 20.0} {6.0 16.0} {6.0 11.0} {1.0 6.0} {1.0 2.0} {} {10.0 20.0}} test text-32.2 {peer widget -start, -end and deletion (bug 1630262)} -setup { destroy .t .pt set res {} } -body { text .t .t peer create .pt for {set i 1} {$i < 100} {incr i} { .t insert end "Line $i\n" } .t configure -startline 5 # none of the following delete shall crash # (all did before fixing bug 1630262) # 1. delete on the same line: line1 == line2 in DeleteIndexRange, # and resetView is true neither for .t not for .pt .pt delete 2.0 2.2 # 2. delete just one line: line1 < line2 in DeleteIndexRange, # and resetView is true only for .t, not for .pt .pt delete 2.0 3.0 # 3. delete several lines: line1 < line2 in DeleteIndexRange, # and resetView is true only for .t, not for .pt .pt delete 2.0 5.0 # 4. delete to the end line: line1 < line2 in DeleteIndexRange, # and resetView is true only for .t, not for .pt .pt delete 2.0 end # this test succeeds provided there is no crash set res 1 } -cleanup { destroy .pt } -result {1} test text-32.3 {peer widget -start, -end and deletion (bug 1630262)} -setup { destroy .t .pt set res {} } -body { text .t .t peer create .pt for {set i 1} {$i < 100} {incr i} { .t insert end "Line $i\n" } .t configure -startline 5 .pt configure -startline 3 # the following delete shall not crash # (it did before fixing bug 1630262) .pt delete 2.0 3.0 # moreover -startline shall be correct # (was wrong before fixing bug 1630262) lappend res [.t cget -start] [.pt cget -start] } -cleanup { destroy .pt } -result {4 3} test text-32.4 {peer widget -start, -end and deletion (bug 1630262)} -setup { destroy .t .pt set res {} } -body { text .t .t peer create .pt for {set i 1} {$i < 100} {incr i} { .t insert end "Line $i\n" } .t configure -startline 5 -endline 15 .pt configure -startline 8 -endline 12 # .pt now shows a range entirely inside the range of .pt # from .t, delete lines located after [.pt cget -end] .t delete 9.0 10.0 # from .t, delete lines straddling [.pt cget -end] .t delete 6.0 9.0 lappend res [.t cget -start] [.t cget -end] [.pt cget -start] [.pt cget -end] .t configure -startline 5 -endline 12 .pt configure -startline 8 -endline 12 # .pt now shows again a range entirely inside the range of .pt # from .t, delete lines located before [.pt cget -start] .t delete 2.0 3.0 # from .t, delete lines straddling [.pt cget -start] .t delete 2.0 5.0 lappend res [.t cget -start] [.t cget -end] [.pt cget -start] [.pt cget -end] .t configure -startline 22 -endline 31 .pt configure -startline 42 -endline 51 # .t now shows a range entirely before the range of .pt # from .t, delete some lines, then do it from .pt .t delete 2.0 3.0 .t delete 2.0 5.0 .pt delete 2.0 5.0 lappend res [.t cget -start] [.t cget -end] [.pt cget -start] [.pt cget -end] .t configure -startline 55 -endline 75 .pt configure -startline 60 -endline 70 # .pt now shows a range entirely inside the range of .t # from .t, delete a range straddling the entire range of .pt .t delete 3.0 18.0 lappend res [.t cget -start] [.t cget -end] [.pt cget -start] [.pt cget -end] } -cleanup { destroy .pt } -result {5 11 8 10 5 8 6 8 22 27 38 44 55 60 57 57} test text-33.1 {widget dump -command alters tags} { .t delete 1.0 end .t insert end "abc\n" a "---" {} "def" b " \n" {} "ghi\n" c .t tag configure b -background red proc Dumpy {key value index} { #puts "KK: $key, $value" |
︙ | ︙ |