Ticket UUID: | 63449c05144fa85be0217ee3f82a78c6605bbdd3 | |||
Title: | [namespace children] doesn't match non-glob patterns below the global namespace | |||
Type: | Bug | Version: | Current | |
Submitter: | stu | Created on: | 2024-02-22 07:17:55 | |
Subsystem: | 21. [namespace] | Assigned To: | jan.nijtmans | |
Priority: | 6 | Severity: | Minor | |
Status: | Closed | Last Modified: | 2025-07-31 18:45:11 | |
Resolution: | Fixed | Closed By: | dgp | |
Closed on: | 2025-07-31 18:45:11 | |||
Description: |
# Create namespaces namespace eval a { namespace eval b {} } # Good result with non-glob pattern, and global namespace namespace children :: a ;# => ::a # Good result with single-char glob pattern, and other namespace namespace children a {[b]} ;# => ::a::b # Good result because of glob char in pattern, and other namespace namespace children a b* ;# => ::a::b # Bad result with non-glob pattern, and other namespace namespace children a b ;# => {} In generic/tclNamespace.c, function NamespaceChildrenCmd (lines 2988-3108), Tcl_StringMatch will be called if a glob char is present in the pattern, otherwise the matching will be performed with a combination of strncmp() and Tcl_FindHashEntry: line 3067: if ((pattern != NULL) && TclMatchIsTrivial(pattern)) { The hash table lookup: line 3075 or 3078: Tcl_FindHashEntry(&nsPtr->childTable, pattern+length) != NULL These two chars might be added but they won't be taken into account when matching: lines 3053-3055: if (nsPtr != globalNsPtr) { TclDStringAppendLiteral(&buffer, "::"); } With a quick hack patch: -Tcl_FindHashEntry(&nsPtr->childTable, pattern+length) != NULL +Tcl_FindHashEntry(&nsPtr->childTable, 2+pattern+length) != NULL The child namespace can now be found: namespace children a b ;# => ::a::b However namespace ::a can no longer be found in the global namespace! namespace children :: a ;# => {} The two namespace separator ("::") chars are not being accounted for properly. | |||
User Comments: |
dgp added on 2025-07-31 18:45:11:
Backport landed on the 8.6 branch last December, so I guess the decision got made. Closing. oehhar (claiming to be oehar) added on 2024-12-15 10:04:56: Great ! I would love some explanatory text around the fix source. Maybe, I care tomorrow ! And it is 9.0.1, not 9.0.2, right ? Take care, Harald jan.nijtmans added on 2024-12-14 23:40:59: The CI build shows no regressions. So, Yes I think this should be included into Tcl 9.0.2 (to be discussed within the TTT). Was this problem introduced in Tcl 8.7 or 9.0, or was it always there? Should it be backported to 8.7 and/or 8.6? Therefore, leaving this ticket open. No hurry to decide that. jan.nijtmans added on 2024-12-13 15:06:13: Proposed fix [ee821ec00f|here] stu added on 2024-12-02 15:02:07: The patch is just a suggestion. The problem is an offset of 2 is not added when it should be. I'm not familiar enough with the code to pick the best place to do this. stu added on 2024-02-22 07:33:25: Correction: -Tcl_FindHashEntry(&nsPtr->childTable, pattern+length) != NULL +Tcl_FindHashEntry(&nsPtr->childTable, (nsPtr != globalNsPtr ? 2 : 0)+pattern+length) != NULL stu added on 2024-02-22 07:32:03: This patch handles global and non-global. q&d poc -Tcl_FindHashEntry(&nsPtr->childTable, 2+pattern+length) != NULL +Tcl_FindHashEntry(&nsPtr->childTable, (nsPtr != globalNsPtr ? 2 : 0)+pattern+length) != NULL |
