ash: eval: Do not cache value of eflag in evaltree
Upsteam commit:
    Date: Mon, 17 May 2021 15:19:23 +0800
    eval: Do not cache value of eflag in evaltree
    Patrick Brünn <P.Bruenn@beckhoff.com> wrote:
    > Since we are migrating to Debian bullseye, we discovered a new behavior
    > with our scripts, which look like this:
    >>cleanup() {
    >>        set +e
    >>        rmdir ""
    >>}
    >>set -eu
    >>trap 'cleanup' EXIT INT TERM
    >>echo 'Hello world!'
    >
    > With old dash v0.5.10.2 this script would return 0 as we expected it.
    > But since commit 62cf6955f8abe875752d7163f6f3adbc7e49ebae it returns
    > the last exit code of our cleanup function.
    ...
    Thanks for the report.  This is actually a fairly old bug with
    set -e that's just been exposed by the exit status change.  What's
    really happening is that cleanup itself is triggering a set -e
    exit incorrectly because evaltree cached the value of eflag prior
    to the function call.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
			
			
This commit is contained in:
		
							
								
								
									
										15
									
								
								shell/ash.c
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								shell/ash.c
									
									
									
									
									
								
							| @@ -9336,8 +9336,7 @@ evaltree(union node *n, int flags) | |||||||
| 	case NCMD: | 	case NCMD: | ||||||
| 		evalfn = evalcommand; | 		evalfn = evalcommand; | ||||||
|  checkexit: |  checkexit: | ||||||
| 		if (!(flags & EV_TESTED)) | 		checkexit = ~flags & EV_TESTED; | ||||||
| 			checkexit = ~0; |  | ||||||
| 		goto calleval; | 		goto calleval; | ||||||
| 	case NFOR: | 	case NFOR: | ||||||
| 		evalfn = evalfor; | 		evalfn = evalfor; | ||||||
| @@ -9359,7 +9358,6 @@ evaltree(union node *n, int flags) | |||||||
| 	case NAND: | 	case NAND: | ||||||
| 	case NOR: | 	case NOR: | ||||||
| 	case NSEMI: { | 	case NSEMI: { | ||||||
|  |  | ||||||
| #if NAND + 1 != NOR | #if NAND + 1 != NOR | ||||||
| #error NAND + 1 != NOR | #error NAND + 1 != NOR | ||||||
| #endif | #endif | ||||||
| @@ -9387,8 +9385,7 @@ evaltree(union node *n, int flags) | |||||||
| 		if (!status) { | 		if (!status) { | ||||||
| 			n = n->nif.ifpart; | 			n = n->nif.ifpart; | ||||||
| 			goto evaln; | 			goto evaln; | ||||||
| 		} | 		} else if (n->nif.elsepart) { | ||||||
| 		if (n->nif.elsepart) { |  | ||||||
| 			n = n->nif.elsepart; | 			n = n->nif.elsepart; | ||||||
| 			goto evaln; | 			goto evaln; | ||||||
| 		} | 		} | ||||||
| @@ -9410,7 +9407,7 @@ evaltree(union node *n, int flags) | |||||||
| 	 */ | 	 */ | ||||||
| 	dotrap(); | 	dotrap(); | ||||||
|  |  | ||||||
| 	if (checkexit & status) { | 	if (checkexit && status) { | ||||||
| 		if (trap[NTRAP_ERR] && !in_trap_ERR) { | 		if (trap[NTRAP_ERR] && !in_trap_ERR) { | ||||||
| 			int err; | 			int err; | ||||||
| 			struct jmploc *volatile savehandler = exception_handler; | 			struct jmploc *volatile savehandler = exception_handler; | ||||||
| @@ -9434,10 +9431,12 @@ evaltree(union node *n, int flags) | |||||||
| 			exitstatus = savestatus; | 			exitstatus = savestatus; | ||||||
| 		} | 		} | ||||||
| 		if (eflag) | 		if (eflag) | ||||||
|  | 			goto exexit; | ||||||
|  | 	} | ||||||
|  | 	if (flags & EV_EXIT) { | ||||||
|  |  exexit: | ||||||
| 		raise_exception(EXEND); | 		raise_exception(EXEND); | ||||||
| 	} | 	} | ||||||
| 	if (flags & EV_EXIT) |  | ||||||
| 		raise_exception(EXEND); |  | ||||||
|  |  | ||||||
| 	popstackmark(&smark); | 	popstackmark(&smark); | ||||||
| 	TRACE(("leaving evaltree (no interrupts)\n")); | 	TRACE(("leaving evaltree (no interrupts)\n")); | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								shell/ash_test/ash-misc/exitcode_trap7.right
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								shell/ash_test/ash-misc/exitcode_trap7.right
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | Start | ||||||
|  | Ok:0 | ||||||
							
								
								
									
										7
									
								
								shell/ash_test/ash-misc/exitcode_trap7.tests
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										7
									
								
								shell/ash_test/ash-misc/exitcode_trap7.tests
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | $THIS_SH -c ' | ||||||
|  | cleanup() { set +e; false; } | ||||||
|  | set -eu | ||||||
|  | trap cleanup EXIT | ||||||
|  | echo Start | ||||||
|  | ' | ||||||
|  | echo Ok:$? | ||||||
		Reference in New Issue
	
	Block a user