fix(dotenv): add support for escaped dollars

This commit is contained in:
Carlo Sala 2026-04-16 20:34:15 +02:00
commit d30724763f
No known key found for this signature in database
GPG key ID: DA6FB450C1A4FE9A
2 changed files with 29 additions and 3 deletions

View file

@ -143,11 +143,9 @@ _parse_dotenv_content() {
fi
## END: FILTER COMMAND EXPANSION
# Unquote the value to handle special characters and multiline values
value="${(Q)value}"
# Single-quoted values are fully literal and must not participate in expansion.
if [[ "$raw_value" == \'*\' ]]; then
value="${(Q)value}"
parsed_vars[$key]="$value"
if [[ "$mode" == "export" ]]; then
typeset -x "$key"="$value"
@ -155,6 +153,13 @@ _parse_dotenv_content() {
continue
fi
# Preserve escaped dollars so they remain literal after unquoting.
local escaped_dollar_placeholder=$'\001DOTENV_ESCAPED_DOLLAR\001'
value="${value//\\\$/$escaped_dollar_placeholder}"
# Unquote the value to handle special characters and multiline values.
value="${(Q)value}"
# Expand previously parsed in-file variables without partial name matches.
local expanded="" prefix remainder="$value" var_name
while [[ "$remainder" == *'$'* ]]; do
@ -179,6 +184,7 @@ _parse_dotenv_content() {
fi
done
value="${expanded}${remainder}"
value="${value//$escaped_dollar_placeholder/\$}"
# Store in parsed vars (for in-file expansion)
parsed_vars[$key]="$value"

View file

@ -366,3 +366,23 @@ EOF
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}
@test 'parse preserves escaped dollar signs before variable expansion' {
> "$fixture" <<'EOF'
BAR=expanded
ESCAPED_UNQUOTED=foo\$BAR
ESCAPED_DOUBLE="foo\$BAR"
ESCAPED_BRACED="\${BAR}"
EOF
expected_vars=(
BAR 'expanded'
ESCAPED_UNQUOTED 'foo$BAR'
ESCAPED_DOUBLE 'foo$BAR'
ESCAPED_BRACED '${BAR}'
)
_parse_dotenv_test "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}