diff options
author | Bart Schaefer <schaefer@zsh.org> | 2025-03-31 15:25:34 -0700 |
---|---|---|
committer | Bart Schaefer <schaefer@zsh.org> | 2025-03-31 15:25:34 -0700 |
commit | e7163e69d90f8dcd5cdeea054df929b635f89260 (patch) | |
tree | fcc4c39b74fe2ffd8685bd12d072febaf147883a | |
parent | b707a60351bb9224fb808b3155dfef3288eef039 (diff) | |
download | zsh-e7163e69d90f8dcd5cdeea054df929b635f89260.tar.gz zsh-e7163e69d90f8dcd5cdeea054df929b635f89260.zip |
53431: fix assignment via named reference to parameters in outer scopes
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | Src/params.c | 6 | ||||
-rw-r--r-- | Test/K01nameref.ztst | 47 |
3 files changed, 56 insertions, 2 deletions
@@ -1,4 +1,7 @@ -2025-03-31 Bart Schaefer <schaefer@zsh.org> +2025-03-31 Bart Schaefer <schaefer@toltec-ubuntu> + + * 53431: Src/params.c, Test/K01nameref.ztst: fix assignment via + named reference to parameters in outer scopes; add tests * Frank Dana: 53414: Functions/Prompts/prompt_restore_setup: attempting to preview the "restore" keyword is nonsensical, diff --git a/Src/params.c b/Src/params.c index d1c06b893..c10236a0d 100644 --- a/Src/params.c +++ b/Src/params.c @@ -6395,7 +6395,9 @@ setscope(Param pm) } } else pm->base = basepm->level; - } + } else if (pm->base < locallevel && refname && + (basepm = (Param)getparamnode(realparamtab, refname))) + pm->base = basepm->level; if (pm->base > pm->level) { if (EMULATION(EMULATE_KSH)) { zerr("%s: global reference cannot refer to local variable", @@ -6420,6 +6422,8 @@ upscope(Param pm, int reflevel) { Param up = pm->old; while (up && up->level >= reflevel) { + if (reflevel < 0 && up->level < locallevel) + break; pm = up; up = up->old; } diff --git a/Test/K01nameref.ztst b/Test/K01nameref.ztst index bacc3ade2..1603ab1b9 100644 --- a/Test/K01nameref.ztst +++ b/Test/K01nameref.ztst @@ -595,6 +595,53 @@ F:Same test, should part 5 output look like this? >nameref-local-nameref-local >typeset -h parameters + ( + inner() { local -n var="${1:?}"; var=(alpha beta gamma); } + outer() { local -a foo=(outer); inner foo; typeset -p foo; } + foo=3 ; { outer foo } always { typeset -p foo } + ) +0:up-reference part 10, assignment to enclosing scope, types match +>typeset -a foo=( alpha beta gamma ) +>typeset -g foo=3 + + ( + inner() { local -n var="${1:?}"; var=(alpha beta gamma); } + outer() { local foo=outer; inner foo; typeset -p foo; } + foo=3 ; { outer foo } always { typeset -p foo } + ) +1:up-reference part 11, assignment to enclosing scope, type mismatch +>typeset -g foo=3 +?inner: foo: attempt to assign array value to non-array + + ( + inner() { local -n var="${1:?}"; unset var; var=(alpha beta gamma); } + outer() { local foo=outer; inner foo; typeset -p foo; } + foo=3 ; { outer foo } always { typeset -p foo } + ) +0:up-reference part 12, assignment to enclosing scope, unset by reference +>typeset -a foo=( alpha beta gamma ) +>typeset -g foo=3 + + ( + inner() { local "${1:?}"; local -nu var="$1"; var=(alpha beta gamma); } + outer() { local -a foo=(outer); inner foo; typeset -p foo; } + foo=3 ; { outer foo } always { typeset -p foo } + ) +0:up-reference part 13, assignment to enclosing scope, skip local +>typeset -a foo=( alpha beta gamma ) +>typeset -g foo=3 + + ( + inner() { local "${1:?}"; local -nu var="$1"; + typeset -g var=(alpha beta gamma); } + outer() { local -a foo=(outer); inner foo; typeset -p foo; } + foo=3 ; { outer foo } always { typeset -p foo } + ) +0f:up-reference part 14, typeset -g to enclosing scope, skip local +F:typeset cannot bypass a name in the local scope, even via nameref +>typeset -a foo=( alpha beta gamma ) +>typeset -g foo=3 + if [[ $options[typesettounset] != on ]]; then ZTST_skip='Ignoring zmodload bug that resets TYPESET_TO_UNSET' setopt typesettounset |