Commit 53b7b06a40d for php

commit 53b7b06a40d32a9718fe63a340d0619a6b6232da
Author: lacatoire <la.catoire@gmail.com>
Date:   Fri Oct 16 11:05:38 2026 +0200

    ext/gd: blame the points array when a polygon has too few points

    In the three-argument form, imagepolygon(), imageopenpolygon() and
    imagefilledpolygon() derive the point count from $points, but the "too few
    points" error blamed argument 3, which is the colour there. It now blames
    $points in that form, and argument 3 is kept for the deprecated $num_points
    form.

    Close GH-25372

diff --git a/NEWS b/NEWS
index 34a5a7506dc..2986eaec7c3 100644
--- a/NEWS
+++ b/NEWS
@@ -36,6 +36,8 @@ PHP                                                                        NEWS
 - GD:
   . Fixed use-after-free when drawing with a brush or tile image that was
     released after imagesetbrush() or imagesettile(). (lacatoire)
+  . Fixed the argument blamed by the imagepolygon(), imageopenpolygon() and
+    imagefilledpolygon() too few points error. (lacatoire)

 - MBString:
   . Fixed stack overflow in mb_check_encoding() and mb_convert_encoding() with
diff --git a/ext/gd/gd.c b/ext/gd/gd.c
index 2b8d7341bce..7176dfcdd54 100644
--- a/ext/gd/gd.c
+++ b/ext/gd/gd.c
@@ -2897,7 +2897,12 @@ static void php_imagepolygon(INTERNAL_FUNCTION_PARAMETERS, int filled)

 	nelem = zend_hash_num_elements(Z_ARRVAL_P(POINTS));
 	if (npoints < 3) {
-		zend_argument_value_error(3, "must be greater than or equal to 3");
+		if (COL_IS_NULL) {
+			/* The count comes from the array, argument #3 is the color */
+			zend_argument_value_error(2, "must have at least 3 points");
+		} else {
+			zend_argument_value_error(3, "must be greater than or equal to 3");
+		}
 		RETURN_THROWS();
 	}

diff --git a/ext/gd/tests/imagepolygon_too_few_points_argument.phpt b/ext/gd/tests/imagepolygon_too_few_points_argument.phpt
new file mode 100644
index 00000000000..a3ccb3d279d
--- /dev/null
+++ b/ext/gd/tests/imagepolygon_too_few_points_argument.phpt
@@ -0,0 +1,27 @@
+--TEST--
+imagepolygon(), imageopenpolygon(), imagefilledpolygon(): too few points blames the points array
+--EXTENSIONS--
+gd
+--FILE--
+<?php
+$im = imagecreatetruecolor(20, 20);
+foreach (['imagepolygon', 'imageopenpolygon', 'imagefilledpolygon'] as $f) {
+    try {
+        $f($im, [1, 1, 2, 2], 0xffffff);
+    } catch (Throwable $e) {
+        echo $e::class, ': ', $e->getMessage(), "\n";
+    }
+    try {
+        @$f($im, [1, 1, 2, 2], 2, 0xffffff);
+    } catch (Throwable $e) {
+        echo $e::class, ': ', $e->getMessage(), "\n";
+    }
+}
+?>
+--EXPECT--
+ValueError: imagepolygon(): Argument #2 ($points) must have at least 3 points
+ValueError: imagepolygon(): Argument #3 ($num_points_or_color) must be greater than or equal to 3
+ValueError: imageopenpolygon(): Argument #2 ($points) must have at least 3 points
+ValueError: imageopenpolygon(): Argument #3 ($num_points_or_color) must be greater than or equal to 3
+ValueError: imagefilledpolygon(): Argument #2 ($points) must have at least 3 points
+ValueError: imagefilledpolygon(): Argument #3 ($num_points_or_color) must be greater than or equal to 3