What Happens
tool_shadow_path (host-setup/linux/install-tools.sh, fixed for plain PATH ordering and a single
trailing slash in #1644) still compares a PATH entry to $BIN_DIR with a literal string equality,
[[ $dir == "$BIN_DIR" ]]. A PATH entry that names the same directory through a different but
equivalent spelling, a doubled slash (/usr/local/bin//) or a dot segment (/usr/local/./bin),
does not match, so the walk treats $BIN_DIR's own managed binary as a shadow of itself.
The Property That Triggers It
A PATH containing $BIN_DIR spelled with a doubled slash or a . segment, ahead of the plain
spelling or with no plain spelling present at all. type -P, which the pre-#1644 code called,
already resolved this identically (type -P also returns the doubled or dotted spelling verbatim
for such an entry), so this is a pre-existing defect rather than one #1644 introduced.
Impact
tool_note reports the managed copy as "installed outside $BIN_DIR" or as shadowing itself.
apply_tool in --upgrade mode calls tool_unshadow, which prompts to remove the very binary
--upgrade is about to reinstall over. The user-visible effect is a confusing, spurious
remove-then-reinstall prompt rather than data loss, since the same file is what gets reinstalled
immediately after, but it undermines the report's claim that the location it names is a problem.
Repro (constructed, no host tool touched)
BIN_DIR=/usr/local/bin
mkdir -p /tmp/probe && printf '#!/bin/sh\necho ok\n' > /tmp/probe/widget && chmod +x /tmp/probe/widget
ln -s /tmp/probe /usr/local/bin_probe 2>/dev/null || true # illustrative only, not required to repro
PATH="/usr/local/bin//:$PATH" type -P widget # a real host would substitute the actual tool name
A PATH entry spelled $BIN_DIR// or $BIN_DIR/. produces a candidate path that string-compares
unequal to $BIN_DIR even though it names the same directory.
Suggested Fix
Normalize both sides before comparing, or use [[ $dir -ef $BIN_DIR ]] (bash's file-identity test,
confirmed to work on directories) as an additional check alongside the literal comparison, so a
directory that resolves to the same inode as $BIN_DIR is never reported as its own shadow.
Found during the local-strict-review pass on #1864 (the PR fixing #1644), scoped out of that PR
since it is a narrower, pre-existing edge case rather than part of the ordering defect #1644 fixed.
What Happens
tool_shadow_path(host-setup/linux/install-tools.sh, fixed for plain PATH ordering and a singletrailing slash in #1644) still compares a PATH entry to
$BIN_DIRwith a literal string equality,[[ $dir == "$BIN_DIR" ]]. A PATH entry that names the same directory through a different butequivalent spelling, a doubled slash (
/usr/local/bin//) or a dot segment (/usr/local/./bin),does not match, so the walk treats
$BIN_DIR's own managed binary as a shadow of itself.The Property That Triggers It
A
PATHcontaining$BIN_DIRspelled with a doubled slash or a.segment, ahead of the plainspelling or with no plain spelling present at all.
type -P, which the pre-#1644 code called,already resolved this identically (
type -Palso returns the doubled or dotted spelling verbatimfor such an entry), so this is a pre-existing defect rather than one #1644 introduced.
Impact
tool_notereports the managed copy as "installed outside $BIN_DIR" or as shadowing itself.apply_toolin--upgrademode callstool_unshadow, which prompts to remove the very binary--upgradeis about to reinstall over. The user-visible effect is a confusing, spuriousremove-then-reinstall prompt rather than data loss, since the same file is what gets reinstalled
immediately after, but it undermines the report's claim that the location it names is a problem.
Repro (constructed, no host tool touched)
A PATH entry spelled
$BIN_DIR//or$BIN_DIR/.produces a candidate path that string-comparesunequal to
$BIN_DIReven though it names the same directory.Suggested Fix
Normalize both sides before comparing, or use
[[ $dir -ef $BIN_DIR ]](bash's file-identity test,confirmed to work on directories) as an additional check alongside the literal comparison, so a
directory that resolves to the same inode as
$BIN_DIRis never reported as its own shadow.Found during the local-strict-review pass on #1864 (the PR fixing #1644), scoped out of that PR
since it is a narrower, pre-existing edge case rather than part of the ordering defect #1644 fixed.