mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-28 04:03:39 +08:00
af7f5f42b6
This puts a hard upper bound of 10 MiB on the amount of data that read will consume. This is to avoid having the shell consume an unreasonable amount of memory, possibly causing the system to enter a OOM condition, if the user does something non-sensical. Fixes #3712
190 lines
4.9 KiB
Fish
190 lines
4.9 KiB
Fish
# vim: set filetype=fish:
|
|
#
|
|
# Test read builtin and IFS.
|
|
#
|
|
count (echo one\ntwo)
|
|
set -l IFS \t
|
|
count (echo one\ntwo)
|
|
set -l IFS
|
|
count (echo one\ntwo)
|
|
echo [(echo -n one\ntwo)]
|
|
count (echo one\ntwo\n)
|
|
echo [(echo -n one\ntwo\n)]
|
|
count (echo one\ntwo\n\n)
|
|
echo [(echo -n one\ntwo\n\n)]
|
|
set -le IFS
|
|
|
|
function print_vars --no-scope-shadowing
|
|
set -l space
|
|
set -l IFS \n # ensure our command substitution works right
|
|
for var in $argv
|
|
echo -n $space (count $$var) \'$$var\'
|
|
set space ''
|
|
end
|
|
echo
|
|
end
|
|
|
|
echo
|
|
echo 'hello there' | read -l one two
|
|
print_vars one two
|
|
echo 'hello there' | read -l one
|
|
print_vars one
|
|
echo '' | read -l one
|
|
print_vars one
|
|
echo '' | read -l one two
|
|
print_vars one two
|
|
echo 'test' | read -l one two three
|
|
print_vars one two three
|
|
echo 'foo bar baz' | read -l one two three
|
|
print_vars one two three
|
|
echo -n 'a' | read -l one
|
|
echo "$status $one"
|
|
|
|
echo
|
|
set -l IFS
|
|
echo 'hello' | read -l one
|
|
print_vars one
|
|
echo 'hello' | read -l one two
|
|
print_vars one two
|
|
echo 'hello' | read -l one two three
|
|
print_vars one two three
|
|
echo '' | read -l one
|
|
print_vars one
|
|
echo 't' | read -l one two
|
|
print_vars one two
|
|
echo 't' | read -l one two three
|
|
print_vars one two three
|
|
echo ' t' | read -l one two
|
|
print_vars one two
|
|
set -le IFS
|
|
|
|
echo
|
|
echo 'hello there' | read -la ary
|
|
print_vars ary
|
|
echo 'hello' | read -la ary
|
|
print_vars ary
|
|
echo 'this is a bunch of words' | read -la ary
|
|
print_vars ary
|
|
echo ' one two three' | read -la ary
|
|
print_vars ary
|
|
echo '' | read -la ary
|
|
print_vars ary
|
|
|
|
echo
|
|
set -l IFS
|
|
echo 'hello' | read -la ary
|
|
print_vars ary
|
|
echo 'h' | read -la ary
|
|
print_vars ary
|
|
echo '' | read -la ary
|
|
print_vars ary
|
|
set -le IFS
|
|
|
|
# read -n tests
|
|
|
|
echo
|
|
echo '# read -n tests'
|
|
echo 'testing' | read -n 3 foo
|
|
echo $foo
|
|
echo 'test' | read -n 10 foo
|
|
echo $foo
|
|
echo 'test' | read -n 0 foo
|
|
echo $foo
|
|
echo 'testing' | begin; read -n 3 foo; read -n 3 bar; end
|
|
echo $foo
|
|
echo $bar
|
|
echo 'test' | read -n 1 foo
|
|
echo $foo
|
|
|
|
# read -0 tests
|
|
|
|
echo
|
|
echo '# read -z tests'
|
|
echo -n 'testing' | read -lz foo
|
|
echo $foo
|
|
echo -n 'test ing' | read -lz foo
|
|
echo $foo
|
|
echo 'newline' | read -lz foo
|
|
echo $foo
|
|
echo -n 'test ing' | read -lz foo bar
|
|
print_vars foo bar
|
|
echo -ne 'test\0ing' | read -lz foo bar
|
|
print_vars foo bar
|
|
echo -ne 'foo\nbar' | read -lz foo bar
|
|
print_vars foo bar
|
|
echo -ne 'foo\nbar\0baz\nquux' | while read -lza foo
|
|
print_vars foo
|
|
end
|
|
|
|
echo
|
|
echo '# chunked read tests'
|
|
set -l path /tmp/fish_chunked_read_test.txt
|
|
set -l longstr (seq 1024 | string join ',')
|
|
echo -n $longstr > $path
|
|
read -l longstr2 < $path
|
|
test "$longstr" = "$longstr2"
|
|
and echo "Chunked reads test pass"
|
|
or echo "Chunked reads test failure: long strings don't match!"
|
|
rm $path
|
|
|
|
# ==========
|
|
# The following tests verify that `read` correctly handles the limit on the
|
|
# number of bytes consumed.
|
|
#
|
|
set FISH_READ_BYTE_LIMIT 8192
|
|
set line abcdefghijklmnopqrstuvwxyz
|
|
|
|
# Ensure the `read` command terminates if asked to read too much data. The var
|
|
# should be empty. We throw away any data we read if it exceeds the limit on
|
|
# what we consider reasonable.
|
|
yes $line | dd bs=1024 count=(math "1 + $FISH_READ_BYTE_LIMIT / 1024") ^/dev/null | read --null x
|
|
if test $status -ne 122
|
|
echo reading too much data did not terminate with failure status
|
|
end
|
|
if test (string length "$x") -ne 0
|
|
echo reading too much data resulted in a var with unexpected data
|
|
end
|
|
|
|
# Ensure the `read` command terminates if asked to read too much data even if
|
|
# given an explicit limit. The var should be empty. We throw away any data we
|
|
# read if it exceeds the limit on what we consider reasonable.
|
|
yes $line | read --null --nchars=(math "$FISH_READ_BYTE_LIMIT + 1") x
|
|
if test $status -ne 122
|
|
echo reading too much data did not terminate with failure status
|
|
end
|
|
if test (string length "$x") -ne 0
|
|
echo reading too much data resulted in a var with unexpected data
|
|
end
|
|
|
|
# Now do the opposite of the previous test and confirm we can read reasonable
|
|
# amounts of data.
|
|
echo $line | read x
|
|
if test $status -ne 0
|
|
echo the read of a reasonable amount of data failed unexpectedly
|
|
end
|
|
set exp_length (string length $x)
|
|
set act_length (string length $line)
|
|
if test $exp_length -ne $act_length
|
|
echo reading a reasonable amount of data failed the length test
|
|
echo expected length $exp_length, actual length $act_length
|
|
end
|
|
|
|
# Confirm we can read exactly up to the limit.
|
|
yes $line | read --null --nchars $FISH_READ_BYTE_LIMIT x
|
|
if test $status -ne 0
|
|
echo the read of the max amount of data with --nchars failed unexpectedly
|
|
end
|
|
if test (string length "$x") -ne $FISH_READ_BYTE_LIMIT
|
|
echo reading the max amount of data with --nchars failed the length test
|
|
end
|
|
|
|
# Same as previous test but limit the amount of data fed to `read` rather than
|
|
# using the `--nchars` flag.
|
|
yes $line | dd bs=1024 count=(math "$FISH_READ_BYTE_LIMIT / 1024") ^/dev/null | read --null x
|
|
if test $status -ne 0
|
|
echo the read of the max amount of data failed unexpectedly
|
|
end
|
|
if test (string length "$x") -ne $FISH_READ_BYTE_LIMIT
|
|
echo reading the max amount of data with --nchars failed the length test
|
|
end
|