mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-05-21 12:01:54 +02:00
52583: extra check for proper scope and existence of readonly specials
This commit is contained in:
parent
40d5200c8b
commit
4b9cd6b8bd
3 changed files with 70 additions and 2 deletions
|
@ -1,3 +1,9 @@
|
|||
2024-02-23 Bart Schaefer <schaefer@zsh.org>
|
||||
|
||||
* 52583: Src/params.c, Test/V10private.ztst: do an extra check
|
||||
for proper scope and parameter existence when assigning to a
|
||||
non-local name that resolves to a readonly special.
|
||||
|
||||
2024-02-22 Oliver Kiddle <opk@zsh.org>
|
||||
|
||||
* 52552: Completion/Unix/Command/_java: newer Java supports
|
||||
|
|
25
Src/params.c
25
Src/params.c
|
@ -1004,8 +1004,29 @@ createparam(char *name, int flags)
|
|||
gethashnode2(paramtab, name) :
|
||||
paramtab->getnode(paramtab, name));
|
||||
|
||||
if (oldpm && (oldpm->node.flags & PM_NAMEREF) &&
|
||||
!(flags & PM_NAMEREF) && (oldpm = upscope(oldpm, oldpm->base))) {
|
||||
if (oldpm && (oldpm->node.flags & PM_RO_BY_DESIGN)) {
|
||||
if (!(flags & PM_LOCAL)) {
|
||||
/* Must call the API for namerefs and specials to work */
|
||||
pm = (Param) paramtab->getnode2(paramtab, oldpm->node.nam);
|
||||
if (!pm || ((pm->node.flags & PM_NAMEREF) &&
|
||||
pm->level != locallevel)) {
|
||||
zerr("%s: can't modify read-only parameter", name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Implementation note: In the case of a readonly nameref,
|
||||
* the right thing might be to insert a new global into
|
||||
* the paramtab and point the local pm->old at it, rather
|
||||
* than error. That is why gethashnode2() is called
|
||||
* first, to avoid skipping up the stack prematurely.
|
||||
**/
|
||||
}
|
||||
|
||||
if (oldpm && !(flags & PM_NAMEREF) &&
|
||||
(!(oldpm->node.flags & PM_RO_BY_DESIGN) || !(flags & PM_LOCAL)) &&
|
||||
(oldpm->node.flags & PM_NAMEREF) &&
|
||||
(oldpm = upscope(oldpm, oldpm->base))) {
|
||||
Param lastpm;
|
||||
struct asgment stop;
|
||||
stop.flags = PM_NAMEREF | (flags & PM_LOCAL);
|
||||
|
|
|
@ -311,6 +311,47 @@ F:future revision will create a global with this assignment
|
|||
>TOP
|
||||
>UP:
|
||||
|
||||
() {
|
||||
typeset -a ary
|
||||
local -P -n ref=ary
|
||||
{
|
||||
(){
|
||||
ref=XX # Should be an error
|
||||
typeset -p ary ref
|
||||
}
|
||||
} always {
|
||||
TRY_BLOCK_ERROR=0
|
||||
typeset -p ary ref
|
||||
}
|
||||
}
|
||||
typeset -p ary
|
||||
1:assignment to private nameref in wrong scope, part 1
|
||||
>typeset -a ary
|
||||
>typeset -hn ref=ary
|
||||
*?*ref: can't modify read-only parameter
|
||||
*?*no such variable: ary
|
||||
|
||||
() {
|
||||
typeset -a ary
|
||||
local -P -n ref=ary
|
||||
{
|
||||
(){
|
||||
typeset ref=XX # Should create a local
|
||||
typeset -p ary ref
|
||||
}
|
||||
} always {
|
||||
TRY_BLOCK_ERROR=0
|
||||
typeset -p ary ref
|
||||
}
|
||||
}
|
||||
typeset -p ary
|
||||
1:assignment to private nameref in wrong scope, part 2
|
||||
>typeset -g -a ary
|
||||
>typeset ref=XX
|
||||
>typeset -a ary
|
||||
>typeset -hn ref=ary
|
||||
*?*no such variable: ary
|
||||
|
||||
() {
|
||||
typeset -n ptr1=ptr2
|
||||
private -n ptr2 # TYPESET_TO_UNSET makes this not a "placeholder"
|
||||
|
|
Loading…
Reference in a new issue