Forbid $status as a command

This is slightly unclean. Even tho it would otherwise be syntactically
valid, using $status as a command is very very very likely to be an
error, like

    if not $status

We have reports of this surprisingly regularly, including #2773.

Because $status can only ever be a value from 0 to 255, it is also
very unlikely to be an actual command, and that command is very
unlikely to do what you want.

So we simply point the user towards the "conditions" help section,
that should explain things.
This commit is contained in:
Fabian Homborg 2021-07-26 21:29:02 +02:00
parent b9ba3020f8
commit 08209b3d9a
2 changed files with 31 additions and 1 deletions

View File

@ -1124,6 +1124,16 @@ static bool detect_errors_in_decorated_statement(const wcstring &buff_src,
}
}
// $status specifically is invalid as a command,
// to avoid people trying `if $status`.
// We see this surprisingly regularly.
const wcstring &com = dst.command.source(buff_src, storage);
if (com == L"$status") {
parse_error_offset_source_start(parse_errors, source_start);
errored = append_syntax_error(parse_errors, source_start,
_(L"$status is not valid as a command. See `help conditions`"));
}
const wcstring &unexp_command = dst.command.source(buff_src, storage);
if (!unexp_command.empty()) {
wcstring command;

View File

@ -1,4 +1,4 @@
#RUN: %fish %s
#RUN: %fish -C 'set -g fish (builtin realpath %fish)' %s
# Test that using variables as command names work correctly.
$EMPTY_VARIABLE
@ -27,4 +27,24 @@ set CMD3 /usr/bin
$CMD3 && echo $PWD
#CHECK: /usr/bin
# $status specifically is not valid, to avoid a common error
# with `if $status`
echo 'if $status; echo foo; end' | $fish --no-config
#CHECKERR: fish: $status is not valid as a command. See `help conditions`
#CHECKERR: if $status; echo foo; end
#CHECKERR: ^
echo 'not $status' | $fish --no-config
#CHECKERR: fish: $status is not valid as a command. See `help conditions`
#CHECKERR: not $status
#CHECKERR: ^
# Script doesn't run at all.
echo 'echo foo; and $status' | $fish --no-config
#CHECKERR: fish: $status is not valid as a command. See `help conditions`
#CHECKERR: echo foo; and $status
#CHECKERR: ^
echo 'set -l status_cmd true; if $status_cmd; echo Heck yes this is true; end' | $fish --no-config
#CHECK: Heck yes this is true
exit 0