From a33bd49ab634b0499422da6fae6fda1abfe12dc5 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Fri, 22 May 2026 06:15:44 +0100 Subject: [PATCH] Fix GH-19739: imageellipse/imagefilledellipse overflow. Port the upstream libgd portable fix (overflowMul3) for the int64 overflow at r = a * bq when w/h reach near INT_MAX. Mirrors the upstream libgd commit 0057de6. --- ext/gd/libgd/gd.c | 7 ++++++- ext/gd/libgd/gd_security.c | 18 ++++++++++++++++++ ext/gd/libgd/gdhelpers.h | 1 + ext/gd/tests/gh19739.phpt | 19 +++++++++++++++++++ 4 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 ext/gd/tests/gh19739.phpt diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c index baa8887089ef..49d4ae31329f 100644 --- a/ext/gd/libgd/gd.c +++ b/ext/gd/libgd/gd.c @@ -1775,6 +1775,9 @@ void gdImageEllipse(gdImagePtr im, int mx, int my, int w, int h, int c) a=w>>1; b=h>>1; + if (overflowMul3(a, b, b) || overflowMul3(b, a, a)) { + return; + } gdImageSetPixel(im,mx+a, my, c); gdImageSetPixel(im,mx-a, my, c); mx1 = mx-a;my1 = my; @@ -1816,7 +1819,9 @@ void gdImageFilledEllipse (gdImagePtr im, int mx, int my, int w, int h, int c) a=w>>1; b=h>>1; - + if (overflowMul3(a, b, b) || overflowMul3(b, a, a)) { + return; + } for (x = mx-a; x <= mx+a; x++) { gdImageSetPixel(im, x, my, c); } diff --git a/ext/gd/libgd/gd_security.c b/ext/gd/libgd/gd_security.c index 438a564ff17c..cbc4872d2fce 100644 --- a/ext/gd/libgd/gd_security.c +++ b/ext/gd/libgd/gd_security.c @@ -14,6 +14,7 @@ #include #include +#include #include #include "gd.h" #include "gd_errors.h" @@ -30,3 +31,20 @@ int overflow2(int a, int b) } return 0; } + +int overflowMul3(int a, int b, int c) +{ + if (a < 0 || b < 0 || c < 0) { + return 1; + } + if (a == 0 || b == 0 || c == 0) { + return 0; + } + if (a > INT_MAX / b) { + return 1; + } + if ((int64_t)a * b > INT64_MAX / c) { + return 1; + } + return 0; +} diff --git a/ext/gd/libgd/gdhelpers.h b/ext/gd/libgd/gdhelpers.h index afb45f0e67de..202ccfce7636 100644 --- a/ext/gd/libgd/gdhelpers.h +++ b/ext/gd/libgd/gdhelpers.h @@ -27,6 +27,7 @@ extern char *gd_strtok_r(char *s, char *sep, char **state); netpbm fixes by Alan Cox. */ int overflow2(int a, int b); +int overflowMul3(int a, int b, int c); #ifdef ZTS #define gdMutexDeclare(x) MUTEX_T x diff --git a/ext/gd/tests/gh19739.phpt b/ext/gd/tests/gh19739.phpt new file mode 100644 index 000000000000..7c9372261050 --- /dev/null +++ b/ext/gd/tests/gh19739.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-19739 (integer overflow in imageellipse / imagefilledellipse) +--EXTENSIONS-- +gd +--FILE-- + +--EXPECT-- +bool(true) +bool(true) +done