From f00c8b92101cc472f6448fd17d3bf25c88107490 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 18 May 2026 13:32:17 +0000 Subject: [PATCH] fix(global_var): non-destructive .env writes; correct shell quoting Three minimum-scope robustness fixes in .templates/00-global_var.sh: 1. shell_quote no longer doubles backslashes inside single quotes (e.g. 'C:\Users\test' was producing 'C:\\Users\\test' in injected scripts) and now uses the canonical '\'' escape for single quotes instead of the buggy '"'"' + trailing-space-trim form, which was mangling values containing apostrophes (e.g. "it's" -> "it' s"). 2. /.env and /etc/environment are now patched in place: existing content from the upstream image and the system (PATH, LANG, etc.) is preserved and only the marked ADDON ENV block is replaced. Previously the whole files were overwritten, destroying upstream defaults. 3. Writing to /var/run/s6/container_environment is now best-effort (|| true) so a read-only mount on a single entry cannot abort the rest of the env injection under set -e. --- .templates/00-global_var.sh | 42 ++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/.templates/00-global_var.sh b/.templates/00-global_var.sh index 17fa18ee50..411eee44f7 100755 --- a/.templates/00-global_var.sh +++ b/.templates/00-global_var.sh @@ -82,11 +82,10 @@ dotenv_quote() { } shell_quote() { - # Single-quote for safe injection in shell code - local s="$1" - s="${s//\\/\\\\}" - s="${s//\'/\'\"\'\"\' }" - s="${s% }" + # Single-quote for safe injection in shell code. + # Inside single quotes only the single quote needs escaping ('->'\''). + # Do NOT escape backslashes: they are literal inside single quotes. + local s="${1//\'/\'\\\'\'}" printf "'%s'" "$s" } @@ -166,9 +165,9 @@ export_var() { # Runtime environment (no eval, safe for special chars) export "$k=$v" - # S6 environment (preferred for services) + # S6 environment (preferred for services); best-effort, tolerate RO mounts if [[ -d /var/run/s6/container_environment ]]; then - printf '%s' "$v" > "/var/run/s6/container_environment/$k" + printf '%s' "$v" > "/var/run/s6/container_environment/$k" || true fi # Queue for .env and /etc/environment (written once, idempotent) @@ -219,18 +218,31 @@ done < <( ) ################################################################################ -# Write .env and /etc/environment (idempotent: replace whole file content) +# Write .env and /etc/environment (idempotent: replace only our block, +# preserving any pre-existing content from the upstream image / system). # Notes: # - /.env is commonly used by apps expecting dotenv format # - /etc/environment is read by PAM/system tooling; KEY="value" is acceptable ################################################################################ -{ - echo "$BLOCK_BEGIN" - cat "$KV_FILE" - echo "$BLOCK_END" -} > "$ENV_FILE.tmp" -mv "$ENV_FILE.tmp" "$ENV_FILE" -cp "$ENV_FILE" "$ETC_ENV_FILE" +update_env_file() { + local f="$1" tmp + tmp="$(mktemp_safe)" + if [[ -f "$f" ]]; then + awk -v b="$BLOCK_BEGIN" -v e="$BLOCK_END" ' + $0==b { skip=1; next } + $0==e { skip=0; next } + !skip + ' "$f" > "$tmp" + fi + { + echo "$BLOCK_BEGIN" + cat "$KV_FILE" + echo "$BLOCK_END" + } >> "$tmp" + mv "$tmp" "$f" +} +update_env_file "$ENV_FILE" +update_env_file "$ETC_ENV_FILE" ################################################################################ # Inject into scripts and shells (best-effort)