Commit 1ef1dd53bb1 for php

commit 1ef1dd53bb11dbdc5a65f79d3dd1144cc38c4008
Author: cuishuang <imcusg@gmail.com>
Date:   Fri Oct 30 22:23:55 2026 +0100

    Fix json_encode() depth range check before narrowing

    json_encode() accepts $depth as a zend_long but stores it in the
    encoder's int max_depth field. On 64-bit builds, values outside the int
    range were silently narrowed, so a too large depth could wrap to a small
    one and a too small depth could wrap to INT_MAX.

    Check the value with ZEND_LONG_EXCEEDS_INT() and throw a ValueError when
    it cannot be represented as an int.

    Closes GH-23589

diff --git a/NEWS b/NEWS
index 433aa7d0297..63621c3ee7f 100644
--- a/NEWS
+++ b/NEWS
@@ -110,6 +110,8 @@ PHP                                                                        NEWS
   . Fixed json_encode() leaving the recursion guard set on objects with hooked
     properties after running out of memory while escaping a property name.
     (adapik)
+  . Fixed json_encode() silently narrowing $depth values outside the int range,
+    which wrapped to an unrelated depth. (cuishuang)

 - LDAP:
   . Fix crash in ldap_exop_sync() when $response_data is omitted. (lacatoire)
diff --git a/ext/json/json.c b/ext/json/json.c
index 9f91d39594e..0b42187491f 100644
--- a/ext/json/json.c
+++ b/ext/json/json.c
@@ -232,6 +232,11 @@ PHP_FUNCTION(json_encode)
 		Z_PARAM_LONG(depth)
 	ZEND_PARSE_PARAMETERS_END();

+	if (ZEND_LONG_EXCEEDS_INT(depth)) {
+		zend_argument_value_error(3, "must be between %d and %d", INT_MIN, INT_MAX);
+		RETURN_THROWS();
+	}
+
 	php_json_encode_init(&encoder);
 	encoder.max_depth = (int)depth;
 	php_json_encode_zval(&buf, parameter, (int)options, &encoder);
diff --git a/ext/json/tests/json_encode_depth.phpt b/ext/json/tests/json_encode_depth.phpt
new file mode 100644
index 00000000000..075228da472
--- /dev/null
+++ b/ext/json/tests/json_encode_depth.phpt
@@ -0,0 +1,19 @@
+--TEST--
+json_encode() rejects depth values outside the encoder range
+--SKIPIF--
+<?php if (PHP_INT_SIZE != 8) die("skip this test is for 64bit platform only"); ?>
+--FILE--
+<?php
+
+foreach ([2147483648, -2147483649] as $depth) {
+    try {
+        json_encode([], depth: $depth);
+    } catch (Throwable $e) {
+        echo $e::class, ': ', $e->getMessage(), "\n";
+    }
+}
+
+?>
+--EXPECT--
+ValueError: json_encode(): Argument #3 ($depth) must be between -2147483648 and 2147483647
+ValueError: json_encode(): Argument #3 ($depth) must be between -2147483648 and 2147483647