function: Error out for read-only variables

This will refuse to define the function instead of defining it with an
unusable argument.

Fixes #10842
This commit is contained in:
Fabian Boehm 2024-11-11 17:50:20 +01:00
parent 0ef811c86e
commit 960415db3f
2 changed files with 25 additions and 1 deletions

View File

@ -3,6 +3,7 @@ use crate::ast::BlockStatement;
use crate::common::{valid_func_name, valid_var_name}; use crate::common::{valid_func_name, valid_var_name};
use crate::complete::complete_add_wrapper; use crate::complete::complete_add_wrapper;
use crate::env::environment::Environment; use crate::env::environment::Environment;
use crate::env::is_read_only;
use crate::event::{self, EventDescription, EventHandler}; use crate::event::{self, EventDescription, EventHandler};
use crate::function; use crate::function;
use crate::global_safety::RelaxedAtomicBool; use crate::global_safety::RelaxedAtomicBool;
@ -172,8 +173,17 @@ fn parse_cmd_opts(
opts.events.push(e); opts.events.push(e);
} }
'a' => { 'a' => {
let name = w.woptarg.unwrap().to_owned();
if is_read_only(&name) {
streams.err.append(wgettext_fmt!(
"%ls: variable '%ls' is read-only\n",
cmd,
name
));
return STATUS_INVALID_ARGS;
}
handling_named_arguments = true; handling_named_arguments = true;
opts.named_arguments.push(w.woptarg.unwrap().to_owned()); opts.named_arguments.push(name);
} }
'S' => { 'S' => {
opts.shadow_scope = false; opts.shadow_scope = false;

View File

@ -162,6 +162,8 @@ end
rm -r $tmpdir rm -r $tmpdir
functions -e foo
function foo -p bar; end function foo -p bar; end
# CHECKERR: {{.*}}function.fish (line {{\d+}}): function: bar: invalid process id # CHECKERR: {{.*}}function.fish (line {{\d+}}): function: bar: invalid process id
# CHECKERR: function foo -p bar; end # CHECKERR: function foo -p bar; end
@ -173,4 +175,16 @@ function foo --argument-names "banana pajama"; end
# CHECKERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ # CHECKERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
function foo --argument-names status; end
# CHECKERR: {{.*}}function.fish (line {{\d+}}): function: variable 'status' is read-only
# CHECKERR: function foo --argument-names status; end
# CHECKERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
echo status $status
# CHECK: status 2
functions -q foo
echo exists $status
# CHECK: exists 1
exit 0 exit 0