From 1843cb06eab90fd5249d0400a26271d3ec06f213 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 18 Jul 2024 13:19:44 +0200 Subject: [PATCH 1/3] Cater to optional support of GD/GD2 image formats Prior to libgd 2.3.0, support for the proprietary GD and GD2 image formats has was mandatory. However, as of that version libgd can be built without support for these formats[1], and as of libgd 2.3.3 by default these formats are not supported[2]. If libgd is built without support for a certain image format, the respective reader and writer functions are still defined, but they are NOPs. However, PHP GD users expect the reader and writer function to only be defined, if there is actual support, so we're checking for the support during build time, and declare the `HAVE_GD_GD` macro only if support for the GD and GD2 image formats is available. We do not change the bundled libgd to make support for these formats optional, yet. [1] [2] --- ext/gd/config.m4 | 2 ++ ext/gd/config.w32 | 1 + ext/gd/gd.stub.php | 4 ++++ ext/gd/gd_arginfo.h | 38 +++++++++++++++++++++++++++++++++++--- 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/ext/gd/config.m4 b/ext/gd/config.m4 index 2a22a1aeed807..317548a287a53 100644 --- a/ext/gd/config.m4 +++ b/ext/gd/config.m4 @@ -188,6 +188,7 @@ AC_DEFUN([PHP_GD_CHECK_VERSION],[ PHP_GD_CHECK_FORMAT([Xpm], [HAVE_GD_XPM]) PHP_GD_CHECK_FORMAT([Bmp], [HAVE_GD_BMP]) PHP_GD_CHECK_FORMAT([Tga], [HAVE_GD_TGA]) + PHP_GD_CHECK_FORMAT([Gd], [HAVE_GD_GD]) PHP_CHECK_LIBRARY(gd, gdFontCacheShutdown, [AC_DEFINE(HAVE_GD_FREETYPE, 1, [ ])], [], [ $GD_SHARED_LIBADD ]) PHP_CHECK_LIBRARY(gd, gdVersionString, [AC_DEFINE(HAVE_GD_LIBVERSION, 1, [ ])], [], [ $GD_SHARED_LIBADD ]) PHP_CHECK_LIBRARY(gd, gdImageGetInterpolationMethod, [AC_DEFINE(HAVE_GD_GET_INTERPOLATION, 1, [ ])], [], [ $GD_SHARED_LIBADD ]) @@ -215,6 +216,7 @@ dnl These are always available with bundled library AC_DEFINE(HAVE_GD_PNG, 1, [ ]) AC_DEFINE(HAVE_GD_BMP, 1, [ ]) AC_DEFINE(HAVE_GD_TGA, 1, [ ]) + AC_DEFINE(HAVE_GD_GD, 1, [ ]) dnl Various checks for GD features PHP_SETUP_ZLIB([GD_SHARED_LIBADD]) diff --git a/ext/gd/config.w32 b/ext/gd/config.w32 index b779df48e91d8..501e59969e059 100644 --- a/ext/gd/config.w32 +++ b/ext/gd/config.w32 @@ -65,6 +65,7 @@ if (PHP_GD != "no") { AC_DEFINE('HAVE_GD_JPG', 1, "JPEG support"); AC_DEFINE('HAVE_XPM', 1, "XPM support"); AC_DEFINE('HAVE_GD_XPM', 1, "XPM support"); + AC_DEFINE('HAVE_GD_GD', 1, "GD/GD2 format support"); AC_DEFINE('HAVE_LIBFREETYPE', 1, "Freetype support"); AC_DEFINE('HAVE_GD_FREETYPE', 1, "Freetype support"); ADD_FLAG("CFLAGS_GD", " \ diff --git a/ext/gd/gd.stub.php b/ext/gd/gd.stub.php index 347e43e728b87..b3cbeae4b362f 100644 --- a/ext/gd/gd.stub.php +++ b/ext/gd/gd.stub.php @@ -580,6 +580,7 @@ function imagecreatefromxpm(string $filename): GdImage|false {} /** @refcount 1 */ function imagecreatefromwbmp(string $filename): GdImage|false {} +#ifdef HAVE_GD_GD /** @refcount 1 */ function imagecreatefromgd(string $filename): GdImage|false {} @@ -588,6 +589,7 @@ function imagecreatefromgd2(string $filename): GdImage|false {} /** @refcount 1 */ function imagecreatefromgd2part(string $filename, int $x, int $y, int $width, int $height): GdImage|false {} +#endif #ifdef HAVE_GD_BMP /** @refcount 1 */ @@ -626,9 +628,11 @@ function imagejpeg(GdImage $image, $file = null, int $quality = -1): bool {} /** @param resource|string|null $file */ function imagewbmp(GdImage $image, $file = null, ?int $foreground_color = null): bool {} +#ifdef HAVE_GD_GD function imagegd(GdImage $image, ?string $file = null): bool {} function imagegd2(GdImage $image, ?string $file = null, int $chunk_size = 128, int $mode = IMG_GD2_RAW): bool {} +#endif #ifdef HAVE_GD_BMP /** @param resource|string|null $file */ diff --git a/ext/gd/gd_arginfo.h b/ext/gd/gd_arginfo.h index f68b34d5e101b..00f7416d62c30 100644 --- a/ext/gd/gd_arginfo.h +++ b/ext/gd/gd_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 0f8a22bff1d123313f37da400500e573baace837 */ + * Stub hash: a9f57da0ffc7088aa327413768b5c9eb062adb4d */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_gd_info, 0, 0, IS_ARRAY, 0) ZEND_END_ARG_INFO() @@ -181,10 +181,17 @@ ZEND_END_ARG_INFO() #define arginfo_imagecreatefromwbmp arginfo_imagecreatefromgif -#define arginfo_imagecreatefromgd arginfo_imagecreatefromgif +#if defined(HAVE_GD_GD) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_imagecreatefromgd, 0, 1, GdImage, MAY_BE_FALSE) + ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) +ZEND_END_ARG_INFO() +#endif -#define arginfo_imagecreatefromgd2 arginfo_imagecreatefromgif +#if defined(HAVE_GD_GD) +#define arginfo_imagecreatefromgd2 arginfo_imagecreatefromgd +#endif +#if defined(HAVE_GD_GD) ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_imagecreatefromgd2part, 0, 5, GdImage, MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, x, IS_LONG, 0) @@ -192,6 +199,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_imagecreatefromgd2part, 0, 5 ZEND_ARG_TYPE_INFO(0, width, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, height, IS_LONG, 0) ZEND_END_ARG_INFO() +#endif #if defined(HAVE_GD_BMP) ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_imagecreatefrombmp, 0, 1, GdImage, MAY_BE_FALSE) @@ -256,17 +264,21 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_imagewbmp, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, foreground_color, IS_LONG, 1, "null") ZEND_END_ARG_INFO() +#if defined(HAVE_GD_GD) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_imagegd, 0, 1, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, image, GdImage, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, file, IS_STRING, 1, "null") ZEND_END_ARG_INFO() +#endif +#if defined(HAVE_GD_GD) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_imagegd2, 0, 1, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, image, GdImage, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, file, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, chunk_size, IS_LONG, 0, "128") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_LONG, 0, "IMG_GD2_RAW") ZEND_END_ARG_INFO() +#endif #if defined(HAVE_GD_BMP) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_imagebmp, 0, 1, _IS_BOOL, 0) @@ -624,9 +636,15 @@ ZEND_FUNCTION(imagecreatefromxbm); ZEND_FUNCTION(imagecreatefromxpm); #endif ZEND_FUNCTION(imagecreatefromwbmp); +#if defined(HAVE_GD_GD) ZEND_FUNCTION(imagecreatefromgd); +#endif +#if defined(HAVE_GD_GD) ZEND_FUNCTION(imagecreatefromgd2); +#endif +#if defined(HAVE_GD_GD) ZEND_FUNCTION(imagecreatefromgd2part); +#endif #if defined(HAVE_GD_BMP) ZEND_FUNCTION(imagecreatefrombmp); #endif @@ -648,8 +666,12 @@ ZEND_FUNCTION(imagewebp); ZEND_FUNCTION(imagejpeg); #endif ZEND_FUNCTION(imagewbmp); +#if defined(HAVE_GD_GD) ZEND_FUNCTION(imagegd); +#endif +#if defined(HAVE_GD_GD) ZEND_FUNCTION(imagegd2); +#endif #if defined(HAVE_GD_BMP) ZEND_FUNCTION(imagebmp); #endif @@ -764,9 +786,15 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(imagecreatefromxpm, arginfo_imagecreatefromxpm) #endif ZEND_FE(imagecreatefromwbmp, arginfo_imagecreatefromwbmp) +#if defined(HAVE_GD_GD) ZEND_FE(imagecreatefromgd, arginfo_imagecreatefromgd) +#endif +#if defined(HAVE_GD_GD) ZEND_FE(imagecreatefromgd2, arginfo_imagecreatefromgd2) +#endif +#if defined(HAVE_GD_GD) ZEND_FE(imagecreatefromgd2part, arginfo_imagecreatefromgd2part) +#endif #if defined(HAVE_GD_BMP) ZEND_FE(imagecreatefrombmp, arginfo_imagecreatefrombmp) #endif @@ -788,8 +816,12 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(imagejpeg, arginfo_imagejpeg) #endif ZEND_FE(imagewbmp, arginfo_imagewbmp) +#if defined(HAVE_GD_GD) ZEND_FE(imagegd, arginfo_imagegd) +#endif +#if defined(HAVE_GD_GD) ZEND_FE(imagegd2, arginfo_imagegd2) +#endif #if defined(HAVE_GD_BMP) ZEND_FE(imagebmp, arginfo_imagebmp) #endif From 5ca9c00f0a0ddf3a3f8cb68f98fc208a2594595a Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 24 Jul 2024 00:34:35 +0200 Subject: [PATCH 2/3] Cater to PHP info, gd_info() and imagetypes() Support for `imagetypes()` implies to define the respective userland constant `IMG_GD`. We also fix the missing #ifdefs for the reader and writer function definitions. --- ext/gd/gd.c | 15 +++++++++++++++ ext/gd/gd.stub.php | 5 +++++ ext/gd/gd_arginfo.h | 3 ++- ext/gd/php_gd.h | 1 + 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/ext/gd/gd.c b/ext/gd/gd.c index 5af2d4a5152bb..becee387d5c8c 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -454,6 +454,9 @@ PHP_MINFO_FUNCTION(gd) #endif #ifdef HAVE_GD_TGA php_info_print_table_row(2, "TGA Read Support", "enabled"); +#endif +#ifdef HAVE_GD_GD + php_info_print_table_row(2, "GD/GD2 Support", "enabled"); #endif php_info_print_table_end(); DISPLAY_INI_ENTRIES(); @@ -514,6 +517,11 @@ PHP_FUNCTION(gd_info) #else add_assoc_bool(return_value, "TGA Read Support", 0); #endif +#ifdef HAVE_GD_GD + add_assoc_bool(return_value, "GD/GD2 Support", 1); +#else + add_assoc_bool(return_value, "GD/GD2 Support", 0); +#endif #ifdef USE_GD_JISX0208 add_assoc_bool(return_value, "JIS-mapped Japanese Font Support", 1); #else @@ -1346,6 +1354,9 @@ PHP_FUNCTION(imagetypes) #ifdef HAVE_GD_AVIF ret |= PHP_IMG_AVIF; #endif +#ifdef HAVE_GD_GD + ret |= PHP_IMG_GD; +#endif ZEND_PARSE_PARAMETERS_NONE(); @@ -1719,6 +1730,7 @@ PHP_FUNCTION(imagecreatefromwbmp) } /* }}} */ +#ifdef HAVE_GD_GD /* {{{ Create a new image from GD file or URL */ PHP_FUNCTION(imagecreatefromgd) { @@ -1739,6 +1751,7 @@ PHP_FUNCTION(imagecreatefromgd2part) _php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GD2PART, "GD2", NULL, NULL); } /* }}} */ +#endif /* HAVE_GD_GD */ #ifdef HAVE_GD_BMP /* {{{ Create a new image from BMP file or URL */ @@ -2131,6 +2144,7 @@ PHP_FUNCTION(imagewbmp) } /* }}} */ +#ifdef HAVE_GD_GD /* {{{ Output GD image to browser or file */ PHP_FUNCTION(imagegd) { @@ -2144,6 +2158,7 @@ PHP_FUNCTION(imagegd2) _php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GD2, "GD2"); } /* }}} */ +#endif /* HAVE_GD_GD */ #ifdef HAVE_GD_BMP /* {{{ Output BMP image to browser or file */ diff --git a/ext/gd/gd.stub.php b/ext/gd/gd.stub.php index b3cbeae4b362f..7b3263f3b2331 100644 --- a/ext/gd/gd.stub.php +++ b/ext/gd/gd.stub.php @@ -52,6 +52,11 @@ * @cvalue PHP_IMG_TGA */ const IMG_TGA = UNKNOWN; +/** + * @var int + * @cvalue PHP_IMG_GD + */ +const IMG_GD = UNKNOWN; /* constant for webp encoding */ diff --git a/ext/gd/gd_arginfo.h b/ext/gd/gd_arginfo.h index 00f7416d62c30..a6973b7354ad9 100644 --- a/ext/gd/gd_arginfo.h +++ b/ext/gd/gd_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: a9f57da0ffc7088aa327413768b5c9eb062adb4d */ + * Stub hash: 4a55dca759d440e63bd41085b70bcae61ee22de4 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_gd_info, 0, 0, IS_ARRAY, 0) ZEND_END_ARG_INFO() @@ -914,6 +914,7 @@ static void register_gd_symbols(int module_number) REGISTER_LONG_CONSTANT("IMG_WEBP", PHP_IMG_WEBP, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMG_BMP", PHP_IMG_BMP, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMG_TGA", PHP_IMG_TGA, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMG_GD", PHP_IMG_GD, CONST_PERSISTENT); #if defined(gdWebpLossless) REGISTER_LONG_CONSTANT("IMG_WEBP_LOSSLESS", gdWebpLossless, CONST_PERSISTENT); #endif diff --git a/ext/gd/php_gd.h b/ext/gd/php_gd.h index 8d27f8cc75a60..b54f2b61e8cf9 100644 --- a/ext/gd/php_gd.h +++ b/ext/gd/php_gd.h @@ -54,6 +54,7 @@ #define PHP_IMG_BMP 64 #define PHP_IMG_TGA 128 #define PHP_IMG_AVIF 256 +#define PHP_IMG_GD 512 /* Section Filters Declarations */ /* IMPORTANT NOTE FOR NEW FILTER From 924fcdb231b28265379e8ff4a1e90060e687d6fd Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 24 Jul 2024 16:11:03 +0200 Subject: [PATCH 3/3] Regenerate optimizer info --- Zend/Optimizer/zend_func_infos.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Zend/Optimizer/zend_func_infos.h b/Zend/Optimizer/zend_func_infos.h index 18e28e6117104..7c2085cd38ae2 100644 --- a/Zend/Optimizer/zend_func_infos.h +++ b/Zend/Optimizer/zend_func_infos.h @@ -127,9 +127,15 @@ static const func_info_t func_infos[] = { F1("imagecreatefromxpm", MAY_BE_OBJECT|MAY_BE_FALSE), #endif F1("imagecreatefromwbmp", MAY_BE_OBJECT|MAY_BE_FALSE), +#if defined(HAVE_GD_GD) F1("imagecreatefromgd", MAY_BE_OBJECT|MAY_BE_FALSE), +#endif +#if defined(HAVE_GD_GD) F1("imagecreatefromgd2", MAY_BE_OBJECT|MAY_BE_FALSE), +#endif +#if defined(HAVE_GD_GD) F1("imagecreatefromgd2part", MAY_BE_OBJECT|MAY_BE_FALSE), +#endif #if defined(HAVE_GD_BMP) F1("imagecreatefrombmp", MAY_BE_OBJECT|MAY_BE_FALSE), #endif