2020-07-07
| ||
07:40 | Merge fixes for [40e4bf61] and [e3888d5820] check-in: a8ce959b user: jan.nijtmans tags: core-8-6-11-rc | |
2020-07-06
| ||
21:14 | • Closed ticket [40e4bf61]: Entry: double free when textvariable set in validatecommand script plus 5 other changes artifact: 50583d23 user: fvogel | |
21:12 | Fix [40e4bf6198]: Entry/spinbox: double free when textvariable set in validatecommand script. check-in: 6044aa73 user: fvogel tags: trunk | |
21:12 | Fix [40e4bf6198]: Entry/spinbox: double free when textvariable set in validatecommand script. check-in: de3c5d23 user: fvogel tags: core-8-6-branch | |
2020-07-05
| ||
20:28 | • Ticket [40e4bf61] Entry: double free when textvariable set in validatecommand script status still Open with 3 other changes artifact: f2c3b9c5 user: fvogel | |
20:01 | Bring entry-19.19 and spinbox-19.19 in line with the fix for [40e4bf6198]. Validation is now aborted earlier (and more correctly) when a validation loop is detected, therefore the widget content does no longer change in the process. check-in: 8b74f4d5 user: fvogel tags: bug-40e4bf6198 | |
2020-06-21
| ||
11:21 | • Ticket [40e4bf61] Entry: double free when textvariable set in validatecommand script status still Open with 3 other changes artifact: c82b69d1 user: fvogel | |
2020-06-20
| ||
10:31 | • Ticket [40e4bf61]: 3 changes artifact: a243aabe user: chrstphrchvz | |
2020-06-18
| ||
20:17 | • Ticket [40e4bf61]: 3 changes artifact: fd37e8f1 user: fvogel | |
18:35 | • Ticket [40e4bf61]: 3 changes artifact: 38083470 user: chrstphrchvz | |
11:47 | • Ticket [40e4bf61]: 3 changes artifact: 79643d28 user: fvogel | |
10:10 | • Ticket [40e4bf61]: 3 changes artifact: 2e6fe563 user: chrstphrchvz | |
2020-06-14
| ||
21:36 | • Ticket [40e4bf61]: 4 changes artifact: 25010c3b user: fvogel | |
21:34 | Fix [40e4bf6198]: Entry: double free when textvariable set in validatecommand script check-in: d9ce9e56 user: fvogel tags: bug-40e4bf6198 | |
2020-06-02
| ||
07:38 | • Ticket [40e4bf61] Entry: double free when textvariable set in validatecommand script status still Open with 3 other changes artifact: de9fe19e user: chrstphrchvz | |
2020-05-24
| ||
19:50 | • Ticket [40e4bf61]: 4 changes artifact: 0af3cf02 user: fvogel | |
19:36 | • Ticket [40e4bf61]: 3 changes artifact: 3a4e1144 user: fvogel | |
2020-05-22
| ||
12:12 | • New ticket [40e4bf61]. artifact: cc5ceef6 user: chrstphrchvz | |
Ticket UUID: | 40e4bf61988580b8ffaecd1d57a7087ba76b54d4 | |||
Title: | Entry: double free when textvariable set in validatecommand script | |||
Type: | Bug | Version: | 8.6.10 | |
Submitter: | chrstphrchvz | Created on: | 2020-05-22 12:12:47 | |
Subsystem: | 07. [entry] | Assigned To: | fvogel | |
Priority: | 5 Medium | Severity: | Important | |
Status: | Closed | Last Modified: | 2020-07-06 21:14:00 | |
Resolution: | Fixed | Closed By: | fvogel | |
Closed on: | 2020-07-06 21:14:00 | |||
Description: |
Here is a double free bug that someone originally reported for Perl/Tk (https://rt.cpan.org/Public/Bug/Display.html?id=102648), but which I replicated in Tcl/Tk using both the original Perl/Tk example through Tcl::pTk, as well as a nearly equivalent Tcl syntax example: package require Tk Pressing 'A' causes the double free in this example. When the key is pressed, It's not obvious to me what should be done about this issue. Should this at least not lead to a crash/corruption, or is it believed that the documentation already firmly warned against mixing I am not aware of this issue affecting Ttk entry widgets. | |||
User Comments: |
fvogel added on 2020-07-06 21:14:00:
Merged in core-8-6-branch and trunk. fvogel added on 2020-07-05 20:28:53: I have made two additional commits in the bugfix branch, in order to let entry-19.19 pass again (I have changed the expected test result) and to test the spinbox too. I will merge soon. fvogel added on 2020-06-21 11:21:42:
The fix consists in properly aborting recursive validation while we're already validating. Such a situation happens when running the validatecommand script (the "outer" validation request): when this script writes the textvariable, a write trace fires and requests validation (the "inner" validation). This inner validation needs to be aborted to prevent the double free from happening. This is done by setting Now when the textvariable is written more than once the second (and later) time the return path in As for the expected behavior of the original example script: the validatecommand script is evaluated, and after that the write traces fire. So the validatecommand script sets the textvariable and sets -validate to "key". Then the write traces fire, it tries to validate the textvariable value set previously, and sets the -validate configuration option to none. So you have the impression that package require Tk set en_text {Type 'A' here} pack [entry .e \ -textvariable en_text \ -validate key \ -validatecommand { if {"%S" eq {A}} { set en_text %P after idle {.e configure -validate key} } return 1 } ] Finally, yes, the statement from the documentation you're mentioning still applies. Just see results of test entry-19.20 or similar tests. Or even with the original script: % package require Tk 8.6.10 % set en_text {Type 'A' here} Type 'A' here % pack [entry .e \ -textvariable en_text \ -validate key \ -validatecommand { if {"%S" eq {A}} { set en_text %P .e configure -validate key } return 1 } ] % set en_text Type 'A' here % # Type letter 'A' in the entry % set en_text TyApe 'A' here % # The entry still shows "Type 'A' here", which is different from $en_text But, really, the manual should be followed: chrstphrchvz added on 2020-06-20 10:31:19: I no longer observe the double free, but I do not understand the code well enough to exhaustively say there's no way for one to happen. I'm also not sure I completely understand the example's expected behavior, and whether other bugs are present. For example, the I also don't know if this statement from the documentation still applies: It is also recommended to not set an associated fvogel added on 2020-06-18 20:17:45: How perverse! My fix [d9ce9e56] sets the Still while executing the validatecommand, when the textvariable is written a second (or more) time, the This is now fixed by [43bc0e3f]. All entry.test tests still pass, including the new entry-19.21, except entry-19.19 which fails as stated previously. chrstphrchvz added on 2020-06-18 18:35:01: My bad, I was not using the original example. Rather I was using a modified one that sets the textvariable repeatedly: set en_text {Type 'A' here} pack [entry .e \ -textvariable en_text \ -validate key \ -validatecommand { if {"%S" eq {A}} { for {set j 0} {$j < 100} {incr j} { set en_text $j } .e configure -validate key } return 1 } ] fvogel added on 2020-06-18 11:47:53: Really? With [d9ce9e5659] I don't. When typing "A" in the entry, line 2376 (the first free) in chrstphrchvz added on 2020-06-18 10:10:04: Under [d9ce9e5659] I still observe the double free issue using the example script. fvogel added on 2020-06-14 21:36:49: My original fix proposal was just a bad ugly hack. I have now something much better, please see [d9ce9e5659]. This fix aborts validation happening during the write trace (that is triggered because the validatecommand script changed the textvariable). The newly added test entry-19.21 passes with this fix (and fails without). All other tests from entry.test still pass, except entry-19.19 which newly fails as follows: ---- Result was: none nextdata {.e -1 -1 nextdata nextdata {} all forced} ---- Result should have been (exact matching): none mydata {.e -1 -1 nextdata nextdata {} all forced} ==== entry-19.19 FAILED This change in entry-19.19 results may well be fine since this test exercises one of the "dangerous" conditions highlighted in the man page (one of the "don't do that" cases). What do you think? chrstphrchvz added on 2020-06-02 07:38:42: Thanks for fixing the function names in the description. It has occurred to me that, by assigning to the textvariable multiple times in the validatecommand, it might be possible for a subsequent call to fvogel added on 2020-05-24 19:50:42: (Preliminary note: I have a bit edited the report since I think it contained wrong names of called functions at threee places.) About a possible fix, wouldn't the following patch be okay: Index: generic/tkEntry.c ================================================================== --- generic/tkEntry.c +++ generic/tkEntry.c @@ -2067,11 +2067,13 @@ VALIDATE_INSERT) != TCL_OK) { ckfree(newStr); return TCL_OK; } - ckfree((char *)string); + if (string == entryPtr->string) { + ckfree((char *)string); + } entryPtr->string = newStr; /* * ??? Is this construction still needed with Tcl_NumUtfChars ??? * Indeed, checking whether or not Of course, the above patch should be augmented with adequate comments to explain what's going on since it's not exactly straightforward. |