1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2024-05-06 07:36:20 +02:00

52583: extra check for proper scope and existence of readonly specials

This commit is contained in:
Bart Schaefer 2024-02-23 09:51:06 -08:00
parent 40d5200c8b
commit 4b9cd6b8bd
3 changed files with 70 additions and 2 deletions

View File

@ -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

View File

@ -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);

View File

@ -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"