mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-06-12 19:38:03 +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>
|
2024-02-22 Oliver Kiddle <opk@zsh.org>
|
||||||
|
|
||||||
* 52552: Completion/Unix/Command/_java: newer Java supports
|
* 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) :
|
gethashnode2(paramtab, name) :
|
||||||
paramtab->getnode(paramtab, name));
|
paramtab->getnode(paramtab, name));
|
||||||
|
|
||||||
if (oldpm && (oldpm->node.flags & PM_NAMEREF) &&
|
if (oldpm && (oldpm->node.flags & PM_RO_BY_DESIGN)) {
|
||||||
!(flags & PM_NAMEREF) && (oldpm = upscope(oldpm, oldpm->base))) {
|
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;
|
Param lastpm;
|
||||||
struct asgment stop;
|
struct asgment stop;
|
||||||
stop.flags = PM_NAMEREF | (flags & PM_LOCAL);
|
stop.flags = PM_NAMEREF | (flags & PM_LOCAL);
|
||||||
|
|
|
@ -311,6 +311,47 @@ F:future revision will create a global with this assignment
|
||||||
>TOP
|
>TOP
|
||||||
>UP:
|
>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
|
typeset -n ptr1=ptr2
|
||||||
private -n ptr2 # TYPESET_TO_UNSET makes this not a "placeholder"
|
private -n ptr2 # TYPESET_TO_UNSET makes this not a "placeholder"
|
||||||
|
|
Loading…
Reference in a new issue