sh: Fix crash with empty functions (f() { }) introduced in r196483
Empty pairs of braces are represented by a NULL node pointer, just like empty lines at the top level. Support for empty pairs of braces may be removed later. They make the code more complex, have inconsistent behaviour (may or may not change $?), are not specified by POSIX and are not allowed by some other shells like bash, dash and ksh93. Reported by: kan
This commit is contained in:
parent
a99fcfd4ca
commit
e16947f83d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=196634
@ -807,9 +807,9 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
|
||||
funcnest++;
|
||||
exitstatus = oexitstatus;
|
||||
if (flags & EV_TESTED)
|
||||
evaltree(&cmdentry.u.func->n, EV_TESTED);
|
||||
evaltree(getfuncnode(cmdentry.u.func), EV_TESTED);
|
||||
else
|
||||
evaltree(&cmdentry.u.func->n, 0);
|
||||
evaltree(getfuncnode(cmdentry.u.func), 0);
|
||||
funcnest--;
|
||||
INTOFF;
|
||||
unreffunc(cmdentry.u.func);
|
||||
|
@ -286,7 +286,7 @@ printentry(struct tblentry *cmdp, int verbose)
|
||||
out1fmt("function %s", cmdp->cmdname);
|
||||
if (verbose) {
|
||||
INTOFF;
|
||||
name = commandtext(&cmdp->param.func->n);
|
||||
name = commandtext(getfuncnode(cmdp->param.func));
|
||||
out1c(' ');
|
||||
out1str(name);
|
||||
ckfree(name);
|
||||
|
@ -248,11 +248,9 @@ output(char *file)
|
||||
fputs("\tstruct nodelist *next;\n", hfile);
|
||||
fputs("\tunion node *n;\n", hfile);
|
||||
fputs("};\n\n\n", hfile);
|
||||
fputs("struct funcdef {\n", hfile);
|
||||
fputs("\tunsigned int refcount;\n", hfile);
|
||||
fputs("\tunion node n;\n", hfile);
|
||||
fputs("};\n\n\n", hfile);
|
||||
fputs("struct funcdef;\n", hfile);
|
||||
fputs("struct funcdef *copyfunc(union node *);\n", hfile);
|
||||
fputs("union node *getfuncnode(struct funcdef *);\n", hfile);
|
||||
fputs("void reffunc(struct funcdef *);\n", hfile);
|
||||
fputs("void unreffunc(struct funcdef *);\n", hfile);
|
||||
|
||||
|
@ -61,6 +61,10 @@ STATIC struct nodelist *copynodelist(struct nodelist *);
|
||||
STATIC char *nodesavestr(char *);
|
||||
|
||||
|
||||
struct funcdef {
|
||||
unsigned int refcount;
|
||||
union node n;
|
||||
};
|
||||
|
||||
/*
|
||||
* Make a copy of a parse tree.
|
||||
@ -85,6 +89,12 @@ copyfunc(union node *n)
|
||||
}
|
||||
|
||||
|
||||
union node *
|
||||
getfuncnode(struct funcdef *fn)
|
||||
{
|
||||
return fn == NULL ? NULL : &fn->n;
|
||||
}
|
||||
|
||||
|
||||
STATIC void
|
||||
calcsize(union node *n)
|
||||
@ -153,7 +163,8 @@ nodesavestr(char *s)
|
||||
void
|
||||
reffunc(struct funcdef *fn)
|
||||
{
|
||||
fn->refcount++;
|
||||
if (fn)
|
||||
fn->refcount++;
|
||||
}
|
||||
|
||||
|
||||
|
11
tools/regression/bin/sh/execution/func2.0
Normal file
11
tools/regression/bin/sh/execution/func2.0
Normal file
@ -0,0 +1,11 @@
|
||||
# $FreeBSD$
|
||||
|
||||
f() { }
|
||||
f
|
||||
hash -v f >/dev/null
|
||||
f() { { }; }
|
||||
f
|
||||
hash -v f >/dev/null
|
||||
f() { { } }
|
||||
f
|
||||
hash -v f >/dev/null
|
Loading…
Reference in New Issue
Block a user