mirror of
https://github.com/ohmyzsh/ohmyzsh.git
synced 2026-05-29 04:53:17 +02:00
Some checks failed
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
* fix(dotenv): expect explicit yes before loading .env file * fix(dotenv): implement secure parsing for .env files and add comprehensive tests * feat(dotenv): check for .env file size to prevent DoS * fix(dotenv): forbid setting special variables * fix(dotenv): FIFO shouldn't be read twice * fix(dotenv): unknown vars should expand to empty * fix(dotenv): reject extremely large named pipes * docs(dotenv): update to new parsing system * fix(dotenv): add support for escaped dollars * chore(dotenv): only declare local variables once * fix(dotenv): apply review suggestions * docs(dotenv): update test instructions Co-authored-by: Carlo Sala <carlosalag@protonmail.com>
139 lines
3.9 KiB
Bash
139 lines
3.9 KiB
Bash
#!/usr/bin/env zsh
|
|
# Bootstrap script for dotenv plugin tests
|
|
# This is sourced before any tests run and provides shared utilities
|
|
|
|
# Load the dotenv plugin
|
|
source "$PWD/dotenv.plugin.zsh"
|
|
ZSH_DOTENV_PROMPT=false
|
|
ZSH_DOTENV_FILE=/dev/null
|
|
|
|
# Helper: Parse dotenv file in test mode
|
|
_parse_dotenv_test() {
|
|
parse_dotenv "$1" "test"
|
|
}
|
|
|
|
# Helper: Parse dotenv file in export mode
|
|
_parse_dotenv_export() {
|
|
unset "${(k)parameters[(R)*export*]}" 2>/dev/null || true
|
|
|
|
parse_dotenv "$1" "test"
|
|
|
|
for key in "${(k)DOTENV_TEST_VARS}"; do
|
|
typeset -x "$key"="${DOTENV_TEST_VARS[$key]}"
|
|
done
|
|
}
|
|
|
|
# Helper: Run parse_dotenv suppressing stderr
|
|
_parse_dotenv_quiet() {
|
|
parse_dotenv "$@" 2>/dev/null
|
|
}
|
|
|
|
# Helper: Create a temporary test fixture
|
|
_create_temp_fixture() {
|
|
local fixture
|
|
fixture==(:) # Create temp file
|
|
echo "$fixture"
|
|
}
|
|
|
|
_write_temp_fixture() {
|
|
local fixture="$1"
|
|
> "$fixture"
|
|
}
|
|
|
|
|
|
# Helper: Source file with allexport and capture variables
|
|
# Usage: _source_with_allexport "file.env"
|
|
# Result is in DOTENV_SOURCE_VARS associative array
|
|
_source_with_allexport() {
|
|
local filename="$1"
|
|
|
|
# Source with allexport in a subshell with no exported variables
|
|
|
|
# The return and capture of the exported variables is a bit of a pain:
|
|
# 1. We first store the key=value pairs in $vars associative array, which is
|
|
# defined before allexport is set to avoid appearing in results.
|
|
# 2. Afterwards, we join all keys and values of the associative with null delimiters. With
|
|
# "$(@kv)vars}" we get keys and values with quotes, to retain empty values. With (pj:\0:)
|
|
# we join them with nulls.
|
|
# 3. The caller reads this output with "${(@0)}" to split by nulls and quoting to retain
|
|
# empty values, and then uses it to populate an associative array.
|
|
# Don't try to understand this or change it unless you have to. Debugging is a nightmare.
|
|
typeset -gA DOTENV_SOURCE_VARS
|
|
DOTENV_SOURCE_VARS=("${(@0)"$(
|
|
local -A vars
|
|
|
|
# Clear all exports first
|
|
zmodload zsh/parameter
|
|
unset ${(k)parameters[(R)*export*]} 2>/dev/null || true
|
|
|
|
# Source file with allexport
|
|
setopt localoptions allexport
|
|
source "$filename"
|
|
|
|
# Set all exported variables into an associative array
|
|
for key in ${(k)parameters[(R)*export*]}; do
|
|
vars[$key]="${(P)key}"
|
|
done
|
|
|
|
print -rn -- "${(@kvpj:\0:)vars}"
|
|
)"}")
|
|
}
|
|
|
|
|
|
## ZUnit assertion helpers
|
|
|
|
_zunit_assert_function_exists() {
|
|
[[ "${+functions[$1]}" -eq 1 ]] && return 0
|
|
echo "Function '$1' does not exist"
|
|
exit 1
|
|
}
|
|
|
|
_zunit_assert_var_same_as() {
|
|
local tvalue=${${:-${(Pt)1%-*}}:-unset} tcomp=${${:-${(Pt)2%-*}}:-unset}
|
|
if [[ $tvalue != $tcomp ]]; then
|
|
echo "Type mismatch: '$1' ($tvalue) and '$2' ($tcomp)"
|
|
exit 78
|
|
fi
|
|
|
|
# Special case for associative arrays
|
|
if [[ ${(Pt)1} == "association" ]]; then
|
|
local -A value=("${(P@kv)1}") comparison=("${(P@kv)2}")
|
|
local -aU keys=("${(@k)value}" "${(@k)comparison}")
|
|
|
|
local ret=0 key
|
|
for key in "${keys[@]}"; do
|
|
# Key match checks
|
|
if [[ -v "value[$key]" && ! -v "comparison[$key]" ]]; then
|
|
echo "'$1[$key]' is set (value='${value[$key]}')"
|
|
ret=1
|
|
elif [[ ! -v "value[$key]" && -v "comparison[$key]" ]]; then
|
|
echo "'$1[$key]' is not set (expected='${comparison[$key]}')"
|
|
ret=1
|
|
# Value match checks
|
|
elif [[ "${value[$key]}" != "${comparison[$key]}" ]]; then
|
|
echo "'$1[$key]' value mismatch: '${value[$key]}' is not the same as '${comparison[$key]}'"
|
|
ret=1
|
|
fi
|
|
done
|
|
|
|
exit $ret
|
|
fi
|
|
|
|
# Generic case
|
|
local value="${(P)1}" comparison="${(P)2}"
|
|
[[ "$value" != "$comparison" ]] || exit 0
|
|
echo "'$1' value mismatch: '$value' is not the same as '$comparison'"
|
|
exit 1
|
|
}
|
|
|
|
_zunit_assert_var_is_set() {
|
|
[[ -v "$1" ]] && return 0
|
|
echo "Variable '$1' is not set"
|
|
exit 1
|
|
}
|
|
|
|
_zunit_assert_var_is_not_set() {
|
|
[[ ! -v "$1" ]] && return 0
|
|
echo "Variable '$1' is set"
|
|
exit 1
|
|
}
|