Ticket UUID: | e87bcf819f03cea4e35dca24cac7228766f53b0 | |||
Title: | [array for] fails to detect array change made through upvar | |||
Type: | Bug | Version: | ||
Submitter: | dgp | Created on: | 2018-04-22 19:10:03 | |
Subsystem: | 07. Variables | Assigned To: | dkf | |
Priority: | 5 Medium | Severity: | Important | |
Status: | Open | Last Modified: | 2018-05-07 15:56:29 | |
Resolution: | None | Closed By: | nobody | |
Closed on: | ||||
Description: |
Contrast these two: % proc demo {} { array set a {m 1 n 2 o 3 p 4} try { array for {k v} a {unset a(n)} } on error {m} { puts "ERROR: $m" } finally { puts [array get a] } } % demo ERROR: array changed during iteration p 4 m 1 o 3 % proc demo {} { array set a {m 1 n 2 o 3 p 4} upvar 0 a(n) l try { array for {k v} a {catch {unset l}} } on error {m} { puts "ERROR:$m" } finally { puts [array get a] } } % demo p 4 m 1 o 3 | |||
User Comments: |
dkf added on 2018-05-07 15:56:29:
And the bug is that the unset isn't killing the searches, and that's because the variable link is meaning that we're arriving at the element (which knows that it is in a TclVarHashTable) without going back to check if this makes things become invalidated. Which it can't do because we don't currently keep a pointer to the containing variable in the TclVarHashTable (the pointer could be NULL for non-array use cases, I guess). I don't know what the consequences of keeping such a pointer would be, apart from a small amount of extra memory usage. The first option is correct; an error should be thrown by array for on internal modification. dkf added on 2018-05-07 15:19:26: The changes to tclOOBasic.c look OK to me. They won't interfere with TIP 500. dkf added on 2018-05-07 15:11:01: Xref: bug-e87bcf819f dkf added on 2018-05-07 15:06:16: What I find interesting is that the [unset l] doesn't change the structure of the array. It's because there's still a reference to it (from the l variable) but it's still unexpected to anyone who isn't experienced with Tcl's guts. dgp added on 2018-04-30 11:56:54: Note that the machinery created here might be useful in fixing the very old bug/RFE https://core.tcl-lang.org/tcl/tktview?name=572889 as well. dgp added on 2018-04-22 23:11:51: Candidate fix on branch bug-e87bcf819f. dkf should comment on the changes made to TclOOBasic.c dgp added on 2018-04-22 19:13:46: The same failure probably exists in the [array startsearch], etc commands. dgp added on 2018-04-22 19:13:11: Because this evades the protection against using a Tcl_HashSearch after the hash table has changed, it is likely this can be used to create segfaults. |