Ticket UUID: | e38dce74e28420b6c1f44fba604c4ed6193a6391 | |||
Title: | Command line built with list not properly quoted | |||
Type: | Bug | Version: | 8.7 | |
Submitter: | sbron | Created on: | 2024-09-17 18:38:51 | |
Subsystem: | 17. Commands I-L | Assigned To: | apnadkarni | |
Priority: | 5 Medium | Severity: | Important | |
Status: | Open | Last Modified: | 2024-09-25 07:59:16 | |
Resolution: | Fixed | Closed By: | nobody | |
Closed on: | ||||
Description: |
A command line built using the list command is not always quoted correctly. Example:
Result in 9.0.0: ##foo This means that a command built like that will not be executed in 9.0.0 because it gets interpreted as a comment. | |||
User Comments: |
jan.nijtmans added on 2024-09-25 07:59:16:
Fixed [8627aad9bd0ee583|here] Keeping open, to handle sebres's suggestion. To be discussed further, but not for 9.0.0 apnadkarni added on 2024-09-22 04:37:53: Sorry, coming late to this. I didn't get an email when Jan assigned to me. Doesn't fossil automatically do that? In any case, I see Sergey /Jan have proposed fixes. Tx. If I understand correctly, the question now is whether I have mixed feelings on that but note at least in some other "no-op" cases, string rep is changed. For example,
jan.nijtmans added on 2024-09-21 22:50:57: I don't think checking for '#' as first character is sufficient. Proof [03f1b16720247ab1|here]. Tcl 8.6 already implements 2), this bug report handles an optimalization which broke this. Your analysis shows this was not done consistently in all cases. I like your bug-e38dce74e2-214cc0eb22-v2 branch, but prefer some more testing before rushing it into 9.0.0. It can wait until 9.0.1, because (I guess) 8.6 has the same problem. Thanks! sebres added on 2024-09-20 20:38:01: Well, it is a bit more complex than one can assume... For instance, there is [214cc0eb22] for similar invocation but with lappend, however about the difference between compiled and not compiled, just the decision was exactly vice versa - both shall not switch the string rep of "new" object as result of command. In my opinion both are the same circumstances and need to be considered in the same manner if the object doesn't change internally:
The different reaction depending on command makes it just more complex and totally confusing. New branch bug-e38dce74e2-214cc0eb22-v2 [3d1a4c2dde] is another fix for this (the 2nd variant but for all list-ops), also covering lappend and other commands, and changes behaviour for [214cc0eb22] to 2nd variant too, e.g. as it was in compiled form previously. Although after all I guess, it must be fixed (in this or that form) for all versions starting with 8.6 in a consequent way. And finally, I tend more towards variant 1 (no change on object internals == no change on it's string representation, no matter which command). jan.nijtmans added on 2024-09-20 12:39:23: Proposed fix [9c2fe388134df0de|here] (with testcase) Note that the TclListObjAppendElements header documentation tells us: If the passed Tcl_Obj is not a list object, it will be converted to one and an error raised if the conversion fails. That's exactly the situation: The Tcl_Obj was not a list so it should be converted to one. Therefore TclListObjAppendElements() didn't behave as it was documented to behave. Thanks, Schelte, for your help. Anyone wants to review? sbron added on 2024-09-19 08:20:55: Looking deeper into the issue, I find that the Tcl 8.6 code that handles this situation (Tcl_ListObjReplace()) contains the following comment:
On Tcl 9.0 a different function is used (TclListObjAppendElements()), which does have the optimization that was warned against. Disabling the shortcut when elemCount <= 0 fixes the problem.
jan.nijtmans added on 2024-09-18 20:20:40: So, doing a bisect: 2 BAD 2024-09-18 15:43:29 9c8c6e1576248c08 4 BAD 2023-03-19 11:56:58 2697657fd20c9270 6 BAD 2022-10-28 13:51:18 57394eda0b9c91f1 7 BAD 2022-09-12 11:10:49 e06d228ee0f6e848 9 BAD 2022-08-30 06:53:35 6f3a9fb52414fda9 12 BAD 2022-08-29 09:56:51 b8d47e9100fa4105 13 BAD 2022-08-29 08:03:58 d9b720c46d3e8155 14 GOOD 2022-08-26 23:11:44 a9db66657b33bf62 CURRENT 11 GOOD 2022-08-26 22:50:50 c6af6c33818bf1e2 10 GOOD 2022-08-23 06:37:37 2254d0416707f433 8 GOOD 2022-07-25 14:05:59 ce8f522a49aef039 5 GOOD 2022-06-20 09:44:07 f16233109c67e020 3 GOOD 2021-03-30 10:17:09 d59e47d7c9c00eb4 1 GOOD 2017-09-08 12:50:06 31bf3805809c5afe This points the problem at [d9b720c46d3e8155|this] commit, which is the TIP #625 implementation: "Re-implementation of lists". I already suspected this before doing the bisect, just wanted to be sure .... Therefore, assigning to Ashok oehhar added on 2024-09-18 17:42:26: Hi Schelte, Hi Jan, I did not know, that this is valid to name a command with leading "#". For me, the quoting for a list is ok. The following snippet returns ##foo for 8.6 and 9.0 proc {##foo} {args} {puts !} set cmd ##foo set args {} set c [list {*}$cmd {*}$args] lindex $c 0 IMHO it is "interesting" to include the special syntax of a command in a list quoting. The list behaves differently than "[]". Really interesting and amazing... TCL 8.6 and 9.0 are identical here for me: % proc {##cmd} {args} {puts !} % ##cmd % {##cmd} ! % set cmd ##cmd ##cmd % list $cmd {##cmd} % puts {*}$cmd ##cmd % puts [{*}$cmd] ! So, the [$cmd] with cmd = ##cmd calls the command - weired ! The use case by Schelte is, that a command would call the command in one case, but not in the other. Ok, lets try: proc {##foo} {args} {puts !} set cmd ##foo set args {} set c [list {*}$cmd {*}$args] lindex $c 0 On 8.6: % eval $c ! % puts [$c] invalid command name "{##foo}" On 9.0: % eval $c % puts [$c] ! That is weired big fun ! Thank you for all, Harald jan.nijtmans added on 2024-09-18 16:30:10: Same problem in 8.7 too |
