mirror of
https://github.com/ohmyzsh/ohmyzsh.git
synced 2026-05-29 04:53:17 +02:00
fix(dotenv): reject extremely large named pipes
This commit is contained in:
parent
9b19287c88
commit
a30c63e011
2 changed files with 75 additions and 2 deletions
|
|
@ -202,7 +202,7 @@ parse_dotenv() {
|
|||
# Fail if file is too large to avoid DoS
|
||||
zmodload -F zsh/stat b:zstat
|
||||
local -i file_size max_size=10485760 # 10MiB
|
||||
if ! file_size=$(zstat -L +size "$filename" 2>/dev/null); then
|
||||
if ! file_size=$(zstat +size "$filename" 2>/dev/null); then
|
||||
echo "dotenv: unable to determine size of file '$filename'" >&2
|
||||
return 1
|
||||
fi
|
||||
|
|
@ -216,6 +216,39 @@ parse_dotenv() {
|
|||
_parse_dotenv_content "$content" "$mode"
|
||||
}
|
||||
|
||||
_dotenv_read_limited() {
|
||||
local filename="$1"
|
||||
local chunk content=""
|
||||
local -i max_size=10485760 total=0 read_size=0 fd read_status
|
||||
|
||||
zmodload zsh/system || return 1
|
||||
exec {fd}<"$filename" || return 1
|
||||
|
||||
while true; do
|
||||
sysread -i $fd -s 65536 -c read_size chunk
|
||||
read_status=$?
|
||||
|
||||
if (( read_status == 5 )); then
|
||||
break
|
||||
elif (( read_status != 0 )); then
|
||||
exec {fd}<&-
|
||||
return 1
|
||||
fi
|
||||
|
||||
(( total += read_size ))
|
||||
if (( total > max_size )); then
|
||||
exec {fd}<&-
|
||||
echo "dotenv: file '$filename' is too large to parse (size: more than $max_size bytes)" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
content+="$chunk"
|
||||
done
|
||||
|
||||
exec {fd}<&-
|
||||
REPLY="$content"
|
||||
}
|
||||
|
||||
_dotenv_check_syntax() {
|
||||
local filename="$1"
|
||||
|
||||
|
|
@ -272,7 +305,8 @@ source_env() {
|
|||
|
||||
local content
|
||||
if [[ -p "$ZSH_DOTENV_FILE" ]]; then
|
||||
content="$(<"$ZSH_DOTENV_FILE")" || return 1
|
||||
_dotenv_read_limited "$ZSH_DOTENV_FILE" || return 1
|
||||
content="$REPLY"
|
||||
_dotenv_check_syntax "$ZSH_DOTENV_FILE" "$content" || return 1
|
||||
|
||||
setopt localoptions allexport
|
||||
|
|
|
|||
|
|
@ -82,6 +82,45 @@
|
|||
assert "$result" equals 'secret'
|
||||
}
|
||||
|
||||
@test 'source_env rejects oversized named pipes' {
|
||||
run zsh -fc '
|
||||
source ./dotenv.plugin.zsh
|
||||
|
||||
tmpdir="$(mktemp -d "${TMPDIR:-/tmp}/dotenv.XXXXXX")" || exit 1
|
||||
fifo="$tmpdir/.env"
|
||||
command mkfifo "$fifo" || exit 1
|
||||
|
||||
cleanup() {
|
||||
kill $killer_pid 2>/dev/null || true
|
||||
kill $writer_pid 2>/dev/null || true
|
||||
wait $writer_pid 2>/dev/null || true
|
||||
command rm -rf "$tmpdir"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
(
|
||||
{
|
||||
print -rn -- "BIG="
|
||||
command dd if=/dev/zero bs=10485761 count=1 2>/dev/null | tr "\0" a
|
||||
} > "$fifo"
|
||||
) &
|
||||
writer_pid=$!
|
||||
|
||||
(
|
||||
sleep 2
|
||||
kill -0 $$ 2>/dev/null || exit 0
|
||||
kill $$ 2>/dev/null || exit 0
|
||||
) &
|
||||
killer_pid=$!
|
||||
|
||||
ZSH_DOTENV_PROMPT=false
|
||||
ZSH_DOTENV_FILE="$fifo"
|
||||
source_env >/dev/null 2>&1
|
||||
'
|
||||
|
||||
assert $state equals 1
|
||||
}
|
||||
|
||||
@test 'parse basic variable assignment' {
|
||||
> "$fixture" <<'EOF'
|
||||
# Basic assignments
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue