Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Segfault in =( ) substitution



On Fri, 21 Dec 2012 15:57:51 +0800
Han Pingtian <hanpt@xxxxxxxxxxxxxxxxxx> wrote:
> I just noticed that this example crashed on zsh both 5.0 and 5.0.1.
> If I compile zsh with debug enabled, it runs like this:
> 
> % () {
> function> print File $1:
> function> cat $1
> function> } =(print hello)
> File :
> cat: : No such file or directory

Glad you noticed this, it's a standard piece of luck we found out
a day late...

Anonymous functions can't be "simple", they need a valid process
environment because (unlike normal function definitions) they can take
arbitrary arguments, as in this case.  (We could probe the arguments
individually to see, but this fix is a good deal simpler.)

If anyone can further elucidate the relationship between job control (in
particular, the current job recorded in "thisjob") and shell code
optimised to "simple" execution, feel free, otherwise whether or not it
fails to crash because it's happened to pick up a version of "thisjob"
from somewhere else isn't really interesting.  The change in 30876 would
have further perturbed the environment seen by execsimple().

Moral: when you spot "gr8 new featurez" you hadn't realised the shell
could do, add tests for them.

Index: Src/parse.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/parse.c,v
retrieving revision 1.93
diff -p -u -r1.93 parse.c
--- Src/parse.c	25 Oct 2012 08:54:33 -0000	1.93
+++ Src/parse.c	21 Dec 2012 10:20:59 -0000
@@ -846,7 +846,7 @@ par_cmd(int *complex)
 	break;
     case FUNC:
 	cmdpush(CS_FUNCDEF);
-	par_funcdef();
+	par_funcdef(complex);
 	cmdpop();
 	break;
     case DINBRACK:
@@ -1420,7 +1420,7 @@ par_subsh(int *complex)
 
 /**/
 static void
-par_funcdef(void)
+par_funcdef(int *complex)
 {
     int oecused = ecused, num = 0, onp, p, c = 0;
     int so, oecssub = ecssub;
@@ -1471,6 +1471,7 @@ par_funcdef(void)
 	if (num == 0) {
 	    /* Anonymous function, possibly with arguments */
 	    incmdpos = 0;
+	    *complex = 1;
 	}
 	zshlex();
     } else if (unset(SHORTLOOPS)) {
@@ -1735,6 +1736,7 @@ par_simple(int *complex, int nr)
 		if (argc == 0) {
 		    /* Anonymous function, possibly with arguments */
 		    incmdpos = 0;
+		    *complex = 1;
 		}
 		zshlex();
 	    } else {
Index: Test/D03procsubst.ztst
===================================================================
RCS file: /cvsroot/zsh/zsh/Test/D03procsubst.ztst,v
retrieving revision 1.6
diff -p -u -r1.6 D03procsubst.ztst
--- Test/D03procsubst.ztst	17 Aug 2011 20:26:05 -0000	1.6
+++ Test/D03procsubst.ztst	21 Dec 2012 10:20:59 -0000
@@ -88,3 +88,22 @@
   print something=${:-=(echo 'C,D),(F,G)'}
 1: Graceful handling of bad substitution in enclosed context
 ?(eval):1: unterminated `=(...)'
+
+  () {
+     print -n "first: "
+     cat $1
+     print -n "second: "
+     cat $2
+  } =(echo This becomes argument one) =(echo and this argument two)
+  function {
+     print -n "third: "
+     cat $1
+     print -n "fourth: "
+     cat $2
+  } =(echo This becomes argument three) =(echo and this argument four)
+0:Process environment of anonymous functions
+>first: This becomes argument one
+>second: and this argument two
+>third: This becomes argument three
+>fourth: and this argument four
+

-- 
Peter Stephenson <p.stephenson@xxxxxxxxxxx>       Consultant, Software
Tel: +44 (0)1223 434724              Samsung Cambridge Solution Centre
St John's House, St John's Innovation Park,
Cowley Road, Cambridge, CB4 0ZT, UK



Messages sorted by: Reverse Date, Date, Thread, Author