Fix apparent programming mistake (newblock doesn’t imply newenv)
that caused “echo ${|true;}$(true)” to segfault; problem reported
by pshevtsov and wbx@ in IRC (thanks!); fix sponsored by tarent
			
			
This commit is contained in:
		
							
								
								
									
										5
									
								
								check.t
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								check.t
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| # $MirOS: src/bin/mksh/check.t,v 1.619 2013/07/21 18:47:16 tg Exp $ | ||||
| # $MirOS: src/bin/mksh/check.t,v 1.620 2013/07/24 12:39:25 tg Exp $ | ||||
| # $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $ | ||||
| # $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $ | ||||
| # $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $ | ||||
| @@ -10186,12 +10186,15 @@ stdin: | ||||
| 	# ensure trailing newlines are kept | ||||
| 	t=${|REPLY=$'foo\n\n';} | ||||
| 	typeset -p t | ||||
| 	echo -n this used to segfault | ||||
| 	echo ${|true;}$(true). | ||||
| expected-stdout: | ||||
| 	before:	x<1> y<2> z<3> R<4> | ||||
| 	begin:	x<1> y<> z<3> R<> | ||||
| 	end:	x<5> y<6> z<7> R<8> | ||||
| 	after:	x<8> y<2> z<7> R<4> | ||||
| 	typeset t=$'foo\n\n' | ||||
| 	this used to segfault. | ||||
| --- | ||||
| name: test-stnze-1 | ||||
| description: | ||||
|   | ||||
							
								
								
									
										30
									
								
								eval.c
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								eval.c
									
									
									
									
									
								
							| @@ -23,7 +23,7 @@ | ||||
|  | ||||
| #include "sh.h" | ||||
|  | ||||
| __RCSID("$MirOS: src/bin/mksh/eval.c,v 1.140 2013/07/21 18:36:00 tg Exp $"); | ||||
| __RCSID("$MirOS: src/bin/mksh/eval.c,v 1.141 2013/07/24 12:39:28 tg Exp $"); | ||||
|  | ||||
| /* | ||||
|  * string expansion | ||||
| @@ -65,7 +65,6 @@ typedef struct { | ||||
|  | ||||
| static int varsub(Expand *, const char *, const char *, int *, int *); | ||||
| static int comsub(Expand *, const char *, int); | ||||
| static void funsub(struct op *); | ||||
| static char *valsub(struct op *, Area *); | ||||
| static char *trimsub(char *, char *, int); | ||||
| static void glob(char *, XPtrV *, bool); | ||||
| @@ -1368,7 +1367,7 @@ comsub(Expand *xp, const char *cp, int fn MKSH_A_UNUSED) | ||||
| 		 * run tree, with output thrown into the tempfile, | ||||
| 		 * in a new function block | ||||
| 		 */ | ||||
| 		funsub(t); | ||||
| 		valsub(t, NULL); | ||||
| 		subst_exstat = exstat & 0xFF; | ||||
| 		/* rewind the tempfile and restore regular stdout */ | ||||
| 		lseek(shf_fileno(shf), (off_t)0, SEEK_SET); | ||||
| @@ -1834,28 +1833,21 @@ alt_expand(XPtrV *wp, char *start, char *exp_start, char *end, int fdo) | ||||
| } | ||||
|  | ||||
| /* helper function due to setjmp/longjmp woes */ | ||||
| static void | ||||
| funsub(struct op *t) | ||||
| { | ||||
| 	newblock(); | ||||
| 	e->type = E_FUNC; | ||||
| 	if (!kshsetjmp(e->jbuf)) | ||||
| 		execute(t, XXCOM | XERROK, NULL); | ||||
| 	popblock(); | ||||
| } | ||||
|  | ||||
| static char * | ||||
| valsub(struct op *t, Area *ap) | ||||
| { | ||||
| 	char *cp; | ||||
| 	struct tbl *vp; | ||||
| 	char *cp = NULL; | ||||
| 	struct tbl * volatile vp = NULL; | ||||
|  | ||||
| 	newenv(E_FUNC); | ||||
| 	newblock(); | ||||
| 	vp = local("REPLY", false); | ||||
| 	e->type = E_FUNC; | ||||
| 	if (ap) | ||||
| 		vp = local("REPLY", false); | ||||
| 	if (!kshsetjmp(e->jbuf)) | ||||
| 		execute(t, XXCOM | XERROK, NULL); | ||||
| 	strdupx(cp, str_val(vp), ap); | ||||
| 	popblock(); | ||||
| 	if (vp) | ||||
| 		strdupx(cp, str_val(vp), ap); | ||||
| 	quitenv(NULL); | ||||
|  | ||||
| 	return (cp); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user