Merge pull request #2257 into stage-355

[codex] Fix start.sh dotenv filtering load (franksong2702)

# Conflicts:
#	CHANGELOG.md
This commit is contained in:
Hermes Agent
2026-05-14 15:13:39 +00:00
2 changed files with 14 additions and 17 deletions
+5 -1
View File
@@ -40,10 +40,14 @@ if [[ -f "${REPO_ROOT}/.env" ]]; then
# both `source` and `.env`.
# Sourced from PR #1686 (@binhpt310) — Cluster 1 (operational hardening),
# extracted to a focused follow-up after the parent PR was deferred.
_hermes_env_filtered="$(mktemp "${TMPDIR:-/tmp}/hermes-webui-env.XXXXXX")"
grep -vE '^[[:space:]]*(export[[:space:]]+)?(UID|GID|EUID|EGID|PPID)=' "${REPO_ROOT}/.env" > "${_hermes_env_filtered}" || true
set -a
# shellcheck source=/dev/null
source <(grep -vE '^[[:space:]]*(export[[:space:]]+)?(UID|GID|EUID|EGID|PPID)=' "${REPO_ROOT}/.env")
source "${_hermes_env_filtered}"
set +a
rm -f "${_hermes_env_filtered}"
unset _hermes_env_filtered
fi
PYTHON="${HERMES_WEBUI_PYTHON:-}"
+9 -16
View File
@@ -66,23 +66,16 @@ class TestStartShReadonlyEnvFilter:
f"'{var}: readonly variable'"
)
def test_filter_pattern_uses_grep_or_equivalent(self):
def test_filter_pattern_uses_grep_before_source(self):
"""Filter must use a pattern that strips readonly-var lines before
the bash `source` consumes them. `grep -vE` is the canonical form;
the assertion accepts any process-substitution-into-source shape."""
# Look for `source <(...UID...)` pattern. Note that the inner shell
# expression can contain its own parens (e.g. `(export[[:space:]]+)`),
# so we use a non-greedy `.*?` rather than `[^)]*`.
assert re.search(
r"source\s+<\(.*?UID.*?\)",
START_SH,
re.DOTALL,
), (
"start.sh's .env loader must filter readonly bash vars "
"(UID/GID/EUID/EGID/PPID) via `source <(grep -vE ...)` or "
"equivalent process-substitution form before `source`-ing "
"the .env file"
)
the bash `source` consumes them. The loader may use a temporary file
rather than process substitution because some bash/macOS combinations
can source an empty `/dev/fd/*` stream from `source <(grep ...)`."""
grep_idx = START_SH.find("grep -vE")
source_idx = START_SH.find("source", grep_idx)
assert grep_idx != -1, "start.sh must filter readonly vars with grep -vE or equivalent"
assert source_idx != -1, "start.sh must source the filtered .env stream"
assert grep_idx < source_idx, "readonly-var filtering must happen before source"
def test_filter_handles_optional_export_prefix(self):
"""The ``export`` prefix on env vars is optional but common. The