From 9e8fec1ef70bc5ad79b9c471cf1c6a0845a25785 Mon Sep 17 00:00:00 2001
From: Bob Weinand <bobwei9@hotmail.com>
Date: Sun, 26 Jul 2015 18:11:45 +0200
Subject: [PATCH] Fix leaks from bug #70138

---
 sapi/phpdbg/phpdbg.c               | 15 ++++++++++-----
 sapi/phpdbg/phpdbg_prompt.c        |  5 +++--
 sapi/phpdbg/tests/normal_exit.phpt | 15 +++++++++++++++
 3 files changed, 28 insertions(+), 7 deletions(-)
 create mode 100644 sapi/phpdbg/tests/normal_exit.phpt

diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c
index a40ab832a4..48e1b6ec06 100644
--- a/sapi/phpdbg/phpdbg.c
+++ b/sapi/phpdbg/phpdbg.c
@@ -1309,6 +1309,7 @@ int main(int argc, char **argv) /* {{{ */
 	char *print_opline_func;
 	zend_bool ext_stmt = 0;
 	zend_bool use_mm_wrappers = 0;
+	zend_bool is_exit;
 
 #ifdef ZTS
 	void ***tsrm_ls;
@@ -1353,6 +1354,7 @@ phpdbg_main:
 	oplog_file = NULL;
 	oplog_file_len = 0;
 	flags = PHPDBG_DEFAULT_FLAGS;
+	is_exit = 0;
 	php_optarg = NULL;
 	php_optind = 1;
 	opt = 0;
@@ -1915,7 +1917,8 @@ phpdbg_out:
 
 		/* In case we aborted during script execution, we may not reset CG(unclean_shutdown) */
 		if (!(PHPDBG_G(flags) & PHPDBG_IS_RUNNING)) {
-			CG(unclean_shutdown) = PHPDBG_G(unclean_eval);
+			is_exit = !PHPDBG_G(in_execution) && EG(exit_status) != 255;
+			CG(unclean_shutdown) = is_exit || PHPDBG_G(unclean_eval);
 		}
 
 		if ((PHPDBG_G(flags) & (PHPDBG_IS_CLEANING | PHPDBG_IS_RUNNING)) == PHPDBG_IS_CLEANING) {
@@ -1959,10 +1962,12 @@ phpdbg_out:
 			php_request_shutdown(NULL);
 		} zend_end_try();
 
-		if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING) && PHPDBG_G(in_execution)) {
-			if (!quit_immediately && !phpdbg_startup_run) {
-				phpdbg_notice("stop", "type=\"normal\"", "Script ended normally");
-				cleaning++;
+		if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
+			if (PHPDBG_G(in_execution) || is_exit) {
+				if (!quit_immediately && !phpdbg_startup_run) {
+					phpdbg_notice("stop", "type=\"normal\"", "Script ended normally");
+					cleaning++;
+				}
 			}
 		}
 		php_output_deactivate();
diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c
index 5b5ac2a075..9d40d000c2 100644
--- a/sapi/phpdbg/phpdbg_prompt.c
+++ b/sapi/phpdbg/phpdbg_prompt.c
@@ -691,7 +691,6 @@ PHPDBG_COMMAND(run) /* {{{ */
 			PHPDBG_G(in_execution) = 0;
 
 			if (!(PHPDBG_G(flags) & PHPDBG_IS_STOPPING)) {
-				phpdbg_error("stop", "type=\"bailout\"", "Caught exit/error from VM");
 				restore = 0;
 			} else {
 				zend_bailout();
@@ -710,9 +709,10 @@ PHPDBG_COMMAND(run) /* {{{ */
 
 			PHPDBG_G(in_execution) = 1;
 		}
-		phpdbg_clean(1);
 
 		PHPDBG_G(flags) &= ~PHPDBG_IS_RUNNING;
+
+		phpdbg_clean(1);
 	} else {
 		phpdbg_error("inactive", "type=\"nocontext\"", "Nothing to execute!");
 	}
@@ -794,6 +794,7 @@ PHPDBG_COMMAND(ev) /* {{{ */
 		EG(vm_stack_top) = original_stack->top;
 		EG(vm_stack_end) = original_stack->end;
 		EG(vm_stack) = original_stack;
+		EG(exit_status) = 0;
 	} zend_end_try();
 
 	PHPDBG_G(flags) &= ~PHPDBG_IN_EVAL;
diff --git a/sapi/phpdbg/tests/normal_exit.phpt b/sapi/phpdbg/tests/normal_exit.phpt
new file mode 100644
index 0000000000..692614e98f
--- /dev/null
+++ b/sapi/phpdbg/tests/normal_exit.phpt
@@ -0,0 +1,15 @@
+--TEST--
+A script with die() must end "normally"
+--PHPDBG--
+r
+q
+--EXPECTF--
+[Successful compilation of %s]
+prompt> [Script ended normally]
+prompt> 
+--FILE--
+<?php
+
+(function($argv) {
+	die();
+})($argv);
-- 
2.40.0