mirror of
https://github.com/msitarzewski/agency-agents.git
synced 2026-10-10 04:35:07 +00:00
fix(install): never follow a symlink when replacing the Hermes plugin
`rm -rf "$dest/"` follows a symlink and empties its target. basename ignores a trailing slash, so HERMES_PLUGIN_DIR=".../agency-agents-router/" passed every check, and a symlinked destination (our own --link install, or a user's folder) had its target's contents deleted. #903's ownership check didn't cover it: the check reads through the link and the rm still follows it. - Strip all trailing slashes from the destination before any check. - A symlinked destination is removed with `rm -f` (the link itself), never `rm -rf`. - test-install-hermes-destination.sh: two new cases (trailing slash on a symlink to a folder with a matching plugin.yaml; re-install over a --link install). Both fail before this commit and pass after. Found by a destructive-path matrix (25 scenarios, throwaway container, fake HOME with sentinel files): main fails 10 (deletes unrelated dirs, files and symlink targets at the plugin path); the series without this commit fails 2 (H8/H9); with it, 25/25. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
d2d2101c45
commit
d801ff90ad
+9
-1
@@ -1390,6 +1390,9 @@ install_hermes() {
|
||||
local src="$INTEGRATIONS/hermes/agency-agents-router"
|
||||
local hermes_home; hermes_home="$(hermes_home_dir)"
|
||||
local dest; dest="$(resolve_dest hermes "${hermes_home}/plugins/agency-agents-router")"
|
||||
# Strip trailing slashes first: basename ignores them, but `rm -rf link/`
|
||||
# follows a symlink and empties its target instead of removing the link.
|
||||
while [[ "$dest" == */ && "$dest" != "/" ]]; do dest="${dest%/}"; done
|
||||
# HERMES_PLUGIN_DIR is ambiguous: its name invites setting it to the plugins
|
||||
# parent (~/.hermes/plugins) rather than the full plugin path. Always target
|
||||
# the agency-agents-router subdir so we never rm -rf a shared plugins dir that
|
||||
@@ -1417,7 +1420,12 @@ install_hermes() {
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
rm -rf "$dest"
|
||||
# A symlink (e.g. from an earlier --link install) is replaced, never followed.
|
||||
if [[ -L "$dest" ]]; then
|
||||
rm -f -- "$dest"
|
||||
else
|
||||
rm -rf -- "$dest"
|
||||
fi
|
||||
if $USE_LINK; then
|
||||
ln -s "$src" "$dest"
|
||||
else
|
||||
|
||||
@@ -57,3 +57,30 @@ HOME="$fresh_home" bash "$repo/scripts/install.sh" --no-interactive --tool herme
|
||||
exit 1
|
||||
}
|
||||
echo 'PASS: fresh Hermes installation works normally'
|
||||
|
||||
# A trailing slash must not turn "replace the plugin" into "empty whatever a
|
||||
# symlink points at": `rm -rf link/` follows the link and deletes the target's
|
||||
# contents. Seen on real installs via HERMES_PLUGIN_DIR=".../agency-agents-router/".
|
||||
link_home="$tmp/link-home"
|
||||
link_plugin="$link_home/.hermes/plugins/agency-agents-router"
|
||||
personal="$tmp/personal"
|
||||
mkdir -p "$personal" "$(dirname "$link_plugin")"
|
||||
printf 'name: agency-agents-router\n' > "$personal/plugin.yaml"
|
||||
printf 'personal content\n' > "$personal/personal.txt"
|
||||
ln -s "$personal" "$link_plugin"
|
||||
HOME="$link_home" HERMES_PLUGIN_DIR="$link_plugin/" bash "$repo/scripts/install.sh" --no-interactive --tool hermes --no-convert > "$tmp/slash-output" 2>&1 || true
|
||||
[[ -f "$personal/personal.txt" ]] || {
|
||||
echo 'FAIL: a trailing slash deleted the contents of a symlinked directory' >&2
|
||||
exit 1
|
||||
}
|
||||
echo 'PASS: a trailing slash on a symlinked destination leaves its target intact'
|
||||
|
||||
relink_home="$tmp/relink-home"
|
||||
HOME="$relink_home" bash "$repo/scripts/install.sh" --no-interactive --tool hermes --no-convert --link > "$tmp/link-output" 2>&1
|
||||
HOME="$relink_home" HERMES_PLUGIN_DIR="$relink_home/.hermes/plugins/agency-agents-router/" \
|
||||
bash "$repo/scripts/install.sh" --no-interactive --tool hermes --no-convert > "$tmp/relink-output" 2>&1
|
||||
[[ -f "$repo/integrations/hermes/agency-agents-router/plugin.yaml" ]] || {
|
||||
echo 'FAIL: re-installing over a --link install deleted the plugin source in the clone' >&2
|
||||
exit 1
|
||||
}
|
||||
echo 'PASS: re-installing over a --link install keeps the clone intact'
|
||||
|
||||
Reference in New Issue
Block a user