1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-02-13 19:52:20 +00:00

typeset -T: fix spurious 2nd error on redef (re: 1fbbeaa1, d309d604)

Reproducers:

    $ ksh -c 'typeset -T foo=(x=1); typeset -T foo=(integer x)'
    ksh: typeset: foo: type cannot be redefined
    ksh: foo: type definition requires compound assignment

    $ ksh -c 'typeset -T foo=(x=1); typeset -T foo=(integer x=2)'
    ksh: foo: type cannot be redefined
    ksh: foo: type definition requires compound assignment

In both cases, the second error message is spurious, as there is in
fact a compound assignment.

The first case was introduced in 1fbbeaa1. The 'integer' command no
longer resolves to a special built-in but is now a regular built-in
so it does not cause the shell to exit on error. The code path
continues and nv_mktype() is called which issues the bad error as
the compound assignment was not fully processed.

The second case was introduced in d309d604. This commit inhibits
the exit-on-error for the assignment list of a regular built-in.
For type definitions, nv_mktype() is called via this code path too.

Since all declaration commands were either special built-ins or
aliases to special built-ins in 93u+, they all exited on error and
this problem never happened. Now that some regular built-ins are
allowed inside 'typeset -T', we need some special-casing to make
them exit on error as before. Arguably this is the correct thing to
do anyway, as their errors are also an error in the enveloping
'typeset' which is a special built-in.

This regression is cosmetic and the case is rare, so this is
probably not worth a NEWS item.

src/cmd/ksh93/sh/xec.c: sh_exec():
- Fix the second case by adding a test for non-NULL 'sh.mktype' to
  the conditions where the assignments list is processed with exit
  on error. This pointer is set while executing a type definition.
- Fix the first case by saving the sh.mktype state before executing
  a built-in and then checking the saved value if a built-in exits
  on error. Saving is needed as sh.mktype has been reset by then.
This commit is contained in:
Martijn Dekker 2022-06-10 02:57:13 +01:00
parent 3030197b89
commit b93216ce88
2 changed files with 13 additions and 4 deletions

View file

@ -1099,9 +1099,10 @@ int sh_exec(register const Shnode_t *t, int flags)
else
flgs |= NV_VARNAME;
/* execute the list of assignments */
if((!np || nv_isattr(np,BLT_SPC)) && !command)
if((!np || nv_isattr(np,BLT_SPC)) && !command || sh.mktype)
{
/* bare assignment(s) or special builtin, and no 'command' prefix: exit on error */
/* (bare assignment(s) or special builtin) and no 'command' prefix,
* or we're inside a type definition: exit on error */
nv_setlist(argp,flgs,tp);
}
else
@ -1224,7 +1225,7 @@ int sh_exec(register const Shnode_t *t, int flags)
/* check for builtins */
if(np && is_abuiltin(np) && !sh_isstate(SH_XARG))
{
volatile int scope=0, share=0;
volatile char scope=0, share=0, was_mktype=(sh.mktype!=NIL(void*));
volatile void *save_ptr;
volatile void *save_data;
int save_prompt;
@ -1378,7 +1379,7 @@ int sh_exec(register const Shnode_t *t, int flags)
if(sh.bltinfun && (error_info.flags&ERROR_NOTIFY))
(*sh.bltinfun)(-2,com,(void*)bp);
/* failure on special built-ins fatal */
if(jmpval<=SH_JMPCMD && (!nv_isattr(np,BLT_SPC) || command))
if(jmpval<=SH_JMPCMD && (!nv_isattr(np,BLT_SPC) || command) && !was_mktype)
jmpval=0;
#if !SHOPT_DEVFD
fifo_cleanup();

View file

@ -84,6 +84,14 @@ typeset -T Pt_t=(
Pt_t p
[[ ${p.y} == 6 ]] || err_exit '${p.y} != 6'
(( p.len == 7 )) || err_exit '((p.len !=7))'
# check for correct error message when failing to redefine a type
exp=': Pt_t: type cannot be redefined'
got=$(set +x; { typeset -T Pt_t=(float foo); } 2>&1);
[[ $got != *$'\n'* && $got == *"$exp" ]] || err_exit "incorrect error on failing to redefine type" \
"(expected match of *$(printf %q "$exp"), got $(printf %q "$got"))"
got=$(set +x; { typeset -T Pt_t=(float foo=1); } 2>&1);
[[ $got != *$'\n'* && $got == *"$exp" ]] || err_exit "incorrect error on failing to redefine type" \
"(expected match of *$(printf %q "$exp"), got $(printf %q "$got"))"
z=()
Pt_t -a z.p