summaryrefslogtreecommitdiff
path: root/ext/gd
diff options
context:
space:
mode:
Diffstat (limited to 'ext/gd')
-rw-r--r--ext/gd/config.m478
-rw-r--r--ext/gd/config.w3210
-rw-r--r--ext/gd/gd.c215
-rw-r--r--ext/gd/gd_ctx.c4
-rw-r--r--ext/gd/libgd/gd.c175
-rw-r--r--ext/gd/libgd/gd.h22
-rw-r--r--ext/gd/libgd/gd_gif_in.c335
-rw-r--r--ext/gd/libgd/gd_png.c23
-rw-r--r--ext/gd/libgd/gd_security.c33
-rw-r--r--ext/gd/libgd/gd_topal.c1
-rw-r--r--ext/gd/libgd/gdft.c46
-rw-r--r--ext/gd/libgd/gdhelpers.h7
-rw-r--r--ext/gd/libgd/gdtest.c8
-rw-r--r--ext/gd/libgd/wbmp.c18
-rw-r--r--ext/gd/libgd/webpng.c2
-rw-r--r--ext/gd/libgd/xbm.c4
-rw-r--r--ext/gd/php_gd.h11
-rw-r--r--ext/gd/tests/bug37360.phpt3
-rw-r--r--ext/gd/tests/bug38179.phpt2
-rw-r--r--ext/gd/tests/bug38212.phpt5
-rw-r--r--ext/gd/tests/bug39273.phpt32
-rw-r--r--ext/gd/tests/bug39286.phpt14
-rw-r--r--ext/gd/tests/bug39366.phpt21
-rw-r--r--ext/gd/tests/bug39508.phpt16
-rw-r--r--ext/gd/tests/bug39780.phpt21
-rw-r--r--ext/gd/tests/bug39780.pngbin0 -> 393216 bytes
-rw-r--r--ext/gd/tests/bug40764.phpt31
-rw-r--r--ext/gd/tests/createfromwbmp2.phpt47
-rw-r--r--ext/gd/tests/gif.phpt3
-rw-r--r--ext/gd/tests/test_gif_2.gifbin33641 -> 0 bytes
30 files changed, 929 insertions, 258 deletions
diff --git a/ext/gd/config.m4 b/ext/gd/config.m4
index cf4001755..524e75236 100644
--- a/ext/gd/config.m4
+++ b/ext/gd/config.m4
@@ -1,10 +1,10 @@
dnl
-dnl $Id: config.m4,v 1.154.2.1 2005/11/29 18:25:59 tony2001 Exp $
+dnl $Id: config.m4,v 1.154.2.1.2.3 2007/04/04 00:47:55 pajoye Exp $
dnl
dnl
dnl Configure options
-dnl
+dnl
PHP_ARG_WITH(gd, for GD support,
[ --with-gd[=DIR] Include GD support where DIR is GD install prefix.
@@ -21,7 +21,7 @@ if test -z "$PHP_PNG_DIR"; then
fi
if test -z "$PHP_ZLIB_DIR"; then
- PHP_ARG_WITH(zlib-dir, for the location of libz,
+ PHP_ARG_WITH(zlib-dir, for the location of libz,
[ --with-zlib-dir[=DIR] GD: Set the path to libz install prefix], no, no)
fi
@@ -30,7 +30,7 @@ PHP_ARG_WITH(xpm-dir, for the location of libXpm,
PHP_ARG_WITH(ttf, for FreeType 1.x support,
[ --with-ttf[=DIR] GD: Include FreeType 1.x support], no, no)
-
+
PHP_ARG_WITH(freetype-dir, for FreeType 2,
[ --with-freetype-dir[=DIR] GD: Set the path to FreeType 2 install prefix], no, no)
@@ -43,9 +43,33 @@ PHP_ARG_ENABLE(gd-native-ttf, whether to enable truetype string function in GD,
PHP_ARG_ENABLE(gd-jis-conv, whether to enable JIS-mapped Japanese font support in GD,
[ --enable-gd-jis-conv GD: Enable JIS-mapped Japanese font support], no, no)
-dnl
-dnl Checks for the configure options
-dnl
+dnl
+dnl Checks for the configure options
+dnl
+
+AC_DEFUN([PHP_GD_ZLIB],[
+ if test "$PHP_ZLIB_DIR" != "no" && test "$PHP_ZLIB_DIR" != "yes"; then
+ if test -f "$PHP_ZLIB_DIR/include/zlib/zlib.h"; then
+ PHP_ZLIB_DIR="$PHP_ZLIB_DIR"
+ PHP_ZLIB_INCDIR="$PHP_ZLIB_DIR/include/zlib"
+ elif test -f "$PHP_ZLIB_DIR/include/zlib.h"; then
+ PHP_ZLIB_DIR="$PHP_ZLIB_DIR"
+ PHP_ZLIB_INCDIR="$PHP_ZLIB_DIR/include"
+ else
+ AC_MSG_ERROR([Can't find zlib headers under "$PHP_ZLIB_DIR"])
+ fi
+ else
+ for i in /usr/local /usr; do
+ if test -f "$i/include/zlib/zlib.h"; then
+ PHP_ZLIB_DIR="$i"
+ PHP_ZLIB_INCDIR="$i/include/zlib"
+ elif test -f "$i/include/zlib.h"; then
+ PHP_ZLIB_DIR="$i"
+ PHP_ZLIB_INCDIR="$i/include"
+ fi
+ done
+ fi
+])
AC_DEFUN([PHP_GD_JPEG],[
if test "$PHP_JPEG_DIR" != "no"; then
@@ -63,11 +87,11 @@ AC_DEFUN([PHP_GD_JPEG],[
PHP_ADD_INCLUDE($GD_JPEG_DIR/include)
PHP_ADD_LIBRARY_WITH_PATH(jpeg, $GD_JPEG_DIR/$PHP_LIBDIR, GD_SHARED_LIBADD)
],[
- AC_MSG_ERROR([Problem with libjpeg.(a|so). Please check config.log for more information.])
+ AC_MSG_ERROR([Problem with libjpeg.(a|so). Please check config.log for more information.])
],[
-L$GD_JPEG_DIR/$PHP_LIBDIR
])
- else
+ else
AC_MSG_RESULT([If configure fails try --with-jpeg-dir=<DIR>])
fi
])
@@ -97,12 +121,12 @@ AC_DEFUN([PHP_GD_PNG],[
PHP_ADD_LIBRARY_WITH_PATH(z, $PHP_ZLIB_DIR/$PHP_LIBDIR, GD_SHARED_LIBADD)
PHP_ADD_LIBRARY_WITH_PATH(png, $GD_PNG_DIR/$PHP_LIBDIR, GD_SHARED_LIBADD)
],[
- AC_MSG_ERROR([Problem with libpng.(a|so) or libz.(a|so). Please check config.log for more information.])
+ AC_MSG_ERROR([Problem with libpng.(a|so) or libz.(a|so). Please check config.log for more information.])
],[
-L$PHP_ZLIB_DIR/$PHP_LIBDIR -lz -L$GD_PNG_DIR/$PHP_LIBDIR
])
- else
+ else
AC_MSG_RESULT([If configure fails try --with-png-dir=<DIR> and --with-zlib-dir=<DIR>])
fi
])
@@ -126,17 +150,17 @@ AC_DEFUN([PHP_GD_XPM],[
AC_MSG_ERROR([xpm.h not found.])
fi
- PHP_CHECK_LIBRARY(Xpm,XpmFreeXpmImage,
+ PHP_CHECK_LIBRARY(Xpm,XpmFreeXpmImage,
[
PHP_ADD_INCLUDE($GD_XPM_INC)
PHP_ADD_LIBRARY_WITH_PATH(Xpm, $GD_XPM_DIR/$PHP_LIBDIR, GD_SHARED_LIBADD)
PHP_ADD_LIBRARY_WITH_PATH(X11, $GD_XPM_DIR/$PHP_LIBDIR, GD_SHARED_LIBADD)
],[
- AC_MSG_ERROR([Problem with libXpm.(a|so) or libX11.(a|so). Please check config.log for more information.])
+ AC_MSG_ERROR([Problem with libXpm.(a|so) or libX11.(a|so). Please check config.log for more information.])
],[
-L$GD_XPM_DIR/$PHP_LIBDIR -lX11
])
- else
+ else
AC_MSG_RESULT(If configure fails try --with-xpm-dir=<DIR>)
fi
])
@@ -186,7 +210,7 @@ AC_DEFUN([PHP_GD_FREETYPE2],[
break
fi
done
-
+
if test -n "$FREETYPE2_DIR" ; then
PHP_ADD_LIBRARY_WITH_PATH(freetype, $FREETYPE2_DIR/$PHP_LIBDIR, GD_SHARED_LIBADD)
PHP_ADD_INCLUDE($FREETYPE2_DIR/include)
@@ -196,7 +220,7 @@ AC_DEFUN([PHP_GD_FREETYPE2],[
else
AC_MSG_ERROR([freetype2 not found!])
fi
- else
+ else
AC_MSG_RESULT([If configure fails try --with-freetype-dir=<DIR>])
fi
])
@@ -209,7 +233,7 @@ AC_DEFUN([PHP_GD_T1LIB],[
done
if test -z "$GD_T1_DIR"; then
- AC_MSG_ERROR([Your t1lib distribution is not installed correctly. Please reinstall it.])
+ AC_MSG_ERROR([Your t1lib distribution is not installed correctly. Please reinstall it.])
fi
PHP_CHECK_LIBRARY(t1, T1_StrError,
@@ -218,7 +242,7 @@ AC_DEFUN([PHP_GD_T1LIB],[
PHP_ADD_INCLUDE($GD_T1_DIR/include)
PHP_ADD_LIBRARY_WITH_PATH(t1, $GD_T1_DIR/$PHP_LIBDIR, GD_SHARED_LIBADD)
],[
- AC_MSG_ERROR([Problem with libt1.(a|so). Please check config.log for more information.])
+ AC_MSG_ERROR([Problem with libt1.(a|so). Please check config.log for more information.])
],[
-L$GD_T1_DIR/$PHP_LIBDIR
])
@@ -260,12 +284,13 @@ AC_DEFUN([PHP_GD_CHECK_VERSION],[
PHP_CHECK_LIBRARY(gd, gdCacheCreate, [AC_DEFINE(HAVE_GD_CACHE_CREATE, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
PHP_CHECK_LIBRARY(gd, gdFontCacheShutdown, [AC_DEFINE(HAVE_GD_FONTCACHESHUTDOWN,1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
PHP_CHECK_LIBRARY(gd, gdFreeFontCache, [AC_DEFINE(HAVE_GD_FREEFONTCACHE, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
+ PHP_CHECK_LIBRARY(gd, gdFontCacheMutexSetup, [AC_DEFINE(HAVE_GD_FONTMUTEX, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
PHP_CHECK_LIBRARY(gd, gdNewDynamicCtxEx, [AC_DEFINE(HAVE_GD_DYNAMIC_CTX_EX, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
])
dnl
dnl Main GD configure
-dnl
+dnl
if test "$PHP_GD" = "yes"; then
GD_MODULE_TYPE=builtin
@@ -274,15 +299,16 @@ if test "$PHP_GD" = "yes"; then
libgd/gdxpm.c libgd/gdfontt.c libgd/gdfonts.c libgd/gdfontmb.c libgd/gdfontl.c \
libgd/gdfontg.c libgd/gdtables.c libgd/gdft.c libgd/gdcache.c libgd/gdkanji.c \
libgd/wbmp.c libgd/gd_wbmp.c libgd/gdhelpers.c libgd/gd_topal.c libgd/gd_gif_in.c \
- libgd/xbm.c libgd/gd_gif_out.c "
+ libgd/xbm.c libgd/gd_gif_out.c libgd/gd_security.c"
dnl check for fabsf and floorf which are available since C99
AC_CHECK_FUNCS(fabsf floorf)
dnl PNG is required by GD library
test "$PHP_PNG_DIR" = "no" && PHP_PNG_DIR=yes
-
+
dnl Various checks for GD features
+ PHP_GD_ZLIB
PHP_GD_TTSTR
PHP_GD_JISX0208
PHP_GD_JPEG
@@ -297,7 +323,7 @@ dnl These are always available with bundled library
AC_DEFINE(HAVE_LIBGD13, 1, [ ])
AC_DEFINE(HAVE_LIBGD15, 1, [ ])
AC_DEFINE(HAVE_LIBGD20, 1, [ ])
- AC_DEFINE(HAVE_LIBGD204, 1, [ ])
+ AC_DEFINE(HAVE_LIBGD204, 1, [ ])
AC_DEFINE(HAVE_GD_IMAGESETTILE, 1, [ ])
AC_DEFINE(HAVE_GD_IMAGESETBRUSH, 1, [ ])
AC_DEFINE(HAVE_GDIMAGECOLORRESOLVE, 1, [ ])
@@ -311,6 +337,7 @@ dnl These are always available with bundled library
AC_DEFINE(HAVE_GD_GIF_CREATE, 1, [ ])
AC_DEFINE(HAVE_GD_IMAGEELLIPSE, 1, [ ])
AC_DEFINE(HAVE_GD_FONTCACHESHUTDOWN,1, [ ])
+ AC_DEFINE(HAVE_GD_FONTMUTEX, 1, [ ])
AC_DEFINE(HAVE_GD_DYNAMIC_CTX_EX, 1, [ ])
AC_DEFINE(HAVE_GD_GIF_CTX, 1, [ ])
@@ -329,7 +356,7 @@ dnl enable the support in bundled GD library
AC_DEFINE(HAVE_GD_XPM, 1, [ ])
GDLIB_CFLAGS="$GDLIB_CFLAGS -DHAVE_XPM"
fi
-
+
if test -n "$FREETYPE2_DIR"; then
AC_DEFINE(HAVE_GD_STRINGFT, 1, [ ])
AC_DEFINE(HAVE_GD_STRINGFTEX, 1, [ ])
@@ -352,6 +379,7 @@ else
extra_sources="gdcache.c"
dnl Various checks for GD features
+ PHP_GD_ZLIB
PHP_GD_TTSTR
PHP_GD_JPEG
PHP_GD_PNG
@@ -378,7 +406,7 @@ dnl Library path
AC_MSG_ERROR([Unable to find gd.h anywhere under $PHP_GD])
else
AC_MSG_ERROR([Unable to find libgd.(a|so) anywhere under $PHP_GD])
- fi
+ fi
PHP_EXPAND_PATH($GD_INCLUDE, GD_INCLUDE)
@@ -416,7 +444,7 @@ if test "$PHP_GD" != "no"; then
GD_HEADER_DIRS="ext/gd/"
GDLIB_CFLAGS="-I$GD_INCLUDE $GDLIB_CFLAGS"
PHP_ADD_INCLUDE($GD_INCLUDE)
-
+
PHP_CHECK_LIBRARY(gd, gdImageCreate, [], [
AC_MSG_ERROR([GD build test failed. Please check the config.log for details.])
], [ -L$GD_LIB $GD_SHARED_LIBADD ])
diff --git a/ext/gd/config.w32 b/ext/gd/config.w32
index 70faeb93c..b842de983 100644
--- a/ext/gd/config.w32
+++ b/ext/gd/config.w32
@@ -1,4 +1,4 @@
-// $Id: config.w32,v 1.10 2005/08/07 21:00:28 sniper Exp $
+// $Id: config.w32,v 1.10.4.4 2007/04/17 15:31:45 pajoye Exp $
// vim:ft=javascript
ARG_WITH("gd", "Bundled GD support", "yes,shared");
@@ -24,12 +24,15 @@ if (PHP_GD != "no") {
CHECK_LIB("zlib.lib", "gd", PHP_GD);
}
+ CHECK_LIB("User32.lib", "gd", PHP_GD);
+ CHECK_LIB("Gdi32.lib", "gd", PHP_GD);
+
EXTENSION("gd", "gd.c gdttf.c", null, "-Iext/gd/libgd", "php_gd2.dll");
ADD_SOURCES("ext/gd/libgd", "gd2copypal.c gd_arc_f_buggy.c gd.c \
gdcache.c gdfontg.c gdfontl.c gdfontmb.c gdfonts.c gdfontt.c \
gdft.c gd_gd2.c gd_gd.c gd_gif_in.c gd_gif_out.c gdhelpers.c gd_io.c gd_io_dp.c \
gd_io_file.c gd_io_ss.c gd_jpeg.c gdkanji.c gd_png.c gd_ss.c \
- gdtables.c gd_topal.c gd_wbmp.c gdxpm.c wbmp.c xbm.c", "gd");
+ gdtables.c gd_topal.c gd_wbmp.c gdxpm.c wbmp.c xbm.c gd_security.c", "gd");
AC_DEFINE('HAVE_LIBGD', 1, 'GD support');
ADD_FLAG("CFLAGS_GD", " \
/D HAVE_GD_DYNAMIC_CTX_EX=1 \
@@ -40,6 +43,9 @@ if (PHP_GD != "no") {
/D HAVE_GDIMAGECOLORRESOLVE=1 \
/D HAVE_GD_IMAGESETBRUSH=1 \
/D HAVE_GD_IMAGESETTILE=1 \
+/D HAVE_GD_FONTCACHESHUTDOWN=1 \
+/D HAVE_GD_FONTMUTEX=1 \
+/D HAVE_LIBFREETYPE=1 \
/D HAVE_GD_JPG \
/D HAVE_GD_PNG \
/D HAVE_GD_STRINGFTEX=1 \
diff --git a/ext/gd/gd.c b/ext/gd/gd.c
index 7fa66d014..7d64fd28b 100644
--- a/ext/gd/gd.c
+++ b/ext/gd/gd.c
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2006 The PHP Group |
+ | Copyright (c) 1997-2007 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: gd.c,v 1.312.2.20.2.8 2006/10/18 16:04:37 bjori Exp $ */
+/* $Id: gd.c,v 1.312.2.20.2.24 2007/04/24 12:51:22 sniper Exp $ */
/* gd 1.2 is copyright 1994, 1995, Quest Protein Database Center,
Cold Spring Harbor Labs. */
@@ -52,6 +52,9 @@
#ifdef PHP_WIN32
# include <io.h>
# include <fcntl.h>
+#include <windows.h>
+#include <Winuser.h>
+#include <Wingdi.h>
#endif
#if HAVE_LIBGD
@@ -314,6 +317,18 @@ ZEND_BEGIN_ARG_INFO(arginfo_imagecopyresampled, 0)
ZEND_END_ARG_INFO()
#endif
+#ifdef PHP_WIN32
+static
+ZEND_BEGIN_ARG_INFO_EX(arginfo_imagegrabwindow, 0, 0, 1)
+ ZEND_ARG_INFO(0, handle)
+ ZEND_ARG_INFO(0, client_area)
+ZEND_END_ARG_INFO()
+
+static
+ZEND_BEGIN_ARG_INFO(arginfo_imagegrabscreen, 0)
+ZEND_END_ARG_INFO()
+#endif
+
#ifdef HAVE_GD_BUNDLED
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_imagerotate, 0, 0, 3)
@@ -1020,6 +1035,11 @@ zend_function_entry gd_functions[] = {
PHP_FE(imagecopyresampled, arginfo_imagecopyresampled)
#endif
+#ifdef PHP_WIN32
+ PHP_FE(imagegrabwindow, arginfo_imagegrabwindow)
+ PHP_FE(imagegrabscreen, arginfo_imagegrabscreen)
+#endif
+
#ifdef HAVE_GD_BUNDLED
PHP_FE(imagerotate, arginfo_imagerotate)
PHP_FE(imageantialias, arginfo_imageantialias)
@@ -1147,9 +1167,13 @@ zend_module_entry gd_module_entry = {
"gd",
gd_functions,
PHP_MINIT(gd),
+#if HAVE_LIBT1 || HAVE_GD_FONTMUTEX
PHP_MSHUTDOWN(gd),
+#else
NULL,
-#if HAVE_LIBGD20 && HAVE_GD_STRINGFT && (HAVE_GD_FONTCACHESHUTDOWN || HAVE_GD_FREEFONTCACHE)
+#endif
+ NULL,
+#if HAVE_LIBGD20 && HAVE_GD_STRINGFT && (HAVE_LIBFREETYPE && (HAVE_GD_FONTCACHESHUTDOWN || HAVE_GD_FREEFONTCACHE))
PHP_RSHUTDOWN(gd),
#else
NULL,
@@ -1191,15 +1215,21 @@ static void php_free_gd_font(zend_rsrc_list_entry *rsrc TSRMLS_DC)
}
/* }}} */
+
/* {{{ PHP_MSHUTDOWN_FUNCTION
*/
+#if HAVE_LIBT1 || HAVE_GD_FONTMUTEX
PHP_MSHUTDOWN_FUNCTION(gd)
{
#if HAVE_LIBT1
T1_CloseLib();
#endif
+#if HAVE_GD_FONTMUTEX && HAVE_LIBFREETYPE
+ gdFontCacheMutexShutdown();
+#endif
return SUCCESS;
}
+#endif
/* }}} */
@@ -1209,6 +1239,10 @@ PHP_MINIT_FUNCTION(gd)
{
le_gd = zend_register_list_destructors_ex(php_free_gd_image, NULL, "gd", module_number);
le_gd_font = zend_register_list_destructors_ex(php_free_gd_font, NULL, "gd font", module_number);
+
+#if HAVE_GD_FONTMUTEX && HAVE_LIBFREETYPE
+ gdFontCacheMutexSetup();
+#endif
#if HAVE_LIBT1
T1_SetBitmapPad(8);
T1_InitLib(NO_LOGFILE | IGNORE_CONFIGFILE | IGNORE_FONTDATABASE);
@@ -1292,7 +1326,7 @@ PHP_MINIT_FUNCTION(gd)
/* {{{ PHP_RSHUTDOWN_FUNCTION
*/
-#if HAVE_LIBGD20 && HAVE_GD_STRINGFT && (HAVE_GD_FONTCACHESHUTDOWN || HAVE_GD_FREEFONTCACHE)
+#if HAVE_LIBGD20 && HAVE_GD_STRINGFT && (HAVE_LIBFREETYPE && (HAVE_GD_FONTCACHESHUTDOWN || HAVE_GD_FREEFONTCACHE))
PHP_RSHUTDOWN_FUNCTION(gd)
{
#if HAVE_GD_FONTCACHESHUTDOWN
@@ -1306,7 +1340,7 @@ PHP_RSHUTDOWN_FUNCTION(gd)
/* }}} */
#if HAVE_GD_BUNDLED
-#define PHP_GD_VERSION_STRING "bundled (2.0.28 compatible)"
+#define PHP_GD_VERSION_STRING "bundled (2.0.34 compatible)"
#elif HAVE_LIBGD20
#define PHP_GD_VERSION_STRING "2.0 or higher"
#elif HAVE_GDIMAGECOLORRESOLVE
@@ -2055,6 +2089,155 @@ PHP_FUNCTION(imagecopyresampled)
/* }}} */
#endif
+#ifdef PHP_WIN32
+/* {{{ proto resource imagegrabwindow(int window_handle [, int client_area])
+ Grab a window or its client area using a windows handle (HWND property in COM instance) */
+PHP_FUNCTION(imagegrabwindow)
+{
+ HWND window;
+ long client_area = 0;
+ RECT rc = {0};
+ RECT rc_win = {0};
+ int Width, Height;
+ HDC hdc;
+ HDC memDC;
+ HBITMAP memBM;
+ HBITMAP hOld;
+ HINSTANCE handle;
+ long lwindow_handle;
+ typedef BOOL (WINAPI *tPrintWindow)(HWND, HDC,UINT);
+ tPrintWindow pPrintWindow = 0;
+ gdImagePtr im;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &lwindow_handle, &client_area) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ window = (HWND) lwindow_handle;
+
+ if (!IsWindow(window)) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Invalid window handle");
+ RETURN_FALSE;
+ }
+
+ hdc = GetDC(0);
+
+ if (client_area) {
+ GetClientRect(window, &rc);
+ Width = rc.right;
+ Height = rc.bottom;
+ } else {
+ GetWindowRect(window, &rc);
+ Width = rc.right - rc.left;
+ Height = rc.bottom - rc.top;
+ }
+
+ Width = (Width/4)*4;
+
+ memDC = CreateCompatibleDC(hdc);
+ memBM = CreateCompatibleBitmap(hdc, Width, Height);
+ hOld = (HBITMAP) SelectObject (memDC, memBM);
+
+
+ handle = LoadLibrary("User32.dll");
+ if ( handle == 0 ) {
+ goto clean;
+ }
+ pPrintWindow = (tPrintWindow) GetProcAddress(handle, "PrintWindow");
+
+ if ( pPrintWindow ) {
+ pPrintWindow(window, memDC, (UINT) client_area);
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Windows API too old");
+ RETURN_FALSE;
+ goto clean;
+ }
+
+ FreeLibrary(handle);
+
+ im = gdImageCreateTrueColor(Width, Height);
+ if (im) {
+ int x,y;
+ for (y=0; y <= Height; y++) {
+ for (x=0; x <= Width; x++) {
+ int c = GetPixel(memDC, x,y);
+ gdImageSetPixel(im, x, y, gdTrueColor(GetRValue(c), GetGValue(c), GetBValue(c)));
+ }
+ }
+ }
+
+clean:
+ SelectObject(memDC,hOld);
+ DeleteObject(memBM);
+ DeleteDC(memDC);
+ ReleaseDC( 0, hdc );
+
+ if (!im) {
+ RETURN_FALSE;
+ } else {
+ ZEND_REGISTER_RESOURCE(return_value, im, le_gd);
+ }
+}
+/* }}} */
+
+/* {{{ proto resource imagegrabscreen()
+ Grab a screenshot */
+PHP_FUNCTION(imagegrabscreen)
+{
+ HWND window = GetDesktopWindow();
+ RECT rc = {0};
+ int Width, Height;
+ HDC hdc;
+ HDC memDC;
+ HBITMAP memBM;
+ HBITMAP hOld;
+ HINSTANCE handle;
+ long lwindow_handle;
+ typedef BOOL (WINAPI *tPrintWindow)(HWND, HDC,UINT);
+ tPrintWindow pPrintWindow = 0;
+ gdImagePtr im;
+ hdc = GetDC(0);
+
+ if (!hdc) {
+ RETURN_FALSE;
+ }
+
+ GetWindowRect(window, &rc);
+ Width = rc.right - rc.left;
+ Height = rc.bottom - rc.top;
+
+ Width = (Width/4)*4;
+
+ memDC = CreateCompatibleDC(hdc);
+ memBM = CreateCompatibleBitmap(hdc, Width, Height);
+ hOld = (HBITMAP) SelectObject (memDC, memBM);
+ BitBlt( memDC, 0, 0, Width, Height , hdc, rc.left, rc.top , SRCCOPY );
+
+ im = gdImageCreateTrueColor(Width, Height);
+ if (im) {
+ int x,y;
+ for (y=0; y <= Height; y++) {
+ for (x=0; x <= Width; x++) {
+ int c = GetPixel(memDC, x,y);
+ gdImageSetPixel(im, x, y, gdTrueColor(GetRValue(c), GetGValue(c), GetBValue(c)));
+ }
+ }
+ }
+
+ SelectObject(memDC,hOld);
+ DeleteObject(memBM);
+ DeleteDC(memDC);
+ ReleaseDC( 0, hdc );
+
+ if (!im) {
+ RETURN_FALSE;
+ } else {
+ ZEND_REGISTER_RESOURCE(return_value, im, le_gd);
+ }
+}
+/* }}} */
+#endif /* PHP_WIN32 */
+
#ifdef HAVE_GD_BUNDLED
/* {{{ proto resource imagerotate(resource src_im, float angle, int bgdcolor [, int ignoretransparent])
Rotate an image using a custom angle */
@@ -2249,6 +2432,11 @@ gdImagePtr _php_image_create_from_string(zval **data, char *tn, gdImagePtr (*ioc
im = (*ioctx_func_p)(io_ctx);
if (!im) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Passed data is not in '%s' format", tn);
+#if HAVE_LIBGD204
+ io_ctx->gd_free(io_ctx);
+#else
+ io_ctx->free(io_ctx);
+#endif
return NULL;
}
@@ -2370,6 +2558,10 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type,
if (argc == 5 && image_type == PHP_GDIMG_TYPE_GD2PART) {
multi_convert_to_long_ex(4, srcx, srcy, width, height);
+ if (Z_LVAL_PP(width) < 1 || Z_LVAL_PP(height) < 1) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,"Zero width or height not allowed");
+ RETURN_FALSE;
+ }
}
fn = Z_STRVAL_PP(file);
@@ -4267,7 +4459,7 @@ PHP_FUNCTION(imagepsextendfont)
T1_DeleteAllSizes(*f_ind);
if (Z_DVAL_PP(ext) <= 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Second parameter %f out of range (must be > 0)", Z_DVAL_PP(ext));
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Second parameter %F out of range (must be > 0)", Z_DVAL_PP(ext));
RETURN_FALSE;
}
@@ -4325,11 +4517,6 @@ PHP_FUNCTION(imagepstext)
T1_TMATRIX *transform = NULL;
char *str;
int str_len;
- int argc = ZEND_NUM_ARGS();
-
- if (argc != 8 && argc != 12) {
- ZEND_WRONG_PARAM_COUNT();
- }
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsrlllll|lldl", &img, &str, &str_len, &fnt, &size, &_fg, &_bg, &x, &y, &space, &width, &angle, &aa_steps) == FAILURE) {
return;
@@ -5057,8 +5244,10 @@ PHP_FUNCTION(imagefilter)
php_image_filter_smooth
};
- if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 5 || zend_parse_parameters(2 TSRMLS_CC, "rl", &tmp, &filtertype) == FAILURE) {
- ZEND_WRONG_PARAM_COUNT();
+ if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 5) {
+ WRONG_PARAM_COUNT;
+ } else if (zend_parse_parameters(2 TSRMLS_CC, "rl", &tmp, &filtertype) == FAILURE) {
+ return;
}
if (filtertype >= 0 && filtertype <= IMAGE_FILTER_MAX) {
diff --git a/ext/gd/gd_ctx.c b/ext/gd/gd_ctx.c
index 2ccfa3d01..773462f99 100644
--- a/ext/gd/gd_ctx.c
+++ b/ext/gd/gd_ctx.c
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2006 The PHP Group |
+ | Copyright (c) 1997-2007 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: gd_ctx.c,v 1.22.2.5.2.2 2006/10/08 17:36:10 pajoye Exp $ */
+/* $Id: gd_ctx.c,v 1.22.2.5.2.3 2007/01/01 09:36:01 sebastian Exp $ */
#include "php_gd.h"
diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c
index 3edec2edf..4901594b7 100644
--- a/ext/gd/libgd/gd.c
+++ b/ext/gd/libgd/gd.c
@@ -754,7 +754,7 @@ int gdImageGetTrueColorPixel (gdImagePtr im, int x, int y)
int p = gdImageGetPixel(im, x, y);
if (!im->trueColor) {
- return gdTrueColorAlpha(im->red[p], im->green[p], im->blue[p], (im->transparent == p) ? gdAlphaTransparent : gdAlphaOpaque);
+ return gdTrueColorAlpha(im->red[p], im->green[p], im->blue[p], (im->transparent == p) ? gdAlphaTransparent : im->alpha[p]);
} else {
return p;
}
@@ -847,7 +847,9 @@ static void gdImageTileApply (gdImagePtr im, int x, int y)
srcy = y % gdImageSY(im->tile);
if (im->trueColor) {
p = gdImageGetTrueColorPixel(im->tile, srcx, srcy);
- gdImageSetPixel(im, x, y, p);
+ if (p != gdImageGetTransparent (im->tile)) {
+ gdImageSetPixel(im, x, y, p);
+ }
} else {
p = gdImageGetPixel(im->tile, srcx, srcy);
/* Allow for transparency */
@@ -1019,6 +1021,7 @@ void gdImageAABlend (gdImagePtr im)
/* Bresenham as presented in Foley & Van Dam */
void gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
{
+ int t;
int dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag;
int wid;
int w, wstart;
@@ -1029,6 +1032,43 @@ void gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
return;
}
+ /* Vertical */
+ if (x1==x2) {
+ if (thick > 1) {
+ int thickhalf = thick >> 1;
+ thickhalf = thick >> 1;
+ gdImageFilledRectangle(im, x1 - thickhalf, y1, x1 + thick - thickhalf - 1, y2, color);
+ } else {
+ if (y2 < y1) {
+ t = y2;
+ y2 = y1;
+ y1 = t;
+ }
+
+ for (;y1 <= y2; y1++) {
+ gdImageSetPixel(im, x1,y1, color);
+ }
+ }
+ return;
+ } else if (y1==y2) { /* Horizontal */
+ if (thick > 1) {
+ int thickhalf = thick >> 1;
+ thickhalf = thick >> 1;
+ gdImageFilledRectangle(im, x1, y1 - thickhalf, x2, y2 + thick - thickhalf - 1, color);
+ } else {
+ if (x2 < x1) {
+ t = x2;
+ x2 = x1;
+ x1 = t;
+ }
+
+ for (;x1 <= x2; x1++) {
+ gdImageSetPixel(im, x1,y1, color);
+ }
+ }
+ return;
+ }
+
/* gdAntiAliased passed as color: set anti-aliased line (AAL) global vars. */
if (color == gdAntiAliased) {
im->AAL_x1 = x1;
@@ -1605,6 +1645,14 @@ void gdImageFilledArc (gdImagePtr im, int cx, int cy, int w, int h, int s, int e
int lx = 0, ly = 0;
int fx = 0, fy = 0;
+ if (s > 360) {
+ s = s % 360;
+ }
+
+ if (e > 360) {
+ e = e % 360;
+ }
+
while (s<0) {
s += 360;
}
@@ -1769,17 +1817,15 @@ void gdImageFillToBorder (gdImagePtr im, int x, int y, int border, int color)
int lastBorder;
/* Seek left */
int leftLimit = -1, rightLimit;
- int i, restoreAlphaBleding=0;
+ int i, restoreAlphaBlending = 0;
if (border < 0) {
/* Refuse to fill to a non-solid border */
return;
}
- if (im->alphaBlendingFlag) {
- restoreAlphaBleding = 1;
- im->alphaBlendingFlag = 0;
- }
+ restoreAlphaBlending = im->alphaBlendingFlag;
+ im->alphaBlendingFlag = 0;
if (x >= im->sx) {
x = im->sx - 1;
@@ -1796,9 +1842,7 @@ void gdImageFillToBorder (gdImagePtr im, int x, int y, int border, int color)
leftLimit = i;
}
if (leftLimit == -1) {
- if (restoreAlphaBleding) {
- im->alphaBlendingFlag = 1;
- }
+ im->alphaBlendingFlag = restoreAlphaBlending;
return;
}
/* Seek right */
@@ -1843,9 +1887,7 @@ void gdImageFillToBorder (gdImagePtr im, int x, int y, int border, int color)
}
}
}
- if (restoreAlphaBleding) {
- im->alphaBlendingFlag = 1;
- }
+ im->alphaBlendingFlag = restoreAlphaBlending;
}
/*
@@ -1882,7 +1924,7 @@ void gdImageFill(gdImagePtr im, int x, int y, int nc)
/* stack of filled segments */
/* struct seg stack[FILL_MAX],*sp = stack;; */
- struct seg *stack;
+ struct seg *stack = NULL;
struct seg *sp;
if (!im->trueColor && nc > (im->colorsTotal -1)) {
@@ -1905,6 +1947,29 @@ void gdImageFill(gdImagePtr im, int x, int y, int nc)
return;
}
+ /* Do not use the 4 neighbors implementation with
+ * small images
+ */
+ if (im->sx < 4) {
+ int ix = x, iy = y, c;
+ do {
+ c = gdImageGetPixel(im, ix, iy);
+ if (c != oc) {
+ goto done;
+ }
+ gdImageSetPixel(im, ix, iy, nc);
+ } while(ix++ < (im->sx -1));
+ ix = x; iy = y + 1;
+ do {
+ c = gdImageGetPixel(im, ix, iy);
+ if (c != oc) {
+ goto done;
+ }
+ gdImageSetPixel(im, ix, iy, nc);
+ } while(ix++ < (im->sx -1));
+ goto done;
+ }
+
stack = (struct seg *)safe_emalloc(sizeof(struct seg), ((int)(im->sy*im->sx)/4), 1);
sp = stack;
@@ -1942,7 +2007,10 @@ skip: for (x++; x<=x2 && (gdImageGetPixel(im, x, y)!=oc); x++);
l = x;
} while (x<=x2);
}
+
efree(stack);
+
+done:
im->alphaBlendingFlag = alphablending_bak;
}
@@ -1955,9 +2023,9 @@ void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc)
/* stack of filled segments */
struct seg *stack;
struct seg *sp;
+ char **pts;
- int **pts;
- if(!im->tile){
+ if (!im->tile) {
return;
}
@@ -1965,10 +2033,10 @@ void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc)
tiled = nc==gdTiled;
nc = gdImageTileGet(im,x,y);
- pts = (int **) ecalloc(sizeof(int *) * im->sy, sizeof(int));
+ pts = (char **) ecalloc(im->sy, sizeof(char*));
for (i=0; i<im->sy;i++) {
- pts[i] = (int *) ecalloc(im->sx, sizeof(int));
+ pts[i] = (char *) ecalloc(im->sx, sizeof(char));
}
stack = (struct seg *)safe_emalloc(sizeof(struct seg), ((int)(im->sy*im->sx)/4), 1);
@@ -1976,17 +2044,13 @@ void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc)
oc = gdImageGetPixel(im, x, y);
- /* required! */
+/* required! */
FILL_PUSH(y,x,x,1);
/* seed segment (popped 1st) */
FILL_PUSH(y+1, x, x, -1);
while (sp>stack) {
FILL_POP(y, x1, x2, dy);
for (x=x1; x>=0 && (!pts[y][x] && gdImageGetPixel(im,x,y)==oc); x--) {
- if (pts[y][x]){
- /* we should never be here */
- break;
- }
nc = gdImageTileGet(im,x,y);
pts[y][x]=1;
gdImageSetPixel(im,x, y, nc);
@@ -2002,11 +2066,7 @@ void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc)
}
x = x1+1;
do {
- for (; x<=wx2 && (!pts[y][x] && gdImageGetPixel(im,x, y)==oc) ; x++) {
- if (pts[y][x]){
- /* we should never be here */
- break;
- }
+ for (; x<wx2 && (!pts[y][x] && gdImageGetPixel(im,x, y)==oc) ; x++) {
nc = gdImageTileGet(im,x,y);
pts[y][x]=1;
gdImageSetPixel(im, x, y, nc);
@@ -2750,6 +2810,9 @@ gdImagePtr gdImageRotate90 (gdImagePtr src, int ignoretransparent)
dst->transparent = src->transparent;
if (dst != NULL) {
+ int old_blendmode = dst->alphaBlendingFlag;
+ dst->alphaBlendingFlag = 0;
+
gdImagePaletteCopy (dst, src);
for (uY = 0; uY<src->sy; uY++) {
@@ -2769,6 +2832,7 @@ gdImagePtr gdImageRotate90 (gdImagePtr src, int ignoretransparent)
}
}
}
+ dst->alphaBlendingFlag = old_blendmode;
}
return dst;
@@ -2792,6 +2856,9 @@ gdImagePtr gdImageRotate180 (gdImagePtr src, int ignoretransparent)
dst->transparent = src->transparent;
if (dst != NULL) {
+ int old_blendmode = dst->alphaBlendingFlag;
+ dst->alphaBlendingFlag = 0;
+
gdImagePaletteCopy (dst, src);
for (uY = 0; uY<src->sy; uY++) {
@@ -2812,6 +2879,7 @@ gdImagePtr gdImageRotate180 (gdImagePtr src, int ignoretransparent)
}
}
}
+ dst->alphaBlendingFlag = old_blendmode;
}
return dst;
@@ -2835,6 +2903,9 @@ gdImagePtr gdImageRotate270 (gdImagePtr src, int ignoretransparent)
dst->transparent = src->transparent;
if (dst != NULL) {
+ int old_blendmode = dst->alphaBlendingFlag;
+ dst->alphaBlendingFlag = 0;
+
gdImagePaletteCopy (dst, src);
for (uY = 0; uY<src->sy; uY++) {
@@ -2855,6 +2926,7 @@ gdImagePtr gdImageRotate270 (gdImagePtr src, int ignoretransparent)
}
}
}
+ dst->alphaBlendingFlag = old_blendmode;
}
return dst;
@@ -3348,7 +3420,7 @@ int gdImageCompare (gdImagePtr im1, gdImagePtr im2)
}
int
-gdAlphaBlend (int dst, int src)
+gdAlphaBlendOld (int dst, int src)
{
/* 2.0.12: TBB: alpha in the destination should be a
* component of the result. Thanks to Frank Warmerdam for
@@ -3370,6 +3442,51 @@ gdAlphaBlend (int dst, int src)
gdTrueColorGetBlue (dst)) / gdAlphaMax));
}
+int gdAlphaBlend (int dst, int src) {
+ int src_alpha = gdTrueColorGetAlpha(src);
+ int dst_alpha, alpha, red, green, blue;
+ int src_weight, dst_weight, tot_weight;
+
+/* -------------------------------------------------------------------- */
+/* Simple cases we want to handle fast. */
+/* -------------------------------------------------------------------- */
+ if( src_alpha == gdAlphaOpaque )
+ return src;
+
+ dst_alpha = gdTrueColorGetAlpha(dst);
+ if( src_alpha == gdAlphaTransparent )
+ return dst;
+ if( dst_alpha == gdAlphaTransparent )
+ return src;
+
+/* -------------------------------------------------------------------- */
+/* What will the source and destination alphas be? Note that */
+/* the destination weighting is substantially reduced as the */
+/* overlay becomes quite opaque. */
+/* -------------------------------------------------------------------- */
+ src_weight = gdAlphaTransparent - src_alpha;
+ dst_weight = (gdAlphaTransparent - dst_alpha) * src_alpha / gdAlphaMax;
+ tot_weight = src_weight + dst_weight;
+
+/* -------------------------------------------------------------------- */
+/* What red, green and blue result values will we use? */
+/* -------------------------------------------------------------------- */
+ alpha = src_alpha * dst_alpha / gdAlphaMax;
+
+ red = (gdTrueColorGetRed(src) * src_weight
+ + gdTrueColorGetRed(dst) * dst_weight) / tot_weight;
+ green = (gdTrueColorGetGreen(src) * src_weight
+ + gdTrueColorGetGreen(dst) * dst_weight) / tot_weight;
+ blue = (gdTrueColorGetBlue(src) * src_weight
+ + gdTrueColorGetBlue(dst) * dst_weight) / tot_weight;
+
+/* -------------------------------------------------------------------- */
+/* Return merged result. */
+/* -------------------------------------------------------------------- */
+ return ((alpha << 24) + (red << 16) + (green << 8) + blue);
+
+}
+
void gdImageAlphaBlending (gdImagePtr im, int alphaBlendingArg)
{
im->alphaBlendingFlag = alphaBlendingArg;
diff --git a/ext/gd/libgd/gd.h b/ext/gd/libgd/gd.h
index 751a1e74e..98362f0e1 100644
--- a/ext/gd/libgd/gd.h
+++ b/ext/gd/libgd/gd.h
@@ -11,14 +11,18 @@ extern "C" {
#include "php_compat.h"
-#ifndef WIN32
-/* default fontpath for unix systems */
-#define DEFAULT_FONTPATH "/usr/X11R6/lib/X11/fonts/TrueType:/usr/X11R6/lib/X11/fonts/truetype:/usr/X11R6/lib/X11/fonts/TTF:/usr/share/fonts/TrueType:/usr/share/fonts/truetype:/usr/openwin/lib/X11/fonts/TrueType:/usr/X11R6/lib/X11/fonts/Type1:."
-#define PATHSEPARATOR ":"
-#else
+#ifdef NETWARE
+/* default fontpath for netware systems */
+#define DEFAULT_FONTPATH "sys:/java/nwgfx/lib/x11/fonts/ttf;."
+#define PATHSEPARATOR ";"
+#elif defined(WIN32)
/* default fontpath for windows systems */
#define DEFAULT_FONTPATH "c:\\winnt\\fonts;c:\\windows\\fonts;."
#define PATHSEPARATOR ";"
+#else
+/* default fontpath for unix systems */
+#define DEFAULT_FONTPATH "/usr/X11R6/lib/X11/fonts/TrueType:/usr/X11R6/lib/X11/fonts/truetype:/usr/X11R6/lib/X11/fonts/TTF:/usr/share/fonts/TrueType:/usr/share/fonts/truetype:/usr/openwin/lib/X11/fonts/TrueType:/usr/X11R6/lib/X11/fonts/Type1:."
+#define PATHSEPARATOR ":"
#endif
/* gd.h: declarations file for the graphic-draw module.
@@ -301,6 +305,14 @@ void gdImageStringUp(gdImagePtr im, gdFontPtr f, int x, int y, unsigned char *s,
void gdImageString16(gdImagePtr im, gdFontPtr f, int x, int y, unsigned short *s, int color);
void gdImageStringUp16(gdImagePtr im, gdFontPtr f, int x, int y, unsigned short *s, int color);
+/*
+ * The following functions are required to be called prior to the
+ * use of any sort of threads in a module load / shutdown function
+ * respectively.
+ */
+void gdFontCacheMutexSetup();
+void gdFontCacheMutexShutdown();
+
/* 2.0.16: for thread-safe use of gdImageStringFT and friends,
* call this before allowing any thread to call gdImageStringFT.
* Otherwise it is invoked by the first thread to invoke
diff --git a/ext/gd/libgd/gd_gif_in.c b/ext/gd/libgd/gd_gif_in.c
index e3d635b31..8ee77b02e 100644
--- a/ext/gd/libgd/gd_gif_in.c
+++ b/ext/gd/libgd/gd_gif_in.c
@@ -61,22 +61,40 @@ static struct {
} GifScreen;
#endif
+#if 0
static struct {
int transparent;
int delayTime;
int inputFlag;
int disposal;
} Gif89 = { -1, -1, -1, 0 };
+#endif
-static int ReadColorMap (gdIOCtx *fd, int number, unsigned char (*buffer)[256]);
-static int DoExtension (gdIOCtx *fd, int label, int *Transparent);
-static int GetDataBlock (gdIOCtx *fd, unsigned char *buf);
-static int GetCode (gdIOCtx *fd, int code_size, int flag);
-static int LWZReadByte (gdIOCtx *fd, int flag, int input_code_size);
+#define STACK_SIZE ((1<<(MAX_LWZ_BITS))*2)
-static void ReadImage (gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace); /*1.4//, int ignore); */
+typedef struct {
+ unsigned char buf[280];
+ int curbit, lastbit, done, last_byte;
+} CODE_STATIC_DATA;
+
+typedef struct {
+ int fresh;
+ int code_size, set_code_size;
+ int max_code, max_code_size;
+ int firstcode, oldcode;
+ int clear_code, end_code;
+ int table[2][(1<< MAX_LWZ_BITS)];
+ int stack[STACK_SIZE], *sp;
+ CODE_STATIC_DATA scd;
+} LZW_STATIC_DATA;
-int ZeroDataBlock;
+static int ReadColorMap (gdIOCtx *fd, int number, unsigned char (*buffer)[256]);
+static int DoExtension (gdIOCtx *fd, int label, int *Transparent, int *ZeroDataBlockP);
+static int GetDataBlock (gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP);
+static int GetCode (gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP);
+static int LWZReadByte (gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP);
+
+static void ReadImage (gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace, int *ZeroDataBlockP); /*1.4//, int ignore); */
gdImagePtr gdImageCreateFromGifSource(gdSourcePtr inSource) /* {{{ */
{
@@ -106,25 +124,26 @@ gdImagePtr gdImageCreateFromGif(FILE *fdFile) /* {{{ */
gdImagePtr gdImageCreateFromGifCtx(gdIOCtxPtr fd) /* {{{ */
{
- /* 1.4 int imageNumber; */
int BitPixel;
+#if 0
int ColorResolution;
int Background;
int AspectRatio;
+#endif
int Transparent = (-1);
unsigned char buf[16];
unsigned char c;
unsigned char ColorMap[3][MAXCOLORMAPSIZE];
unsigned char localColorMap[3][MAXCOLORMAPSIZE];
- int imw, imh;
- int useGlobalColormap;
+ int imw, imh, screen_width, screen_height;
+ int gif87a, useGlobalColormap;
int bitPixel;
int i;
/*1.4//int imageCount = 0; */
- char version[4];
+ int ZeroDataBlock = FALSE;
+ int haveGlobalColormap;
gdImagePtr im = 0;
- ZeroDataBlock = FALSE;
/*1.4//imageNumber = 1; */
if (! ReadOK(fd,buf,6)) {
@@ -133,29 +152,39 @@ gdImagePtr gdImageCreateFromGifCtx(gdIOCtxPtr fd) /* {{{ */
if (strncmp((char *)buf,"GIF",3) != 0) {
return 0;
}
- strncpy(version, (char *)buf + 3, 3);
- version[3] = '\0';
- if ((strcmp(version, "87a") != 0) && (strcmp(version, "89a") != 0)) {
+ if (memcmp((char *)buf+3, "87a", 3) == 0) {
+ gif87a = 1;
+ } else if (memcmp((char *)buf+3, "89a", 3) == 0) {
+ gif87a = 0;
+ } else {
return 0;
}
+
if (! ReadOK(fd,buf,7)) {
return 0;
}
+
BitPixel = 2<<(buf[4]&0x07);
+#if 0
ColorResolution = (int) (((buf[4]&0x70)>>3)+1);
Background = buf[5];
AspectRatio = buf[6];
+#endif
+ screen_width = imw = LM_to_uint(buf[0],buf[1]);
+ screen_height = imh = LM_to_uint(buf[2],buf[3]);
- imw = LM_to_uint(buf[0],buf[1]);
- imh = LM_to_uint(buf[2],buf[3]);
-
- if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */
+ haveGlobalColormap = BitSet(buf[4], LOCALCOLORMAP); /* Global Colormap */
+ if (haveGlobalColormap) {
if (ReadColorMap(fd, BitPixel, ColorMap)) {
return 0;
}
}
+
for (;;) {
+ int top, left;
+ int width, height;
+
if (! ReadOK(fd,&c,1)) {
return 0;
}
@@ -167,7 +196,7 @@ gdImagePtr gdImageCreateFromGifCtx(gdIOCtxPtr fd) /* {{{ */
if (! ReadOK(fd,&c,1)) {
return 0;
}
- DoExtension(fd, c, &Transparent);
+ DoExtension(fd, c, &Transparent, &ZeroDataBlock);
continue;
}
@@ -184,29 +213,38 @@ gdImagePtr gdImageCreateFromGifCtx(gdIOCtxPtr fd) /* {{{ */
useGlobalColormap = ! BitSet(buf[8], LOCALCOLORMAP);
bitPixel = 1<<((buf[8]&0x07)+1);
-
- if (!useGlobalColormap) {
- if (ReadColorMap(fd, bitPixel, localColorMap)) {
- return 0;
+ left = LM_to_uint(buf[0], buf[1]);
+ top = LM_to_uint(buf[2], buf[3]);
+ width = LM_to_uint(buf[4], buf[5]);
+ height = LM_to_uint(buf[6], buf[7]);
+
+ if (left + width > screen_width || top + height > screen_height) {
+ if (VERBOSE) {
+ printf("Frame is not confined to screen dimension.\n");
}
+ return 0;
}
- if (!(im = gdImageCreate(imw, imh))) {
+ if (!(im = gdImageCreate(width, height))) {
return 0;
}
-
im->interlace = BitSet(buf[8], INTERLACE);
- if (! useGlobalColormap) {
- ReadImage(im, fd, imw, imh, localColorMap,
- BitSet(buf[8], INTERLACE));
- /*1.4//imageCount != imageNumber); */
+ if (!useGlobalColormap) {
+ if (ReadColorMap(fd, bitPixel, localColorMap)) {
+ gdImageDestroy(im);
+ return 0;
+ }
+ ReadImage(im, fd, width, height, localColorMap,
+ BitSet(buf[8], INTERLACE), &ZeroDataBlock);
} else {
- ReadImage(im, fd, imw, imh,
- ColorMap,
- BitSet(buf[8], INTERLACE));
- /*1.4//imageCount != imageNumber); */
+ if (!haveGlobalColormap) {
+ gdImageDestroy(im);
+ return 0;
+ }
+ ReadImage(im, fd, width, height,
+ ColorMap,
+ BitSet(buf[8], INTERLACE), &ZeroDataBlock);
}
-
if (Transparent != (-1)) {
gdImageColorTransparent(im, Transparent);
}
@@ -218,12 +256,10 @@ terminated:
if (!im) {
return 0;
}
-
if (!im->colorsTotal) {
gdImageDestroy(im);
return 0;
}
-
/* Check for open colors at the end, so
we can reduce colorsTotal and ultimately
BitsPerPixel */
@@ -258,33 +294,37 @@ static int ReadColorMap(gdIOCtx *fd, int number, unsigned char (*buffer)[256]) /
}
/* }}} */
-static int DoExtension(gdIOCtx *fd, int label, int *Transparent) /* {{{ */
+static int
+DoExtension(gdIOCtx *fd, int label, int *Transparent, int *ZeroDataBlockP)
{
- static unsigned char buf[256];
+ unsigned char buf[256];
switch (label) {
case 0xf9: /* Graphic Control Extension */
- (void) GetDataBlock(fd, (unsigned char*) buf);
+ memset(buf, 0, 4); /* initialize a few bytes in the case the next function fails */
+ (void) GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP);
+#if 0
Gif89.disposal = (buf[0] >> 2) & 0x7;
Gif89.inputFlag = (buf[0] >> 1) & 0x1;
Gif89.delayTime = LM_to_uint(buf[1],buf[2]);
+#endif
if ((buf[0] & 0x1) != 0)
*Transparent = buf[3];
- while (GetDataBlock(fd, (unsigned char*) buf) > 0)
- ;
+ while (GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP) > 0);
return FALSE;
default:
break;
}
- while (GetDataBlock(fd, (unsigned char*) buf) > 0)
+ while (GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP) > 0)
;
return FALSE;
}
/* }}} */
-static int GetDataBlock_(gdIOCtx *fd, unsigned char *buf) /* {{{ */
+static int
+GetDataBlock_(gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP)
{
unsigned char count;
@@ -292,7 +332,7 @@ static int GetDataBlock_(gdIOCtx *fd, unsigned char *buf) /* {{{ */
return -1;
}
- ZeroDataBlock = count == 0;
+ *ZeroDataBlockP = count == 0;
if ((count != 0) && (! ReadOK(fd, buf, count))) {
return -1;
@@ -302,14 +342,15 @@ static int GetDataBlock_(gdIOCtx *fd, unsigned char *buf) /* {{{ */
}
/* }}} */
-static int GetDataBlock(gdIOCtx *fd, unsigned char *buf) /* {{{ */
+static int
+GetDataBlock(gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP)
{
int rv;
int i;
- char *tmp = NULL;
- rv = GetDataBlock_(fd,buf);
+ rv = GetDataBlock_(fd,buf, ZeroDataBlockP);
if (VERBOSE) {
+ char *tmp = NULL;
if (rv > 0) {
tmp = safe_emalloc(3 * rv, sizeof(char), 1);
for (i=0;i<rv;i++) {
@@ -325,126 +366,119 @@ static int GetDataBlock(gdIOCtx *fd, unsigned char *buf) /* {{{ */
}
/* }}} */
-static int GetCode_(gdIOCtx *fd, int code_size, int flag) /* {{{ */
+static int
+GetCode_(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP)
{
- static unsigned char buf[280];
- static int curbit, lastbit, done, last_byte;
- int i, j, ret;
- unsigned char count;
+ int i, j, ret;
+ unsigned char count;
if (flag) {
- curbit = 0;
- lastbit = 0;
- done = FALSE;
+ scd->curbit = 0;
+ scd->lastbit = 0;
+ scd->last_byte = 0;
+ scd->done = FALSE;
return 0;
}
- if ( (curbit+code_size) >= lastbit) {
- if (done) {
- if (curbit >= lastbit) {
+ if ( (scd->curbit + code_size) >= scd->lastbit) {
+ if (scd->done) {
+ if (scd->curbit >= scd->lastbit) {
/* Oh well */
}
return -1;
}
- buf[0] = buf[last_byte-2];
- buf[1] = buf[last_byte-1];
+ scd->buf[0] = scd->buf[scd->last_byte-2];
+ scd->buf[1] = scd->buf[scd->last_byte-1];
- if ((count = GetDataBlock(fd, &buf[2])) <= 0)
- done = TRUE;
+ if ((count = GetDataBlock(fd, &scd->buf[2], ZeroDataBlockP)) <= 0)
+ scd->done = TRUE;
- last_byte = 2 + count;
- curbit = (curbit - lastbit) + 16;
- lastbit = (2+count)*8 ;
+ scd->last_byte = 2 + count;
+ scd->curbit = (scd->curbit - scd->lastbit) + 16;
+ scd->lastbit = (2+count)*8 ;
}
ret = 0;
- for (i = curbit, j = 0; j < code_size; ++i, ++j)
- ret |= ((buf[ i / 8 ] & (1 << (i % 8))) != 0) << j;
+ for (i = scd->curbit, j = 0; j < code_size; ++i, ++j)
+ ret |= ((scd->buf[ i / 8 ] & (1 << (i % 8))) != 0) << j;
- curbit += code_size;
+ scd->curbit += code_size;
return ret;
}
-static int GetCode(gdIOCtx *fd, int code_size, int flag) /* {{{ */
+static int
+GetCode(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP)
{
int rv;
- rv = GetCode_(fd,code_size,flag);
- if (VERBOSE) php_gd_error_ex(E_NOTICE, "[GetCode(,%d,%d) returning %d]",code_size,flag,rv);
+ rv = GetCode_(fd, scd, code_size,flag, ZeroDataBlockP);
+ if (VERBOSE) printf("[GetCode(,%d,%d) returning %d]\n",code_size,flag,rv);
return(rv);
}
/* }}} */
-#define STACK_SIZE ((1<<(MAX_LWZ_BITS))*2)
-static int LWZReadByte_(gdIOCtx *fd, int flag, int input_code_size) /* {{{ */
+static int
+LWZReadByte_(gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP)
{
- static int fresh = FALSE;
- int code, incode;
- static int code_size, set_code_size;
- static int max_code, max_code_size;
- static int firstcode, oldcode;
- static int clear_code, end_code;
- static int table[2][(1<< MAX_LWZ_BITS)];
- static int stack[STACK_SIZE], *sp;
- register int i;
+ int code, incode, i;
if (flag) {
- set_code_size = input_code_size;
- code_size = set_code_size+1;
- clear_code = 1 << set_code_size ;
- end_code = clear_code + 1;
- max_code_size = 2*clear_code;
- max_code = clear_code+2;
+ sd->set_code_size = input_code_size;
+ sd->code_size = sd->set_code_size+1;
+ sd->clear_code = 1 << sd->set_code_size ;
+ sd->end_code = sd->clear_code + 1;
+ sd->max_code_size = 2*sd->clear_code;
+ sd->max_code = sd->clear_code+2;
- GetCode(fd, 0, TRUE);
+ GetCode(fd, &sd->scd, 0, TRUE, ZeroDataBlockP);
- fresh = TRUE;
+ sd->fresh = TRUE;
- for (i = 0; i < clear_code; ++i) {
- table[0][i] = 0;
- table[1][i] = i;
+ for (i = 0; i < sd->clear_code; ++i) {
+ sd->table[0][i] = 0;
+ sd->table[1][i] = i;
}
for (; i < (1<<MAX_LWZ_BITS); ++i)
- table[0][i] = table[1][0] = 0;
+ sd->table[0][i] = sd->table[1][0] = 0;
- sp = stack;
+ sd->sp = sd->stack;
return 0;
- } else if (fresh) {
- fresh = FALSE;
+ } else if (sd->fresh) {
+ sd->fresh = FALSE;
do {
- firstcode = oldcode =
- GetCode(fd, code_size, FALSE);
- } while (firstcode == clear_code);
- return firstcode;
+ sd->firstcode = sd->oldcode =
+ GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP);
+ } while (sd->firstcode == sd->clear_code);
+ return sd->firstcode;
}
- if (sp > stack)
- return *--sp;
+ if (sd->sp > sd->stack)
+ return *--sd->sp;
- while ((code = GetCode(fd, code_size, FALSE)) >= 0) {
- if (code == clear_code) {
- for (i = 0; i < clear_code; ++i) {
- table[0][i] = 0;
- table[1][i] = i;
+ while ((code = GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP)) >= 0) {
+ if (code == sd->clear_code) {
+ for (i = 0; i < sd->clear_code; ++i) {
+ sd->table[0][i] = 0;
+ sd->table[1][i] = i;
}
for (; i < (1<<MAX_LWZ_BITS); ++i)
- table[0][i] = table[1][i] = 0;
- code_size = set_code_size+1;
- max_code_size = 2*clear_code;
- max_code = clear_code+2;
- sp = stack;
- firstcode = oldcode =
- GetCode(fd, code_size, FALSE);
- return firstcode;
- } else if (code == end_code) {
+ sd->table[0][i] = sd->table[1][i] = 0;
+ sd->code_size = sd->set_code_size+1;
+ sd->max_code_size = 2*sd->clear_code;
+ sd->max_code = sd->clear_code+2;
+ sd->sp = sd->stack;
+ sd->firstcode = sd->oldcode =
+ GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP);
+ return sd->firstcode;
+ } else if (code == sd->end_code) {
int count;
unsigned char buf[260];
- if (ZeroDataBlock)
+ if (*ZeroDataBlockP)
return -2;
- while ((count = GetDataBlock(fd, buf)) > 0)
+ while ((count = GetDataBlock(fd, buf, ZeroDataBlockP)) > 0)
;
if (count != 0)
@@ -453,66 +487,69 @@ static int LWZReadByte_(gdIOCtx *fd, int flag, int input_code_size) /* {{{ */
incode = code;
- if (sp == (stack + STACK_SIZE)) {
+ if (sd->sp == (sd->stack + STACK_SIZE)) {
/* Bad compressed data stream */
return -1;
}
- if (code >= max_code) {
- *sp++ = firstcode;
- code = oldcode;
+ if (code >= sd->max_code) {
+ *sd->sp++ = sd->firstcode;
+ code = sd->oldcode;
}
- while (code >= clear_code) {
- if (sp == (stack + STACK_SIZE)) {
+ while (code >= sd->clear_code) {
+ if (sd->sp == (sd->stack + STACK_SIZE)) {
/* Bad compressed data stream */
return -1;
}
- *sp++ = table[1][code];
- if (code == table[0][code]) {
+ *sd->sp++ = sd->table[1][code];
+ if (code == sd->table[0][code]) {
/* Oh well */
}
- code = table[0][code];
+ code = sd->table[0][code];
}
- *sp++ = firstcode = table[1][code];
+ *sd->sp++ = sd->firstcode = sd->table[1][code];
- if ((code = max_code) <(1<<MAX_LWZ_BITS)) {
- table[0][code] = oldcode;
- table[1][code] = firstcode;
- ++max_code;
- if ((max_code >= max_code_size) &&
- (max_code_size < (1<<MAX_LWZ_BITS))) {
- max_code_size *= 2;
- ++code_size;
+ if ((code = sd->max_code) <(1<<MAX_LWZ_BITS)) {
+ sd->table[0][code] = sd->oldcode;
+ sd->table[1][code] = sd->firstcode;
+ ++sd->max_code;
+ if ((sd->max_code >= sd->max_code_size) &&
+ (sd->max_code_size < (1<<MAX_LWZ_BITS))) {
+ sd->max_code_size *= 2;
+ ++sd->code_size;
}
}
- oldcode = incode;
+ sd->oldcode = incode;
- if (sp > stack)
- return *--sp;
+ if (sd->sp > sd->stack)
+ return *--sd->sp;
}
return code;
}
/* }}} */
-static int LWZReadByte(gdIOCtx *fd, int flag, int input_code_size) /* {{{ */
+static int
+LWZReadByte(gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP)
{
int rv;
- rv = LWZReadByte_(fd,flag,input_code_size);
- if (VERBOSE) php_gd_error_ex(E_NOTICE, "[LWZReadByte(,%d,%d) returning %d]",flag,input_code_size,rv);
+ rv = LWZReadByte_(fd, sd, flag, input_code_size, ZeroDataBlockP);
+ if (VERBOSE) printf("[LWZReadByte(,%d,%d) returning %d]\n",flag,input_code_size,rv);
return(rv);
}
/* }}} */
-static void ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace) /* {{{ */ /*1.4//, int ignore) */
+static void
+ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace, int *ZeroDataBlockP) /*1.4//, int ignore) */
{
unsigned char c;
int v;
int xpos = 0, ypos = 0, pass = 0;
int i;
+ LZW_STATIC_DATA sd;
/*
@@ -535,7 +572,7 @@ static void ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned
}
/* Many (perhaps most) of these colors will remain marked open. */
im->colorsTotal = gdMaxColors;
- if (LWZReadByte(fd, TRUE, c) < 0) {
+ if (LWZReadByte(fd, &sd, TRUE, c, ZeroDataBlockP) < 0) {
return;
}
@@ -544,12 +581,12 @@ static void ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned
** REMOVED For 1.4
*/
/*if (ignore) { */
- /* while (LWZReadByte(fd, FALSE, c) >= 0) */
+ /* while (LWZReadByte(fd, &sd, FALSE, c) >= 0) */
/* ; */
/* return; */
/*} */
- while ((v = LWZReadByte(fd,FALSE,c)) >= 0 ) {
+ while ((v = LWZReadByte(fd, &sd, FALSE, c, ZeroDataBlockP)) >= 0 ) {
/* This how we recognize which colors are actually used. */
if (im->open[v]) {
im->open[v] = 0;
@@ -591,7 +628,7 @@ static void ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned
}
fini:
- if (LWZReadByte(fd,FALSE,c)>=0) {
+ if (LWZReadByte(fd, &sd, FALSE, c, ZeroDataBlockP) >=0) {
/* Ignore extra */
}
}
diff --git a/ext/gd/libgd/gd_png.c b/ext/gd/libgd/gd_png.c
index b99c33c8c..0f6436f12 100644
--- a/ext/gd/libgd/gd_png.c
+++ b/ext/gd/libgd/gd_png.c
@@ -58,7 +58,7 @@ static void gdPngErrorHandler (png_structp png_ptr, png_const_charp msg)
* been defined.
*/
- php_gd_error_ex(E_ERROR, "gd-png: fatal libpng error: %s", msg);
+ php_gd_error_ex(E_WARNING, "gd-png: fatal libpng error: %s", msg);
jmpbuf_ptr = png_get_error_ptr (png_ptr);
if (jmpbuf_ptr == NULL) { /* we are completely hosed now */
@@ -126,7 +126,7 @@ gdImagePtr gdImageCreateFromPngCtx (gdIOCtx * infile)
/* Make sure the signature can't match by dumb luck -- TBB */
/* GRR: isn't sizeof(infile) equal to the size of the pointer? */
- memset (infile, 0, sizeof(infile));
+ memset (sig, 0, sizeof(sig));
/* first do a quick check that the file really is a PNG image; could
* have used slightly more general png_sig_cmp() function instead
@@ -200,6 +200,23 @@ gdImagePtr gdImageCreateFromPngCtx (gdIOCtx * infile)
png_set_packing (png_ptr); /* expand to 1 byte per pixel */
}
+ /* setjmp() must be called in every non-callback function that calls a
+ * PNG-reading libpng function
+ */
+#ifndef PNG_SETJMP_NOT_SUPPORTED
+ if (setjmp(gdPngJmpbufStruct.jmpbuf)) {
+ php_gd_error("gd-png error: setjmp returns error condition");
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+ gdFree(image_data);
+ gdFree(row_pointers);
+ if (im) {
+ gdImageDestroy(im);
+ }
+ return NULL;
+ }
+#endif
+
+
switch (color_type) {
case PNG_COLOR_TYPE_PALETTE:
png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
@@ -490,7 +507,7 @@ void gdImagePngCtxEx (gdImagePtr im, gdIOCtx * outfile, int level, int basefilte
if (basefilter >= 0) {
png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, basefilter);
}
-
+
/* can set this to a smaller value without compromising compression if all
* image data is 16K or less; will save some decoder memory [min == 8]
*/
diff --git a/ext/gd/libgd/gd_security.c b/ext/gd/libgd/gd_security.c
new file mode 100644
index 000000000..a5fea34c1
--- /dev/null
+++ b/ext/gd/libgd/gd_security.c
@@ -0,0 +1,33 @@
+/*
+ * gd_security.c
+ *
+ * Implements buffer overflow check routines.
+ *
+ * Written 2004, Phil Knirsch.
+ * Based on netpbm fixes by Alan Cox.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include "gd.h"
+
+int overflow2(int a, int b)
+{
+ if(a < 0 || b < 0) {
+ php_gd_error("gd warning: one parameter to a memory allocation multiplication is negative, failing operation gracefully\n");
+ return 1;
+ }
+ if(b == 0)
+ return 0;
+ if(a > INT_MAX / b) {
+ php_gd_error("gd warning: product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully\n");
+ return 1;
+ }
+ return 0;
+}
diff --git a/ext/gd/libgd/gd_topal.c b/ext/gd/libgd/gd_topal.c
index 2d7db8c73..d2cd13f5b 100644
--- a/ext/gd/libgd/gd_topal.c
+++ b/ext/gd/libgd/gd_topal.c
@@ -772,6 +772,7 @@ LOCAL (void)
nim->green[icolor] = 255;
nim->blue[icolor] = 255;
}
+ nim->open[icolor] = 0;
#endif
}
diff --git a/ext/gd/libgd/gdft.c b/ext/gd/libgd/gdft.c
index 30ac2768c..49a540c42 100644
--- a/ext/gd/libgd/gdft.c
+++ b/ext/gd/libgd/gdft.c
@@ -192,6 +192,16 @@ typedef struct
#include "jisx0208.h"
#endif
+extern int any2eucjp (char *, char *, unsigned int);
+
+/* Persistent font cache until explicitly cleared */
+/* Fonts can be used across multiple images */
+
+/* 2.0.16: thread safety (the font cache is shared) */
+gdMutexDeclare(gdFontCacheMutex);
+static gdCache_head_t *fontCache = NULL;
+static FT_Library library;
+
#define Tcl_UniChar int
#define TCL_UTF_MAX 3
static int gdTcl_UtfToUniChar (char *str, Tcl_UniChar * chPtr)
@@ -367,7 +377,11 @@ static void *fontFetch (char **error, void *key)
path = gdEstrdup (fontsearchpath);
/* if name is an absolute filename then test directly */
+#ifdef NETWARE
+ if (*name == '/' || (name[0] != 0 && strstr(name, ":/"))) {
+#else
if (*name == '/' || (name[0] != 0 && name[1] == ':' && (name[2] == '/' || name[2] == '\\'))) {
+#endif
snprintf(fullname, sizeof(fullname) - 1, "%s", name);
if (access(fullname, R_OK) == 0) {
font_found++;
@@ -703,24 +717,17 @@ gdroundupdown (FT_F26Dot6 v1, int updown)
return (!updown) ? (v1 < 0 ? ((v1 - 63) >> 6) : v1 >> 6) : (v1 > 0 ? ((v1 + 63) >> 6) : v1 >> 6);
}
-extern int any2eucjp (char *, char *, unsigned int);
-
-/* Persistent font cache until explicitly cleared */
-/* Fonts can be used across multiple images */
-
-/* 2.0.16: thread safety (the font cache is shared) */
-gdMutexDeclare(gdFontCacheMutex);
-static gdCache_head_t *fontCache = NULL;
-static FT_Library library;
-
void gdFontCacheShutdown()
{
+ gdMutexLock(gdFontCacheMutex);
+
if (fontCache) {
- gdMutexShutdown(gdFontCacheMutex);
gdCacheDelete(fontCache);
fontCache = NULL;
FT_Done_FreeType(library);
}
+
+ gdMutexUnlock(gdFontCacheMutex);
}
void gdFreeFontCache()
@@ -728,15 +735,23 @@ void gdFreeFontCache()
gdFontCacheShutdown();
}
+void gdFontCacheMutexSetup()
+{
+ gdMutexSetup(gdFontCacheMutex);
+}
+
+void gdFontCacheMutexShutdown()
+{
+ gdMutexShutdown(gdFontCacheMutex);
+}
+
int gdFontCacheSetup(void)
{
if (fontCache) {
/* Already set up */
return 0;
}
- gdMutexSetup(gdFontCacheMutex);
if (FT_Init_FreeType(&library)) {
- gdMutexShutdown(gdFontCacheMutex);
return -1;
}
fontCache = gdCacheCreate (FONTCACHESIZE, fontTest, fontFetch, fontRelease);
@@ -799,15 +814,16 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, double ptsi
/***** initialize font library and font cache on first call ******/
+ gdMutexLock(gdFontCacheMutex);
if (!fontCache) {
if (gdFontCacheSetup() != 0) {
gdCacheDelete(tc_cache);
+ gdMutexUnlock(gdFontCacheMutex);
return "Failure to initialize font library";
}
}
/*****/
- gdMutexLock(gdFontCacheMutex);
/* get the font (via font cache) */
fontkey.fontlist = fontlist;
fontkey.library = &library;
@@ -983,7 +999,7 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, double ptsi
} else {
ch = c & 0xFF; /* don't extend sign */
}
- next++;
+ if (*next) next++;
}
break;
case gdFTEX_Big5: {
diff --git a/ext/gd/libgd/gdhelpers.h b/ext/gd/libgd/gdhelpers.h
index 5e7d9bee7..6c469726e 100644
--- a/ext/gd/libgd/gdhelpers.h
+++ b/ext/gd/libgd/gdhelpers.h
@@ -21,6 +21,13 @@ extern char *gd_strtok_r(char *s, char *sep, char **state);
#define gdPFree(ptr) pefree(ptr, 1)
#define gdPEstrdup(ptr) pestrdup(ptr, 1)
+/* Returns nonzero if multiplying the two quantities will
+ result in integer overflow. Also returns nonzero if
+ either quantity is negative. By Phil Knirsch based on
+ netpbm fixes by Alan Cox. */
+
+int overflow2(int a, int b);
+
#ifdef ZTS
#define gdMutexDeclare(x) MUTEX_T x
#define gdMutexSetup(x) x = tsrm_mutex_alloc()
diff --git a/ext/gd/libgd/gdtest.c b/ext/gd/libgd/gdtest.c
index f4300bb3f..24b750386 100644
--- a/ext/gd/libgd/gdtest.c
+++ b/ext/gd/libgd/gdtest.c
@@ -56,7 +56,7 @@ main (int argc, char **argv)
/* */
/* Send to PNG File then Ptr */
/* */
- sprintf (of, "%s.png", argv[1]);
+ snprintf (of, sizeof(of), "%s.png", argv[1]);
out = fopen (of, "wb");
gdImagePng (im, out);
fclose (out);
@@ -88,7 +88,7 @@ main (int argc, char **argv)
/* */
/* Send to GD2 File then Ptr */
/* */
- sprintf (of, "%s.gd2", argv[1]);
+ snprintf (of, sizeof(of), "%s.gd2", argv[1]);
out = fopen (of, "wb");
gdImageGd2 (im, out, 128, 2);
fclose (out);
@@ -123,7 +123,7 @@ main (int argc, char **argv)
/* */
/* Send to GD File then Ptr */
/* */
- sprintf (of, "%s.gd", argv[1]);
+ snprintf (of, sizeof(of), "%s.gd", argv[1]);
out = fopen (of, "wb");
gdImageGd (im, out);
fclose (out);
@@ -180,7 +180,7 @@ main (int argc, char **argv)
** Test gdImagePngToSink'
* */
- sprintf (of, "%s.snk", argv[1]);
+ snprintf (of, sizeof(of), "%s.snk", argv[1]);
out = fopen (of, "wb");
imgsnk.sink = fwriteWrapper;
imgsnk.context = out;
diff --git a/ext/gd/libgd/wbmp.c b/ext/gd/libgd/wbmp.c
index d63c684ac..605d0b573 100644
--- a/ext/gd/libgd/wbmp.c
+++ b/ext/gd/libgd/wbmp.c
@@ -116,6 +116,15 @@ createwbmp (int width, int height, int color)
if ((wbmp = (Wbmp *) gdMalloc (sizeof (Wbmp))) == NULL)
return (NULL);
+ if (overflow2(sizeof (int), width)) {
+ gdFree(wbmp);
+ return NULL;
+ }
+ if (overflow2(sizeof (int) * width, height)) {
+ gdFree(wbmp);
+ return NULL;
+ }
+
if ((wbmp->bitmap = (int *) safe_emalloc(sizeof(int), width * height, 0)) == NULL)
{
gdFree (wbmp);
@@ -176,7 +185,14 @@ readwbmp (int (*getin) (void *in), void *in, Wbmp ** return_wbmp)
printf ("W: %d, H: %d\n", wbmp->width, wbmp->height);
#endif
- if ((wbmp->bitmap = (int *) safe_emalloc(wbmp->width * wbmp->height, sizeof(int), 0)) == NULL)
+ if (overflow2(sizeof (int), wbmp->width) ||
+ overflow2(sizeof (int) * wbmp->width, wbmp->height))
+ {
+ gdFree(wbmp);
+ return (-1);
+ }
+
+ if ((wbmp->bitmap = (int *) safe_emalloc((size_t)wbmp->width * wbmp->height, sizeof(int), 0)) == NULL)
{
gdFree (wbmp);
return (-1);
diff --git a/ext/gd/libgd/webpng.c b/ext/gd/libgd/webpng.c
index 81a00e749..c01dd82f2 100644
--- a/ext/gd/libgd/webpng.c
+++ b/ext/gd/libgd/webpng.c
@@ -252,7 +252,7 @@ usage:
/* Open a temporary file. */
/* "temp.tmp" is not good temporary filename. */
- sprintf (outFn, "webpng.tmp%d", getpid ());
+ snprintf (outFn, sizeof(outFn), "webpng.tmp%d", getpid ());
out = fopen (outFn, "wb");
if (!out)
diff --git a/ext/gd/libgd/xbm.c b/ext/gd/libgd/xbm.c
index 55dfac4e1..54288b755 100644
--- a/ext/gd/libgd/xbm.c
+++ b/ext/gd/libgd/xbm.c
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2006 The PHP Group |
+ | Copyright (c) 1997-2007 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: xbm.c,v 1.7.2.2 2006/01/01 12:50:07 sniper Exp $ */
+/* $Id: xbm.c,v 1.7.2.2.2.1 2007/01/01 09:36:01 sebastian Exp $ */
#include <stdio.h>
#include <math.h>
diff --git a/ext/gd/php_gd.h b/ext/gd/php_gd.h
index 645428be1..05ccab1d3 100644
--- a/ext/gd/php_gd.h
+++ b/ext/gd/php_gd.h
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2006 The PHP Group |
+ | Copyright (c) 1997-2007 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_gd.h,v 1.59.2.3 2006/01/01 12:50:06 sniper Exp $ */
+/* $Id: php_gd.h,v 1.59.2.3.2.5 2007/04/17 15:31:45 pajoye Exp $ */
#ifndef PHP_GD_H
#define PHP_GD_H
@@ -66,7 +66,9 @@ extern zend_module_entry gd_module_entry;
/* gd.c functions */
PHP_MINFO_FUNCTION(gd);
PHP_MINIT_FUNCTION(gd);
+#if HAVE_LIBT1 || HAVE_GD_FONTMUTEX
PHP_MSHUTDOWN_FUNCTION(gd);
+#endif
#if HAVE_LIBGD20 && HAVE_GD_STRINGFT
PHP_RSHUTDOWN_FUNCTION(gd);
#endif
@@ -112,6 +114,11 @@ PHP_FUNCTION(imagecolorexactalpha);
PHP_FUNCTION(imagecopyresampled);
#endif
+#ifdef PHP_WIN32
+PHP_FUNCTION(imagegrabwindow);
+PHP_FUNCTION(imagegrabscreen);
+#endif
+
#ifdef HAVE_GD_BUNDLED
PHP_FUNCTION(imagerotate);
PHP_FUNCTION(imageantialias);
diff --git a/ext/gd/tests/bug37360.phpt b/ext/gd/tests/bug37360.phpt
index dce22e7c6..4b377ade8 100644
--- a/ext/gd/tests/bug37360.phpt
+++ b/ext/gd/tests/bug37360.phpt
@@ -11,4 +11,5 @@ $im = imagecreatefromgif(dirname(__FILE__) . '/bug37360.gif');
var_dump($im);
?>
--EXPECTF--
-resource(%d) of type (gd)
+Warning: imagecreatefromgif(): '%s' is not a valid GIF file in %s on line %d
+bool(false)
diff --git a/ext/gd/tests/bug38179.phpt b/ext/gd/tests/bug38179.phpt
index 01adaa32c..34a6d58e0 100644
--- a/ext/gd/tests/bug38179.phpt
+++ b/ext/gd/tests/bug38179.phpt
@@ -1,5 +1,5 @@
--TEST--
-imagecopy doen't copy alpha, palette to truecolor
+Bug #38179 (imagecopy from a palette to a truecolor image loses alpha channel)
--SKIPIF--
<?php
if (!function_exists('imagecopy')) die("skip gd extension not available\n");
diff --git a/ext/gd/tests/bug38212.phpt b/ext/gd/tests/bug38212.phpt
index 0094712a5..04c89fece 100644
--- a/ext/gd/tests/bug38212.phpt
+++ b/ext/gd/tests/bug38212.phpt
@@ -1,5 +1,5 @@
--TEST--
-imagecopy doen't copy alpha, palette to truecolor
+Bzg #38212 (Seg Fault on invalid imagecreatefromgd2part() parameters)
--SKIPIF--
<?php
if (!function_exists('imagecopy')) die("skip gd extension not available\n");
@@ -14,4 +14,5 @@ $im = imagecreatefromgd2part($file, 0,0, -25,10);
unlink($file);
?>
--EXPECTF--
-Warning: imagecreatefromgd2part(): '%sbug38212.gd2' is not a valid GD2 file in %sbug38212.php on line %d
+
+Warning: imagecreatefromgd2part(): Zero width or height not allowed in %s on line %d
diff --git a/ext/gd/tests/bug39273.phpt b/ext/gd/tests/bug39273.phpt
new file mode 100644
index 000000000..438450044
--- /dev/null
+++ b/ext/gd/tests/bug39273.phpt
@@ -0,0 +1,32 @@
+--TEST--
+Bug #37360 (gdimagecreatefromgif, bad image sizes)
+--SKIPIF--
+<?php
+ if (!extension_loaded('gd')) die("skip gd extension not available\n");
+ if (!GD_BUNDLED) die('skip external GD libraries always fail');
+?>
+--FILE--
+<?php
+$small = imagecreatetruecolor(10, 10);
+$c1 = imagecolorallocatealpha($small, 255,0,0,50);
+imagecolortransparent($small, 0);
+imagealphablending($small, 0);
+imagefilledrectangle($small, 0,0, 6,6, $c1);
+
+$width = 300;
+$height = 300;
+$srcw = imagesx($small);
+$srch = imagesy($small);
+
+$img = imagecreatetruecolor($width, $height);
+
+imagecolortransparent($img, 0);
+imagealphablending($img, false);
+imagecopyresized($img, $small, 0,0, 0,0, $width, $height, $srcw, $srch);
+imagesavealpha($img, 1);
+
+$c = imagecolorat($img, 0,0);
+printf("%X", $c);
+?>
+--EXPECTF--
+32FF0000
diff --git a/ext/gd/tests/bug39286.phpt b/ext/gd/tests/bug39286.phpt
new file mode 100644
index 000000000..3f2a17812
--- /dev/null
+++ b/ext/gd/tests/bug39286.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Bug #39508 (imagefill crashes with small images 3 pixels or less)
+--SKIPIF--
+<?php
+ if (!extension_loaded('gd')) die("skip gd extension not available\n");
+ if (!GD_BUNDLED) die('skip external GD libraries always fail');
+?>
+--FILE--
+<?php
+$img =imagecreatefromgd2part("foo.png",0, 100, 0, 100);
+?>
+--EXPECTF--
+
+Warning: imagecreatefromgd2part(): Zero width or height not allowed in %s on line %d
diff --git a/ext/gd/tests/bug39366.phpt b/ext/gd/tests/bug39366.phpt
new file mode 100644
index 000000000..212012a1b
--- /dev/null
+++ b/ext/gd/tests/bug39366.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Bug #39366 (imagerotate does not respect alpha with angles>45)
+--SKIPIF--
+<?php
+ if (!extension_loaded('gd')) die("skip gd extension not available\n");
+ if (!GD_BUNDLED) die('skip external GD libraries always fail');
+?>
+--FILE--
+<?php
+
+$im = imagecreatetruecolor(10,10);
+imagealphablending($im, 0);
+imagefilledrectangle($im, 0,0, 8,8, 0x32FF0000);
+$rotate = imagerotate($im, 180, 0);
+imagecolortransparent($rotate,0);
+imagesavealpha($rotate, true);
+$c = imagecolorat($rotate,5,5);
+printf("%X\n", $c);
+?>
+--EXPECTF--
+32FF0000
diff --git a/ext/gd/tests/bug39508.phpt b/ext/gd/tests/bug39508.phpt
new file mode 100644
index 000000000..9e86efc20
--- /dev/null
+++ b/ext/gd/tests/bug39508.phpt
@@ -0,0 +1,16 @@
+--TEST--
+Bug #39508 (imagefill crashes with small images 3 pixels or less)
+--SKIPIF--
+<?php
+ if (!extension_loaded('gd')) die("skip gd extension not available\n");
+ if (!GD_BUNDLED) die('skip external GD libraries always fail');
+?>
+--FILE--
+<?php
+$im = imagecreatetruecolor(3,1);
+$bgcolor = imagecolorallocatealpha($im,255, 255, 0, 0);
+imagefill($im,0,0,$bgcolor);
+print_r(imagecolorat($im, 1,0));
+?>
+--EXPECTF--
+16776960
diff --git a/ext/gd/tests/bug39780.phpt b/ext/gd/tests/bug39780.phpt
new file mode 100644
index 000000000..3a23aa9df
--- /dev/null
+++ b/ext/gd/tests/bug39780.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Bug #39780 (PNG image with CRC/data error raises a fatal error)
+--SKIPIF--
+<?php
+ if (!extension_loaded('gd')) die("skip gd extension not available\n");
+ if (!GD_BUNDLED) die('skip external GD libraries always fail');
+?>
+--FILE--
+<?php
+
+$im = imagecreatefrompng(dirname(__FILE__) . '/bug39780.png');
+var_dump($im);
+?>
+--EXPECTF--
+
+Warning: imagecreatefrompng(): gd-png: fatal libpng error: IDAT: CRC error in %s on line %d
+
+Warning: imagecreatefrompng(): gd-png error: setjmp returns error condition in %s on line %d
+
+Warning: imagecreatefrompng(): '%s' is not a valid PNG file in %s on line %d
+bool(false)
diff --git a/ext/gd/tests/bug39780.png b/ext/gd/tests/bug39780.png
new file mode 100644
index 000000000..73a7d6a3e
--- /dev/null
+++ b/ext/gd/tests/bug39780.png
Binary files differ
diff --git a/ext/gd/tests/bug40764.phpt b/ext/gd/tests/bug40764.phpt
new file mode 100644
index 000000000..cbe262fe7
--- /dev/null
+++ b/ext/gd/tests/bug40764.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Bug #40764 (line thickness not respected for horizontal and vertical lines)
+--SKIPIF--
+<?php
+ if (!extension_loaded('gd')) die("skip gd extension not available\n");
+?>
+--FILE--
+<?php
+$image=imagecreatetruecolor(400, 400);
+$white = imagecolorallocate($image, 255, 255, 255);
+$black = imagecolorallocate($image, 0, 0, 0);
+$red = imagecolorallocate($image, 255, 0, 0);
+
+imagefill($image, 0, 0, $white);
+imagesetthickness($image, 10);
+
+imageline($image, 200, 0, 200, 400, $black);
+imageline($image, 0, 200, 400, 200, $black);
+imageline($image, 0, 0, 392, 392, $black);
+
+imagesetthickness($image, 1);
+
+imageline($image, 200, 0, 200, 400, $red);
+imageline($image, 0, 200, 400, 200, $red);
+imageline($image, 0, 0, 392, 392, $red);
+print_r(imagecolorat($image, 195, 0));
+print_r(imagecolorat($image, 0, 195));
+
+?>
+--EXPECT--
+00
diff --git a/ext/gd/tests/createfromwbmp2.phpt b/ext/gd/tests/createfromwbmp2.phpt
new file mode 100644
index 000000000..88c39b02a
--- /dev/null
+++ b/ext/gd/tests/createfromwbmp2.phpt
@@ -0,0 +1,47 @@
+--TEST--
+imagecreatefromwbmp with invalid wbmp
+--SKIPIF--
+<?php
+ if (!function_exists('imagecreatefromwbmp')) die("skip gd extension not available\n");
+?>
+--FILE--
+<?php
+$filename = dirname(__FILE__) . '/_tmp.wbmp';
+$fp = fopen($filename,"wb");
+if (!$fp) {
+ exit("Failed to create <$filename>");
+}
+
+//write header
+$c = 0;
+fputs($fp, chr($c), 1);
+fputs($fp, $c, 1);
+
+//write width = 2^32 / 4 + 1
+$c = 0x84;
+fputs($fp, chr($c), 1);
+$c = 0x80;
+fputs($fp, chr($c), 1);
+fputs($fp, chr($c), 1);
+fputs($fp, chr($c), 1);
+$c = 0x01;
+fputs($fp, chr($c), 1);
+
+/*write height = 4*/
+$c = 0x04;
+fputs($fp, chr($c), 1);
+
+/*write some data to cause overflow*/
+for ($i=0; $i<10000; $i++) {
+ fwrite($fp, chr($c), 1);
+}
+
+fclose($fp);
+$im = imagecreatefromwbmp($filename);
+unlink($filename);
+?>
+--EXPECTF--
+Warning: imagecreatefromwbmp(): gd warning: product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully
+ in %s on line %d
+
+Warning: imagecreatefromwbmp(): '%s' is not a valid WBMP file in %s on line %d
diff --git a/ext/gd/tests/gif.phpt b/ext/gd/tests/gif.phpt
index f4ed578c4..dd71a5404 100644
--- a/ext/gd/tests/gif.phpt
+++ b/ext/gd/tests/gif.phpt
@@ -2,7 +2,7 @@
gif in/out
--SKIPIF--
<?php
-// $Id: gif.phpt,v 1.2.2.2 2006/07/17 12:54:09 pajoye Exp $
+// $Id: gif.phpt,v 1.2.2.3 2006/11/03 14:51:02 bjori Exp $
if (!extension_loaded('gd')) {
die("skip gd extension not available.");
}
@@ -133,6 +133,7 @@ if (check_box(255,255,255, 10)) {
}
@unlink($cwd . "/test_gif.gif");
+@unlink($cwd . "/test_gif_2.gif");
?>
--EXPECT--
<4 cols: ok
diff --git a/ext/gd/tests/test_gif_2.gif b/ext/gd/tests/test_gif_2.gif
deleted file mode 100644
index 332ec8b41..000000000
--- a/ext/gd/tests/test_gif_2.gif
+++ /dev/null
Binary files differ