From 960415db3fe6029d26a1127b8f851eb51dd51865 Mon Sep 17 00:00:00 2001 From: Fabian Boehm Date: Mon, 11 Nov 2024 17:50:20 +0100 Subject: [PATCH] function: Error out for read-only variables This will refuse to define the function instead of defining it with an unusable argument. Fixes #10842 --- src/builtins/function.rs | 12 +++++++++++- tests/checks/function.fish | 14 ++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/builtins/function.rs b/src/builtins/function.rs index 241f4a1b8..1b198c21f 100644 --- a/src/builtins/function.rs +++ b/src/builtins/function.rs @@ -3,6 +3,7 @@ use crate::ast::BlockStatement; use crate::common::{valid_func_name, valid_var_name}; use crate::complete::complete_add_wrapper; use crate::env::environment::Environment; +use crate::env::is_read_only; use crate::event::{self, EventDescription, EventHandler}; use crate::function; use crate::global_safety::RelaxedAtomicBool; @@ -172,8 +173,17 @@ fn parse_cmd_opts( opts.events.push(e); } '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; - opts.named_arguments.push(w.woptarg.unwrap().to_owned()); + opts.named_arguments.push(name); } 'S' => { opts.shadow_scope = false; diff --git a/tests/checks/function.fish b/tests/checks/function.fish index ca6b88fba..bf71723be 100644 --- a/tests/checks/function.fish +++ b/tests/checks/function.fish @@ -162,6 +162,8 @@ end rm -r $tmpdir +functions -e foo + function foo -p bar; end # CHECKERR: {{.*}}function.fish (line {{\d+}}): function: bar: invalid process id # CHECKERR: function foo -p bar; end @@ -173,4 +175,16 @@ function foo --argument-names "banana pajama"; end # 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