If a variable from the temporary environment is made non-scalar (by use
of either compound assignment or a declaration command), and a variable
of the same name is then declared in a lower scope, the latter variable
can end up with an inconsistent state:

    $ f() { x=(); ${|local x; local -p x;}; }; x= f
    declare -x x=$'\377\377\377\377\377\377\377\377'

    $ f() { local -A x; ${|local x; local -p x;}; }; x= f
    declare -x x=$'\240RB\356|'

    $ f() { x=(); ${|local -I x;}; }; x= f
    ERROR: AddressSanitizer: heap-buffer-overflow on...
    READ of size 8 at...
        #0 array_flush array.c:103:11
        #1 array_dispose array.c:119:2
        #2 dispose_variable_value variables.c:3715:5
        #3 dispose_variable variables.c:3732:5
        #4 push_posix_tempvar_internal variables.c:5321:3
        #5 push_func_var variables.c:5330:3
        #6 hash_flush hashlib.c:374:6
        #7 pop_var_context variables.c:5363:2
        #8 uw_pop_var_context subst.c:6838:3
        ...

The test cases above use command substitution for brevity only; calling
a nested function with the same body has the same effect.

Reply via email to