From d8e110991be7275ea5f245dbdf7f79302cac4fd2 Mon Sep 17 00:00:00 2001 From: Julian Noble Date: Fri, 6 Mar 2026 14:02:03 +1100 Subject: [PATCH] fix for dir listings of folders with windows illegal paths --- src/bootsupport/modules/punk/du-0.1.0.tm | 32 ++++++++++++++----- src/bootsupport/modules/punk/nav/fs-0.1.0.tm | 2 +- src/bootsupport/modules/punk/repo-0.1.1.tm | 2 +- src/modules/punk/du-999999.0a1.0.tm | 32 ++++++++++++++----- src/modules/punk/imap4-999999.0a1.0.tm | 2 +- src/modules/punk/repo-999999.0a1.0.tm | 2 +- .../src/bootsupport/modules/punk/du-0.1.0.tm | 32 ++++++++++++++----- .../bootsupport/modules/punk/nav/fs-0.1.0.tm | 2 +- .../bootsupport/modules/punk/repo-0.1.1.tm | 2 +- .../src/bootsupport/modules/punk/du-0.1.0.tm | 32 ++++++++++++++----- .../bootsupport/modules/punk/nav/fs-0.1.0.tm | 2 +- .../bootsupport/modules/punk/repo-0.1.1.tm | 2 +- 12 files changed, 104 insertions(+), 40 deletions(-) diff --git a/src/bootsupport/modules/punk/du-0.1.0.tm b/src/bootsupport/modules/punk/du-0.1.0.tm index 5955cf42..bc753154 100644 --- a/src/bootsupport/modules/punk/du-0.1.0.tm +++ b/src/bootsupport/modules/punk/du-0.1.0.tm @@ -24,6 +24,7 @@ package require punk::args namespace eval punk::du { variable has_twapi 0 + variable has_winpath 0 } if {"windows" eq $::tcl_platform(platform)} { if {![interp issafe]} { @@ -36,7 +37,10 @@ if {"windows" eq $::tcl_platform(platform)} { } else { set punk::du::has_twapi 1 } - #package require punk::winpath + + if {![catch {package require punk::winpath}]} { + set punk::du::has_winpath 1 + } } @@ -1450,6 +1454,7 @@ namespace eval punk::du { #return fsizes,allsizes,alltimes metadata in same order as files,dirs,links lists - if specified in sized_types proc du_get_metadata_lists {sized_types timed_types files dirs links} { + upvar ::punk::du::has_winpath has_winpath set meta_dict [dict create] set meta_types [list {*}$sized_types {*}$timed_types] #known tcl stat keys 2023 - review @@ -1460,13 +1465,24 @@ namespace eval punk::du { foreach ft {f d l} lvar {files dirs links} { if {"$ft" in $meta_types} { foreach path [set $lvar] { - #caller may have read perm on the containing folder - but not on child item - so file stat could raise an error - if {![catch {file stat $path arrstat} errM]} { - dict set meta_dict $path [dict create shorttype $ft {*}[array get arrstat]] + if {$has_winpath && [punk::winpath::illegalname_test $path]} { + set testpath [punk::winpath::illegalname_fix $path] + if {![catch {file stat $testpath arrstat} errM]} { + dict set meta_dict $path [dict create shorttype $ft {*}[array get arrstat]] + } else { + puts stderr "du_get_metadata_lists: file stat $testpath error: $errM" + dict lappend errors $path "file stat error: $errM" + dict set meta_dict $path [dict create shorttype $ft {*}$empty_stat_dict] + } } else { - puts stderr "du_get_metadata_lists: file stat $path error: $errM" - dict lappend errors $path "file stat error: $errM" - dict set meta_dict $path [dict create shorttype $ft {*}$empty_stat_dict] + #caller may have read perm on the containing folder - but not on child item - so file stat could raise an error + if {![catch {file stat $path arrstat} errM]} { + dict set meta_dict $path [dict create shorttype $ft {*}[array get arrstat]] + } else { + puts stderr "du_get_metadata_lists: file stat $path error: $errM" + dict lappend errors $path "file stat error: $errM" + dict set meta_dict $path [dict create shorttype $ft {*}$empty_stat_dict] + } } } } @@ -1481,7 +1497,7 @@ namespace eval punk::du { if {$ft in $sized_types} { dict set allsizes $path [dict create bytes [dict get $pathinfo size]] if {$ft eq "f"} { - #subst with na if empty? + #subst with na if empty? lappend fsizes [dict get $pathinfo size] if {[dict get $pathinfo size] eq ""} { puts stderr "du_get_metadata_lists: fsize $path is empty!" diff --git a/src/bootsupport/modules/punk/nav/fs-0.1.0.tm b/src/bootsupport/modules/punk/nav/fs-0.1.0.tm index 20a0849e..c9f744e0 100644 --- a/src/bootsupport/modules/punk/nav/fs-0.1.0.tm +++ b/src/bootsupport/modules/punk/nav/fs-0.1.0.tm @@ -792,7 +792,7 @@ tcl::namespace::eval punk::nav::fs { if {$searchspec eq ""} { set location } else { - if {$is_relativesarchspec} { + if {$is_relativesearchspec} { #set location [file dirname [file join $opt_searchbase $searchspec]] set location [punk::path::normjoin $searchbase $searchspec ..] } else { diff --git a/src/bootsupport/modules/punk/repo-0.1.1.tm b/src/bootsupport/modules/punk/repo-0.1.1.tm index 16f6f1cb..464baef6 100644 --- a/src/bootsupport/modules/punk/repo-0.1.1.tm +++ b/src/bootsupport/modules/punk/repo-0.1.1.tm @@ -1682,7 +1682,7 @@ namespace eval punk::repo { #whether path is at and/or below one of the vfs mount points #The design should facilitate nested vfs mountpoints proc path_vfs_info {filepath} { - error "unimplmented" + error "unimplemented" } #file normalize is expensive so this is too diff --git a/src/modules/punk/du-999999.0a1.0.tm b/src/modules/punk/du-999999.0a1.0.tm index 2ac4389b..daf8ca56 100644 --- a/src/modules/punk/du-999999.0a1.0.tm +++ b/src/modules/punk/du-999999.0a1.0.tm @@ -24,6 +24,7 @@ package require punk::args namespace eval punk::du { variable has_twapi 0 + variable has_winpath 0 } if {"windows" eq $::tcl_platform(platform)} { if {![interp issafe]} { @@ -36,7 +37,10 @@ if {"windows" eq $::tcl_platform(platform)} { } else { set punk::du::has_twapi 1 } - #package require punk::winpath + + if {![catch {package require punk::winpath}]} { + set punk::du::has_winpath 1 + } } @@ -1450,6 +1454,7 @@ namespace eval punk::du { #return fsizes,allsizes,alltimes metadata in same order as files,dirs,links lists - if specified in sized_types proc du_get_metadata_lists {sized_types timed_types files dirs links} { + upvar ::punk::du::has_winpath has_winpath set meta_dict [dict create] set meta_types [list {*}$sized_types {*}$timed_types] #known tcl stat keys 2023 - review @@ -1460,13 +1465,24 @@ namespace eval punk::du { foreach ft {f d l} lvar {files dirs links} { if {"$ft" in $meta_types} { foreach path [set $lvar] { - #caller may have read perm on the containing folder - but not on child item - so file stat could raise an error - if {![catch {file stat $path arrstat} errM]} { - dict set meta_dict $path [dict create shorttype $ft {*}[array get arrstat]] + if {$has_winpath && [punk::winpath::illegalname_test $path]} { + set testpath [punk::winpath::illegalname_fix $path] + if {![catch {file stat $testpath arrstat} errM]} { + dict set meta_dict $path [dict create shorttype $ft {*}[array get arrstat]] + } else { + puts stderr "du_get_metadata_lists: file stat $testpath error: $errM" + dict lappend errors $path "file stat error: $errM" + dict set meta_dict $path [dict create shorttype $ft {*}$empty_stat_dict] + } } else { - puts stderr "du_get_metadata_lists: file stat $path error: $errM" - dict lappend errors $path "file stat error: $errM" - dict set meta_dict $path [dict create shorttype $ft {*}$empty_stat_dict] + #caller may have read perm on the containing folder - but not on child item - so file stat could raise an error + if {![catch {file stat $path arrstat} errM]} { + dict set meta_dict $path [dict create shorttype $ft {*}[array get arrstat]] + } else { + puts stderr "du_get_metadata_lists: file stat $path error: $errM" + dict lappend errors $path "file stat error: $errM" + dict set meta_dict $path [dict create shorttype $ft {*}$empty_stat_dict] + } } } } @@ -1481,7 +1497,7 @@ namespace eval punk::du { if {$ft in $sized_types} { dict set allsizes $path [dict create bytes [dict get $pathinfo size]] if {$ft eq "f"} { - #subst with na if empty? + #subst with na if empty? lappend fsizes [dict get $pathinfo size] if {[dict get $pathinfo size] eq ""} { puts stderr "du_get_metadata_lists: fsize $path is empty!" diff --git a/src/modules/punk/imap4-999999.0a1.0.tm b/src/modules/punk/imap4-999999.0a1.0.tm index ede4704c..0c8f8f21 100644 --- a/src/modules/punk/imap4-999999.0a1.0.tm +++ b/src/modules/punk/imap4-999999.0a1.0.tm @@ -1639,7 +1639,7 @@ tcl::namespace::eval punk::imap4 { chan configure $chan -translation binary dict set coninfo $chan [dict create hostname $address port $port debug $opt_debug security $opt_security] - # Intialize the connection state array + # Initialize the connection state array punk::imap4::proto::initinfo $chan # Get the banner punk::imap4::proto::processline $chan * diff --git a/src/modules/punk/repo-999999.0a1.0.tm b/src/modules/punk/repo-999999.0a1.0.tm index 060431fe..11c50596 100644 --- a/src/modules/punk/repo-999999.0a1.0.tm +++ b/src/modules/punk/repo-999999.0a1.0.tm @@ -1682,7 +1682,7 @@ namespace eval punk::repo { #whether path is at and/or below one of the vfs mount points #The design should facilitate nested vfs mountpoints proc path_vfs_info {filepath} { - error "unimplmented" + error "unimplemented" } #file normalize is expensive so this is too diff --git a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/du-0.1.0.tm b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/du-0.1.0.tm index 5955cf42..bc753154 100644 --- a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/du-0.1.0.tm +++ b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/du-0.1.0.tm @@ -24,6 +24,7 @@ package require punk::args namespace eval punk::du { variable has_twapi 0 + variable has_winpath 0 } if {"windows" eq $::tcl_platform(platform)} { if {![interp issafe]} { @@ -36,7 +37,10 @@ if {"windows" eq $::tcl_platform(platform)} { } else { set punk::du::has_twapi 1 } - #package require punk::winpath + + if {![catch {package require punk::winpath}]} { + set punk::du::has_winpath 1 + } } @@ -1450,6 +1454,7 @@ namespace eval punk::du { #return fsizes,allsizes,alltimes metadata in same order as files,dirs,links lists - if specified in sized_types proc du_get_metadata_lists {sized_types timed_types files dirs links} { + upvar ::punk::du::has_winpath has_winpath set meta_dict [dict create] set meta_types [list {*}$sized_types {*}$timed_types] #known tcl stat keys 2023 - review @@ -1460,13 +1465,24 @@ namespace eval punk::du { foreach ft {f d l} lvar {files dirs links} { if {"$ft" in $meta_types} { foreach path [set $lvar] { - #caller may have read perm on the containing folder - but not on child item - so file stat could raise an error - if {![catch {file stat $path arrstat} errM]} { - dict set meta_dict $path [dict create shorttype $ft {*}[array get arrstat]] + if {$has_winpath && [punk::winpath::illegalname_test $path]} { + set testpath [punk::winpath::illegalname_fix $path] + if {![catch {file stat $testpath arrstat} errM]} { + dict set meta_dict $path [dict create shorttype $ft {*}[array get arrstat]] + } else { + puts stderr "du_get_metadata_lists: file stat $testpath error: $errM" + dict lappend errors $path "file stat error: $errM" + dict set meta_dict $path [dict create shorttype $ft {*}$empty_stat_dict] + } } else { - puts stderr "du_get_metadata_lists: file stat $path error: $errM" - dict lappend errors $path "file stat error: $errM" - dict set meta_dict $path [dict create shorttype $ft {*}$empty_stat_dict] + #caller may have read perm on the containing folder - but not on child item - so file stat could raise an error + if {![catch {file stat $path arrstat} errM]} { + dict set meta_dict $path [dict create shorttype $ft {*}[array get arrstat]] + } else { + puts stderr "du_get_metadata_lists: file stat $path error: $errM" + dict lappend errors $path "file stat error: $errM" + dict set meta_dict $path [dict create shorttype $ft {*}$empty_stat_dict] + } } } } @@ -1481,7 +1497,7 @@ namespace eval punk::du { if {$ft in $sized_types} { dict set allsizes $path [dict create bytes [dict get $pathinfo size]] if {$ft eq "f"} { - #subst with na if empty? + #subst with na if empty? lappend fsizes [dict get $pathinfo size] if {[dict get $pathinfo size] eq ""} { puts stderr "du_get_metadata_lists: fsize $path is empty!" diff --git a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/nav/fs-0.1.0.tm b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/nav/fs-0.1.0.tm index 20a0849e..c9f744e0 100644 --- a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/nav/fs-0.1.0.tm +++ b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/nav/fs-0.1.0.tm @@ -792,7 +792,7 @@ tcl::namespace::eval punk::nav::fs { if {$searchspec eq ""} { set location } else { - if {$is_relativesarchspec} { + if {$is_relativesearchspec} { #set location [file dirname [file join $opt_searchbase $searchspec]] set location [punk::path::normjoin $searchbase $searchspec ..] } else { diff --git a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/repo-0.1.1.tm b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/repo-0.1.1.tm index 16f6f1cb..464baef6 100644 --- a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/repo-0.1.1.tm +++ b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/repo-0.1.1.tm @@ -1682,7 +1682,7 @@ namespace eval punk::repo { #whether path is at and/or below one of the vfs mount points #The design should facilitate nested vfs mountpoints proc path_vfs_info {filepath} { - error "unimplmented" + error "unimplemented" } #file normalize is expensive so this is too diff --git a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/du-0.1.0.tm b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/du-0.1.0.tm index 5955cf42..bc753154 100644 --- a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/du-0.1.0.tm +++ b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/du-0.1.0.tm @@ -24,6 +24,7 @@ package require punk::args namespace eval punk::du { variable has_twapi 0 + variable has_winpath 0 } if {"windows" eq $::tcl_platform(platform)} { if {![interp issafe]} { @@ -36,7 +37,10 @@ if {"windows" eq $::tcl_platform(platform)} { } else { set punk::du::has_twapi 1 } - #package require punk::winpath + + if {![catch {package require punk::winpath}]} { + set punk::du::has_winpath 1 + } } @@ -1450,6 +1454,7 @@ namespace eval punk::du { #return fsizes,allsizes,alltimes metadata in same order as files,dirs,links lists - if specified in sized_types proc du_get_metadata_lists {sized_types timed_types files dirs links} { + upvar ::punk::du::has_winpath has_winpath set meta_dict [dict create] set meta_types [list {*}$sized_types {*}$timed_types] #known tcl stat keys 2023 - review @@ -1460,13 +1465,24 @@ namespace eval punk::du { foreach ft {f d l} lvar {files dirs links} { if {"$ft" in $meta_types} { foreach path [set $lvar] { - #caller may have read perm on the containing folder - but not on child item - so file stat could raise an error - if {![catch {file stat $path arrstat} errM]} { - dict set meta_dict $path [dict create shorttype $ft {*}[array get arrstat]] + if {$has_winpath && [punk::winpath::illegalname_test $path]} { + set testpath [punk::winpath::illegalname_fix $path] + if {![catch {file stat $testpath arrstat} errM]} { + dict set meta_dict $path [dict create shorttype $ft {*}[array get arrstat]] + } else { + puts stderr "du_get_metadata_lists: file stat $testpath error: $errM" + dict lappend errors $path "file stat error: $errM" + dict set meta_dict $path [dict create shorttype $ft {*}$empty_stat_dict] + } } else { - puts stderr "du_get_metadata_lists: file stat $path error: $errM" - dict lappend errors $path "file stat error: $errM" - dict set meta_dict $path [dict create shorttype $ft {*}$empty_stat_dict] + #caller may have read perm on the containing folder - but not on child item - so file stat could raise an error + if {![catch {file stat $path arrstat} errM]} { + dict set meta_dict $path [dict create shorttype $ft {*}[array get arrstat]] + } else { + puts stderr "du_get_metadata_lists: file stat $path error: $errM" + dict lappend errors $path "file stat error: $errM" + dict set meta_dict $path [dict create shorttype $ft {*}$empty_stat_dict] + } } } } @@ -1481,7 +1497,7 @@ namespace eval punk::du { if {$ft in $sized_types} { dict set allsizes $path [dict create bytes [dict get $pathinfo size]] if {$ft eq "f"} { - #subst with na if empty? + #subst with na if empty? lappend fsizes [dict get $pathinfo size] if {[dict get $pathinfo size] eq ""} { puts stderr "du_get_metadata_lists: fsize $path is empty!" diff --git a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/nav/fs-0.1.0.tm b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/nav/fs-0.1.0.tm index 20a0849e..c9f744e0 100644 --- a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/nav/fs-0.1.0.tm +++ b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/nav/fs-0.1.0.tm @@ -792,7 +792,7 @@ tcl::namespace::eval punk::nav::fs { if {$searchspec eq ""} { set location } else { - if {$is_relativesarchspec} { + if {$is_relativesearchspec} { #set location [file dirname [file join $opt_searchbase $searchspec]] set location [punk::path::normjoin $searchbase $searchspec ..] } else { diff --git a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/repo-0.1.1.tm b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/repo-0.1.1.tm index 16f6f1cb..464baef6 100644 --- a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/repo-0.1.1.tm +++ b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/repo-0.1.1.tm @@ -1682,7 +1682,7 @@ namespace eval punk::repo { #whether path is at and/or below one of the vfs mount points #The design should facilitate nested vfs mountpoints proc path_vfs_info {filepath} { - error "unimplmented" + error "unimplemented" } #file normalize is expensive so this is too