Commit f7c1a38606a for php

commit f7c1a38606aecf6bb866c17905d5267b686db2f2
Author: Gina Peter Banyard <girgias@php.net>
Date:   Thu Sep 24 17:11:11 2026 +0100

    Zend: redefine scanner_mode type to be zend_ini_scanner_mode

    And move error handling to the call sites in PHP_FUNCTIONs

diff --git a/Zend/tests/bug61087.phpt b/Zend/tests/bug61087.phpt
index a0375f21bf2..124497c657c 100644
--- a/Zend/tests/bug61087.phpt
+++ b/Zend/tests/bug61087.phpt
@@ -7,4 +7,4 @@
 parse_ini_file(__FILE__, false, 100);
 ?>
 --EXPECTF--
-Warning: Invalid scanner mode in %s on line %d
+Warning: parse_ini_file(): Invalid scanner mode in %s on line %d
diff --git a/Zend/zend_ini.h b/Zend/zend_ini.h
index dbe650675b6..c9db9123724 100644
--- a/Zend/zend_ini.h
+++ b/Zend/zend_ini.h
@@ -232,8 +232,8 @@ END_EXTERN_C()
 /* INI parsing engine */
 typedef void (*zend_ini_parser_cb_t)(zval *arg1, zval *arg2, zval *arg3, int callback_type, void *arg);
 BEGIN_EXTERN_C()
-ZEND_API zend_result zend_parse_ini_file(zend_file_handle *fh, bool unbuffered_errors, int scanner_mode, zend_ini_parser_cb_t ini_parser_cb, void *arg);
-ZEND_API zend_result zend_parse_ini_string(const char *str, bool unbuffered_errors, int scanner_mode, zend_ini_parser_cb_t ini_parser_cb, void *arg);
+ZEND_API zend_result zend_parse_ini_file(zend_file_handle *fh, bool unbuffered_errors, zend_ini_scanner_mode scanner_mode, zend_ini_parser_cb_t ini_parser_cb, void *arg);
+ZEND_API zend_result zend_parse_ini_string(const char *str, bool unbuffered_errors, zend_ini_scanner_mode scanner_mode, zend_ini_parser_cb_t ini_parser_cb, void *arg);
 END_EXTERN_C()

 /* INI entries */
diff --git a/Zend/zend_ini_parser.y b/Zend/zend_ini_parser.y
index 47b05de4e69..7c91e4a8e0f 100644
--- a/Zend/zend_ini_parser.y
+++ b/Zend/zend_ini_parser.y
@@ -221,8 +221,7 @@ static ZEND_COLD void ini_error(const char *msg)
 }
 /* }}} */

-/* {{{ zend_parse_ini_file() */
-ZEND_API zend_result zend_parse_ini_file(zend_file_handle *fh, bool unbuffered_errors, int scanner_mode, zend_ini_parser_cb_t ini_parser_cb, void *arg)
+ZEND_API zend_result zend_parse_ini_file(zend_file_handle *fh, bool unbuffered_errors, zend_ini_scanner_mode scanner_mode, zend_ini_parser_cb_t ini_parser_cb, void *arg)
 {
 	int retval;
 	zend_ini_parser_param ini_parser_param;
@@ -246,10 +245,8 @@ ZEND_API zend_result zend_parse_ini_file(zend_file_handle *fh, bool unbuffered_e
 		return FAILURE;
 	}
 }
-/* }}} */

-/* {{{ zend_parse_ini_string() */
-ZEND_API zend_result zend_parse_ini_string(const char *str, bool unbuffered_errors, int scanner_mode, zend_ini_parser_cb_t ini_parser_cb, void *arg)
+ZEND_API zend_result zend_parse_ini_string(const char *str, bool unbuffered_errors, zend_ini_scanner_mode scanner_mode, zend_ini_parser_cb_t ini_parser_cb, void *arg)
 {
 	int retval;
 	zend_ini_parser_param ini_parser_param;
@@ -273,7 +270,6 @@ ZEND_API zend_result zend_parse_ini_string(const char *str, bool unbuffered_erro
 		return FAILURE;
 	}
 }
-/* }}} */

 /* {{{ zval_ini_dtor() */
 static void zval_ini_dtor(zval *zv)
diff --git a/Zend/zend_ini_scanner.h b/Zend/zend_ini_scanner.h
index 4cdcf0472bb..4a6b5d08900 100644
--- a/Zend/zend_ini_scanner.h
+++ b/Zend/zend_ini_scanner.h
@@ -33,8 +33,8 @@ C23_ENUM(zend_ini_scanner_mode, uint8_t) {
 BEGIN_EXTERN_C()
 ZEND_COLD uint32_t zend_ini_scanner_get_lineno(void);
 ZEND_COLD const char *zend_ini_scanner_get_filename(void);
-zend_result zend_ini_open_file_for_scanning(zend_file_handle *fh, int scanner_mode);
-zend_result zend_ini_prepare_string_for_scanning(const char *str, int scanner_mode);
+zend_result zend_ini_open_file_for_scanning(zend_file_handle *fh, zend_ini_scanner_mode scanner_mode);
+zend_result zend_ini_prepare_string_for_scanning(const char *str, zend_ini_scanner_mode scanner_mode);
 int ini_lex(zval *ini_lval);
 void shutdown_ini_scanner(void);
 END_EXTERN_C()
diff --git a/Zend/zend_ini_scanner.l b/Zend/zend_ini_scanner.l
index 7fd51654ac8..acf265604cc 100644
--- a/Zend/zend_ini_scanner.l
+++ b/Zend/zend_ini_scanner.l
@@ -192,15 +192,8 @@ static void yy_scan_buffer(const char *str, unsigned int len)

 #define ini_filename SCNG(filename)

-/* {{{ init_ini_scanner() */
-static zend_result init_ini_scanner(int scanner_mode, zend_file_handle *fh)
+static zend_result init_ini_scanner(zend_ini_scanner_mode scanner_mode, zend_file_handle *fh)
 {
-	/* Sanity check */
-	if (scanner_mode != ZEND_INI_SCANNER_NORMAL && scanner_mode != ZEND_INI_SCANNER_RAW && scanner_mode != ZEND_INI_SCANNER_TYPED) {
-		zend_error(E_WARNING, "Invalid scanner mode");
-		return FAILURE;
-	}
-
 	SCNG(lineno) = 1;
 	SCNG(scanner_mode) = scanner_mode;
 	SCNG(yy_in) = fh;
@@ -216,7 +209,6 @@ static zend_result init_ini_scanner(int scanner_mode, zend_file_handle *fh)

 	return SUCCESS;
 }
-/* }}} */

 /* {{{ shutdown_ini_scanner() */
 void shutdown_ini_scanner(void)
@@ -243,7 +235,7 @@ ZEND_COLD const char *zend_ini_scanner_get_filename(void)
 /* }}} */

 /* {{{ zend_ini_open_file_for_scanning() */
-zend_result zend_ini_open_file_for_scanning(zend_file_handle *fh, int scanner_mode)
+zend_result zend_ini_open_file_for_scanning(zend_file_handle *fh, zend_ini_scanner_mode scanner_mode)
 {
 	char *buf;
 	size_t size;
@@ -262,8 +254,7 @@ zend_result zend_ini_open_file_for_scanning(zend_file_handle *fh, int scanner_mo
 }
 /* }}} */

-/* {{{ zend_ini_prepare_string_for_scanning() */
-zend_result zend_ini_prepare_string_for_scanning(const char *str, int scanner_mode)
+zend_result zend_ini_prepare_string_for_scanning(const char *str, zend_ini_scanner_mode scanner_mode)
 {
 	int len = (int)strlen(str);

@@ -275,7 +266,6 @@ zend_result zend_ini_prepare_string_for_scanning(const char *str, int scanner_mo

 	return SUCCESS;
 }
-/* }}} */

 /* {{{ zend_ini_escape_string() */
 static void zend_ini_escape_string(zval *lval, const char *str, int len, char quote_type)
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index 5313388d8fc..6f089a1ff88 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -2508,6 +2508,12 @@ PHP_FUNCTION(parse_ini_file)
 		RETURN_THROWS();
 	}

+	/* Sanity check */
+	if (UNEXPECTED(scanner_mode != ZEND_INI_SCANNER_NORMAL && scanner_mode != ZEND_INI_SCANNER_RAW && scanner_mode != ZEND_INI_SCANNER_TYPED)) {
+		php_error_docref(NULL, E_WARNING, "Invalid scanner mode");
+		RETURN_FALSE;
+	}
+
 	/* Set callback function */
 	if (process_sections) {
 		ZVAL_UNDEF(&BG(active_ini_file_section));
@@ -2520,7 +2526,7 @@ PHP_FUNCTION(parse_ini_file)
 	zend_stream_init_filename_ex(&fh, filename);

 	array_init(return_value);
-	if (zend_parse_ini_file(&fh, 0, (int)scanner_mode, ini_parser_cb, return_value) == FAILURE) {
+	if (zend_parse_ini_file(&fh, 0, (zend_ini_scanner_mode)scanner_mode, ini_parser_cb, return_value) == FAILURE) {
 		zend_array_destroy(Z_ARR_P(return_value));
 		RETVAL_FALSE;
 	}
@@ -2544,6 +2550,12 @@ PHP_FUNCTION(parse_ini_string)
 		Z_PARAM_LONG(scanner_mode)
 	ZEND_PARSE_PARAMETERS_END();

+	/* Sanity check */
+	if (UNEXPECTED(scanner_mode != ZEND_INI_SCANNER_NORMAL && scanner_mode != ZEND_INI_SCANNER_RAW && scanner_mode != ZEND_INI_SCANNER_TYPED)) {
+		php_error_docref(NULL, E_WARNING, "Invalid scanner mode");
+		RETURN_FALSE;
+	}
+
 	if (INT_MAX - str_len < ZEND_MMAP_AHEAD) {
 		RETVAL_FALSE;
 	}
@@ -2562,7 +2574,7 @@ PHP_FUNCTION(parse_ini_string)
 	memset(string + str_len, 0, ZEND_MMAP_AHEAD);

 	array_init(return_value);
-	if (zend_parse_ini_string(string, 0, (int)scanner_mode, ini_parser_cb, return_value) == FAILURE) {
+	if (zend_parse_ini_string(string, 0, (zend_ini_scanner_mode)scanner_mode, ini_parser_cb, return_value) == FAILURE) {
 		zend_array_destroy(Z_ARR_P(return_value));
 		RETVAL_FALSE;
 	}
diff --git a/ext/standard/tests/file/parse_ini_file_error.phpt b/ext/standard/tests/file/parse_ini_file_error.phpt
index 583be438006..6c519c1e5fe 100644
--- a/ext/standard/tests/file/parse_ini_file_error.phpt
+++ b/ext/standard/tests/file/parse_ini_file_error.phpt
@@ -5,11 +5,11 @@
 echo "*** Testing parse_ini_file() : error conditions ***\n";

 //Test parse_ini_file with one more than the expected number of arguments
-echo "\n-- Testing parse_ini_file() function with more than expected no. of arguments --\n";
+echo "\n-- Testing parse_ini_file() function with invalid scanner mode --\n";
 $filename = 'string_val';
 $process_sections = true;
-$extra_arg = 10;
-var_dump( parse_ini_file($filename, $process_sections, $extra_arg) );
+$scanner_mode = 10;
+var_dump( parse_ini_file($filename, $process_sections, $scanner_mode) );

 echo "\n-- Testing parse_ini_file() function with a non-existent file --\n";
 $filename = __FILE__ . 'invalidfilename';
@@ -20,9 +20,9 @@
 --EXPECTF--
 *** Testing parse_ini_file() : error conditions ***

--- Testing parse_ini_file() function with more than expected no. of arguments --
+-- Testing parse_ini_file() function with invalid scanner mode --

-Warning: parse_ini_file(): Failed to open stream: No such file or directory in %s on line %d
+Warning: parse_ini_file(): Invalid scanner mode in %s on line %d
 bool(false)

 -- Testing parse_ini_file() function with a non-existent file --