Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 28 Aug 2009 22:41:25 +0000 (UTC)
From:      Jilles Tjoelker <jilles@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r196634 - in head: bin/sh tools/regression/bin/sh/execution
Message-ID:  <200908282241.n7SMfP6f038547@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jilles
Date: Fri Aug 28 22:41:25 2009
New Revision: 196634
URL: http://svn.freebsd.org/changeset/base/196634

Log:
  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

Added:
  head/tools/regression/bin/sh/execution/func2.0   (contents, props changed)
Modified:
  head/bin/sh/eval.c
  head/bin/sh/exec.c
  head/bin/sh/mknodes.c
  head/bin/sh/nodes.c.pat

Modified: head/bin/sh/eval.c
==============================================================================
--- head/bin/sh/eval.c	Fri Aug 28 22:30:55 2009	(r196633)
+++ head/bin/sh/eval.c	Fri Aug 28 22:41:25 2009	(r196634)
@@ -807,9 +807,9 @@ evalcommand(union node *cmd, int flags, 
 		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);

Modified: head/bin/sh/exec.c
==============================================================================
--- head/bin/sh/exec.c	Fri Aug 28 22:30:55 2009	(r196633)
+++ head/bin/sh/exec.c	Fri Aug 28 22:41:25 2009	(r196634)
@@ -286,7 +286,7 @@ printentry(struct tblentry *cmdp, int ve
 		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);

Modified: head/bin/sh/mknodes.c
==============================================================================
--- head/bin/sh/mknodes.c	Fri Aug 28 22:30:55 2009	(r196633)
+++ head/bin/sh/mknodes.c	Fri Aug 28 22:41:25 2009	(r196634)
@@ -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);
 

Modified: head/bin/sh/nodes.c.pat
==============================================================================
--- head/bin/sh/nodes.c.pat	Fri Aug 28 22:30:55 2009	(r196633)
+++ head/bin/sh/nodes.c.pat	Fri Aug 28 22:41:25 2009	(r196634)
@@ -61,6 +61,10 @@ STATIC struct nodelist *copynodelist(str
 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++;
 }
 
 

Added: head/tools/regression/bin/sh/execution/func2.0
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/regression/bin/sh/execution/func2.0	Fri Aug 28 22:41:25 2009	(r196634)
@@ -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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200908282241.n7SMfP6f038547>