Commit dddbca6ec6c for php.net

commit dddbca6ec6ca83ddc610c1996c5c56cba22875ae
Author: lacatoire <la.catoire@gmail.com>
Date:   Fri Sep 4 04:47:38 2026 +0100

    ext/gd: report $size with the argument number of the function called

    php_imagettftext_common() serves the bbox functions, where $size is
    argument #1, and the drawing ones, where it is #2, but its two size
    checks hardcode 2. imageftbbox(NAN, ...) therefore blamed $angle.

    Also fix the upper bound itself: (double)LONG_MAX rounds up to 2^63, so
    (double)LONG_MAX / 64 is 2^57 and the check let 2^57 through, whose
    product with 64 is LONG_MAX + 1. The bound is now exclusive, and the
    reported values use integer division, which gives the largest size that
    is actually representable. The lower bound stays inclusive:
    (double)LONG_MIN / 64 is exactly -2^57 and its product with 64 is
    LONG_MIN.

    Co-authored-by: NickSdot <32384907+NickSdot@users.noreply.github.com>

    Close GH-23541

diff --git a/ext/gd/gd.c b/ext/gd/gd.c
index 7f55b8bcc74..6a056287c45 100644
--- a/ext/gd/gd.c
+++ b/ext/gd/gd.c
@@ -3422,14 +3422,16 @@ static void php_imagettftext_common(INTERNAL_FUNCTION_PARAMETERS, int mode)
 		im = php_gd_libgdimageptr_from_zval_p(IM);
 	}

+	uint32_t ptsize_arg_num = mode == TTFTEXT_BBOX ? 1 : 2;
+
 	// FT_F26Dot6 is a signed long alias
-	if (ptsize < (double)LONG_MIN / 64 || ptsize > (double)LONG_MAX / 64) {
-		zend_argument_value_error(2, "must be between " ZEND_LONG_FMT " and " ZEND_LONG_FMT, (zend_long)((double)LONG_MIN / 64), (zend_long)((double)LONG_MAX / 64));
+	if (ptsize < (double)LONG_MIN / 64 || ptsize >= (double)LONG_MAX / 64) {
+		zend_argument_value_error(ptsize_arg_num, "must be between " ZEND_LONG_FMT " and " ZEND_LONG_FMT, (zend_long)(LONG_MIN / 64), (zend_long)(LONG_MAX / 64));
 		RETURN_THROWS();
 	}

 	if (UNEXPECTED(!zend_finite(ptsize))) {
-		zend_argument_value_error(2, "must be finite");
+		zend_argument_value_error(ptsize_arg_num, "must be finite");
 		RETURN_THROWS();
 	}

diff --git a/ext/gd/tests/gh18243.phpt b/ext/gd/tests/gh18243.phpt
index 00698add614..de0ac1861fb 100644
--- a/ext/gd/tests/gh18243.phpt
+++ b/ext/gd/tests/gh18243.phpt
@@ -34,9 +34,16 @@
 } catch (\ValueError $e) {
 	echo $e::class, ': ', $e->getMessage(), PHP_EOL;
 }
+
+try {
+	imagettftext($im, 144115188075855872.0, 0, 15, 60, 0, $font, "");
+} catch (Throwable $e) {
+	echo $e::class, ': ', $e->getMessage(), "\n";
+}
 ?>
 --EXPECTF--
 ValueError: imagettftext(): Argument #2 ($size) must be between %i and %d
 ValueError: imagettftext(): Argument #2 ($size) must be between %i and %d
 ValueError: imagettftext(): Argument #2 ($size) must be finite
 ValueError: imagettftext(): Argument #2 ($size) must be between %i and %d
+ValueError: imagettftext(): Argument #2 ($size) must be between %i and %d
diff --git a/ext/gd/tests/imageftbbox_size_arg_num.phpt b/ext/gd/tests/imageftbbox_size_arg_num.phpt
new file mode 100644
index 00000000000..b968817c48c
--- /dev/null
+++ b/ext/gd/tests/imageftbbox_size_arg_num.phpt
@@ -0,0 +1,62 @@
+--TEST--
+The $size errors name the argument of the function that was called
+--EXTENSIONS--
+gd
+--SKIPIF--
+<?php
+if (!function_exists('imageftbbox')) die('skip imageftbbox() not available');
+?>
+--FILE--
+<?php
+$font = __DIR__ . '/Rochester-Regular.otf';
+$image = imagecreatetruecolor(100, 80);
+
+/* $size is argument #1 here */
+foreach ([NAN, INF, PHP_INT_MAX, PHP_INT_MIN] as $size) {
+    try {
+        imageftbbox($size, 0.0, $font, 'A');
+    } catch (Throwable $e) {
+        echo $e::class, ': ', $e->getMessage(), "\n";
+    }
+    try {
+        imagettfbbox($size, 0.0, $font, 'A');
+    } catch (Throwable $e) {
+        echo $e::class, ': ', $e->getMessage(), "\n";
+    }
+}
+
+/* and argument #2 here */
+foreach ([NAN, INF] as $size) {
+    try {
+        imagefttext($image, $size, 0.0, 15, 60, 0, $font, 'A');
+    } catch (Throwable $e) {
+        echo $e::class, ': ', $e->getMessage(), "\n";
+    }
+    try {
+        imagettftext($image, $size, 0.0, 15, 60, 0, $font, 'A');
+    } catch (Throwable $e) {
+        echo $e::class, ': ', $e->getMessage(), "\n";
+    }
+}
+
+/* the type error already agreed with the signature and still does */
+try {
+    imageftbbox('x', 0.0, $font, 'A');
+} catch (Throwable $e) {
+    echo $e::class, ': ', $e->getMessage(), "\n";
+}
+?>
+--EXPECTF--
+ValueError: imageftbbox(): Argument #1 ($size) must be finite
+ValueError: imagettfbbox(): Argument #1 ($size) must be finite
+ValueError: imageftbbox(): Argument #1 ($size) must be between %i and %d
+ValueError: imagettfbbox(): Argument #1 ($size) must be between %i and %d
+ValueError: imageftbbox(): Argument #1 ($size) must be between %i and %d
+ValueError: imagettfbbox(): Argument #1 ($size) must be between %i and %d
+ValueError: imageftbbox(): Argument #1 ($size) must be between %i and %d
+ValueError: imagettfbbox(): Argument #1 ($size) must be between %i and %d
+ValueError: imagefttext(): Argument #2 ($size) must be finite
+ValueError: imagettftext(): Argument #2 ($size) must be finite
+ValueError: imagefttext(): Argument #2 ($size) must be between %i and %d
+ValueError: imagettftext(): Argument #2 ($size) must be between %i and %d
+TypeError: imageftbbox(): Argument #1 ($size) must be of type float, string given