From e31c54d02592caa31d6a59aaefeaa96aab2d7b27 Mon Sep 17 00:00:00 2001
From: Remi Collet <remi@remirepo.net>
Date: Fri, 7 Jan 2022 15:04:36 +0100
Subject: [PATCH] fix GH-7899 Regression in unpack for negative int value

---
 NEWS                                   |  3 +++
 ext/standard/pack.c                    | 11 +++++++++--
 ext/standard/tests/strings/pack64.phpt | 21 +++++++++++++++++++++
 3 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/ext/standard/pack.c b/ext/standard/pack.c
index 46856874bc2a..8736d291fb24 100644
--- a/ext/standard/pack.c
+++ b/ext/standard/pack.c
@@ -62,6 +62,7 @@ typedef ZEND_SET_ALIGNED(1, uint16_t unaligned_uint16_t);
 typedef ZEND_SET_ALIGNED(1, uint32_t unaligned_uint32_t);
 typedef ZEND_SET_ALIGNED(1, uint64_t unaligned_uint64_t);
 typedef ZEND_SET_ALIGNED(1, unsigned int unaligned_uint);
+typedef ZEND_SET_ALIGNED(1, int unaligned_int);
 
 /* Mapping of byte from char (8bit) to long for machine endian */
 static int byte_map[1];
@@ -1043,8 +1044,14 @@ PHP_FUNCTION(unpack)
 
 					case 'i':   /* signed integer, machine size, machine endian */
 					case 'I': { /* unsigned integer, machine size, machine endian */
-						unsigned int x = *((unaligned_uint*) &input[inputpos]);
-						zend_long v = (type == 'i') ? (int) x : x;
+						zend_long v;
+						if (type == 'i') {
+							int x = *((unaligned_int*) &input[inputpos]);
+							v = x;
+						} else {
+							unsigned int x = *((unaligned_uint*) &input[inputpos]);
+							v = x;
+						}
 
 						ZVAL_LONG(&val, v);
 						zend_symtable_update(Z_ARRVAL_P(return_value), real_name, &val);
diff --git a/ext/standard/tests/strings/pack64.phpt b/ext/standard/tests/strings/pack64.phpt
index 753821f65429..84e69008284d 100644
--- a/ext/standard/tests/strings/pack64.phpt
+++ b/ext/standard/tests/strings/pack64.phpt
@@ -31,6 +31,11 @@ print_r(unpack("q", pack("q", 0)));
 print_r(unpack("q", pack("q", 0x8000000000000002)));
 print_r(unpack("q", pack("q", -1)));
 print_r(unpack("q", pack("q", 0x8000000000000000)));
+
+print_r(unpack("i", pack("i",  2147483647))); // Max int32
+print_r(unpack("i", pack("i", -2147483647)));
+print_r(unpack("i", pack("i", -2147483648))); // Min int32
+print_r(unpack("I", pack("I",  4294967295))); // Max uint32
 ?>
 --EXPECT--
 Array
@@ -113,3 +118,19 @@ Array
 (
     [1] => -9223372036854775808
 )
+Array
+(
+    [1] => 2147483647
+)
+Array
+(
+    [1] => -2147483647
+)
+Array
+(
+    [1] => -2147483648
+)
+Array
+(
+    [1] => 4294967295
+)
From cdfc4d3596d9f983b7395ee11641cbf37b77b46e Mon Sep 17 00:00:00 2001
From: Remi Collet <remi@remirepo.net>
Date: Mon, 17 Jan 2022 10:23:15 +0100
Subject: [PATCH] Fix GH-7883 don't close not open file handle don't create a
 stream if file is not open

---
 NEWS               | 1 +
 Zend/zend_stream.c | 5 ++++-
 main/php_ini.c     | 7 ++++---
 3 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/Zend/zend_stream.c b/Zend/zend_stream.c
index aadc62558e60..ae2c734b09b4 100644
--- a/Zend/zend_stream.c
+++ b/Zend/zend_stream.c
@@ -214,7 +214,10 @@ static void zend_file_handle_dtor(zend_file_handle *fh) /* {{{ */
 {
 	switch (fh->type) {
 		case ZEND_HANDLE_FP:
-			fclose(fh->handle.fp);
+			if (fh->handle.fp) {
+				fclose(fh->handle.fp);
+				fh->handle.fp = NULL;
+			}
 			break;
 		case ZEND_HANDLE_STREAM:
 			if (fh->handle.stream.closer && fh->handle.stream.handle) {
diff --git a/main/php_ini.c b/main/php_ini.c
index fd6f36648821..136942896da4 100644
--- a/main/php_ini.c
+++ b/main/php_ini.c
@@ -686,8 +686,9 @@ int php_init_config(void)
 					if (VCWD_STAT(ini_file, &sb) == 0) {
 						if (S_ISREG(sb.st_mode)) {
 							zend_file_handle fh;
-							zend_stream_init_fp(&fh, VCWD_FOPEN(ini_file, "r"), ini_file);
-							if (fh.handle.fp) {
+							FILE *file = VCWD_FOPEN(ini_file, "r");
+							if (file) {
+								zend_stream_init_fp(&fh, file, ini_file);
 								if (zend_parse_ini_file(&fh, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, &configuration_hash) == SUCCESS) {
 									/* Here, add it to the list of ini files read */
 									l = (int)strlen(ini_file);
@@ -695,8 +696,8 @@ int php_init_config(void)
 									p = estrndup(ini_file, l);
 									zend_llist_add_element(&scanned_ini_list, &p);
 								}
+								zend_destroy_file_handle(&fh);
 							}
-							zend_destroy_file_handle(&fh);
 						}
 					}
 					free(namelist[i]);