Commit 6947fe15b39 for php

commit 6947fe15b396211c2421ac9dec549f1d31939271
Merge: bbed764507c bba94675f51
Author: Ilia Alshanetsky <ilia@ilia.ws>
Date:   Tue Oct 20 07:46:20 2026 -0400

    Merge branch 'PHP-8.4' into PHP-8.5

    * PHP-8.4:
      ext/pdo: Validate Oracle null handling modes

diff --cc NEWS
index 714bb44ebb9,5f966a6ea0f..b37e5fb8d8a
--- a/NEWS
+++ b/NEWS
@@@ -73,10 -83,10 +73,12 @@@ PH
      reference check). (ndossche)

  - PDO:
+   . Fixed invalid ATTR_ORACLE_NULLS values being accepted and truncated.
+     (Ilia Alshanetsky)
    . Fixed a duplicate warning when ATTR_STATEMENT_CLASS is rejected on a
      persistent connection. (Ilia Alshanetsky)
 +  . Fixed constructor option errors naming argument #3 ($password) instead
 +    of argument #4 ($options). (Ilia Alshanetsky)

  - Phpdbg:
    . Fix wrong command names. (ndossche, Weilin Du)
diff --cc ext/pdo/pdo_dbh.c
index fcb1ff4498a,804cbb64407..8f5ab3097db
--- a/ext/pdo/pdo_dbh.c
+++ b/ext/pdo/pdo_dbh.c
@@@ -860,9 -854,16 +860,16 @@@ static bool pdo_dbh_attribute_set(pdo_d
  			if (!pdo_get_long_param(&lval, value)) {
  				return false;
  			}
- 			/* TODO Check for valid value (NULL_NATURAL, NULL_EMPTY_STRING, NULL_TO_STRING)? */
- 			dbh->oracle_nulls = lval;
- 			return true;
+ 			switch (lval) {
+ 				case PDO_NULL_NATURAL:
+ 				case PDO_NULL_EMPTY_STRING:
+ 				case PDO_NULL_TO_STRING:
+ 					dbh->oracle_nulls = lval;
+ 					return true;
+ 				default:
 -					zend_value_error("PDO::ATTR_ORACLE_NULLS must be one of the PDO::NULL_* constants");
++					zend_argument_value_error(value_arg_num, "PDO::ATTR_ORACLE_NULLS must be one of the PDO::NULL_* constants");
+ 					return false;
+ 			}

  		case PDO_ATTR_DEFAULT_FETCH_MODE:
  			if (Z_TYPE_P(value) == IS_ARRAY) {
diff --cc ext/pdo/tests/pdo_oracle_nulls_invalid.phpt
index 00000000000,30b251e1915..64595562d67
mode 000000,100644..100644
--- a/ext/pdo/tests/pdo_oracle_nulls_invalid.phpt
+++ b/ext/pdo/tests/pdo_oracle_nulls_invalid.phpt
@@@ -1,0 -1,49 +1,49 @@@
+ --TEST--
+ PDO Common: Invalid Oracle null handling modes do not change the attribute
+ --EXTENSIONS--
+ pdo
+ --SKIPIF--
+ <?php
+ $dir = getenv('REDIR_TEST_DIR');
+ if ($dir === false) {
+     die('skip no driver');
+ }
+ require_once $dir . 'pdo_test.inc';
+ PDOTest::skip();
+ ?>
+ --FILE--
+ <?php
+ require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+ $pdo = PDOTest::factory();
+
+ foreach ([PDO::NULL_NATURAL, PDO::NULL_EMPTY_STRING, PDO::NULL_TO_STRING] as $value) {
+     echo "Valid mode: ";
+     var_dump($pdo->setAttribute(PDO::ATTR_ORACLE_NULLS, $value));
+     var_dump($pdo->getAttribute(PDO::ATTR_ORACLE_NULLS));
+ }
+
+ foreach ([-1, 3, 4, PHP_INT_MAX] as $value) {
+     try {
+         $pdo->setAttribute(PDO::ATTR_ORACLE_NULLS, $value);
+     } catch (ValueError $e) {
+         echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+     }
+     echo "Unchanged mode: ";
+     var_dump($pdo->getAttribute(PDO::ATTR_ORACLE_NULLS));
+ }
+ ?>
+ --EXPECT--
+ Valid mode: bool(true)
+ int(0)
+ Valid mode: bool(true)
+ int(1)
+ Valid mode: bool(true)
+ int(2)
 -ValueError: PDO::ATTR_ORACLE_NULLS must be one of the PDO::NULL_* constants
++ValueError: PDO::setAttribute(): Argument #2 ($value) PDO::ATTR_ORACLE_NULLS must be one of the PDO::NULL_* constants
+ Unchanged mode: int(2)
 -ValueError: PDO::ATTR_ORACLE_NULLS must be one of the PDO::NULL_* constants
++ValueError: PDO::setAttribute(): Argument #2 ($value) PDO::ATTR_ORACLE_NULLS must be one of the PDO::NULL_* constants
+ Unchanged mode: int(2)
 -ValueError: PDO::ATTR_ORACLE_NULLS must be one of the PDO::NULL_* constants
++ValueError: PDO::setAttribute(): Argument #2 ($value) PDO::ATTR_ORACLE_NULLS must be one of the PDO::NULL_* constants
+ Unchanged mode: int(2)
 -ValueError: PDO::ATTR_ORACLE_NULLS must be one of the PDO::NULL_* constants
++ValueError: PDO::setAttribute(): Argument #2 ($value) PDO::ATTR_ORACLE_NULLS must be one of the PDO::NULL_* constants
+ Unchanged mode: int(2)