fish-shell/tests/read.in
Kurtis Rader af7f5f42b6 put upper bound on data read will consume
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
2017-02-09 21:04:46 -08:00

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