diff options
author | jilles <jilles@FreeBSD.org> | 2009-08-28 22:41:25 +0000 |
---|---|---|
committer | jilles <jilles@FreeBSD.org> | 2009-08-28 22:41:25 +0000 |
commit | 0bf6e8da4eba6a1fb35ec2e5b2db62e53fec7d32 (patch) | |
tree | 7a8084b831c46519ff07655affc5c604f115d66a /bin | |
parent | 9940277b0b89316256a4ba3df75a0b17de8b7157 (diff) | |
download | FreeBSD-src-0bf6e8da4eba6a1fb35ec2e5b2db62e53fec7d32.zip FreeBSD-src-0bf6e8da4eba6a1fb35ec2e5b2db62e53fec7d32.tar.gz |
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
Diffstat (limited to 'bin')
-rw-r--r-- | bin/sh/eval.c | 4 | ||||
-rw-r--r-- | bin/sh/exec.c | 2 | ||||
-rw-r--r-- | bin/sh/mknodes.c | 6 | ||||
-rw-r--r-- | bin/sh/nodes.c.pat | 13 |
4 files changed, 17 insertions, 8 deletions
diff --git a/bin/sh/eval.c b/bin/sh/eval.c index 8dfa7dd..7978b84 100644 --- a/bin/sh/eval.c +++ b/bin/sh/eval.c @@ -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); diff --git a/bin/sh/exec.c b/bin/sh/exec.c index 639a23c..8107821 100644 --- a/bin/sh/exec.c +++ b/bin/sh/exec.c @@ -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); diff --git a/bin/sh/mknodes.c b/bin/sh/mknodes.c index 904f9f4..1a177f8 100644 --- a/bin/sh/mknodes.c +++ b/bin/sh/mknodes.c @@ -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); diff --git a/bin/sh/nodes.c.pat b/bin/sh/nodes.c.pat index b6a8559..1f5adbb 100644 --- a/bin/sh/nodes.c.pat +++ b/bin/sh/nodes.c.pat @@ -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++; } |