- fix previous commit (missing #ifdef in shutdown declaration)

- MFB:
 - Sync with gd 2.0.35 (bug #52, #60 and #66)
  - Improve TS of gif loading code (Roman Nemecek, Nuno, Pierre)
  - a frame size must be confined to the screen defition (Pierre)
  - be sure to always read the dimensions in the frame and does not use
    the screen size (see #66 for a side effect) (Pierre)
  - Update #37360 test. The frame does not fit the logical screen (specs
    tell that it must fit) (Pierre)
This commit is contained in:
Pierre Joye 2007-04-04 01:54:34 +00:00
parent 01e1fa0495
commit a110d07c96
4 changed files with 95 additions and 62 deletions

View file

@ -1078,7 +1078,11 @@ zend_module_entry gd_module_entry = {
"gd", "gd",
gd_functions, gd_functions,
PHP_MINIT(gd), PHP_MINIT(gd),
#if HAVE_LIBT1 || HAVE_GD_FONTMUTEX
PHP_MSHUTDOWN(gd), PHP_MSHUTDOWN(gd),
#else
NULL,
#endif
NULL, NULL,
#if HAVE_GD_STRINGFT && (HAVE_GD_FONTCACHESHUTDOWN || HAVE_GD_FREEFONTCACHE) #if HAVE_GD_STRINGFT && (HAVE_GD_FONTCACHESHUTDOWN || HAVE_GD_FREEFONTCACHE)
PHP_RSHUTDOWN(gd), PHP_RSHUTDOWN(gd),
@ -1122,9 +1126,9 @@ static void php_free_gd_font(zend_rsrc_list_entry *rsrc TSRMLS_DC)
} }
/* }}} */ /* }}} */
/* {{{ PHP_MSHUTDOWN_FUNCTION /* {{{ PHP_MSHUTDOWN_FUNCTION
*/ */
#if HAVE_LIBT1 || HAVE_GD_FONTMUTEX
PHP_MSHUTDOWN_FUNCTION(gd) PHP_MSHUTDOWN_FUNCTION(gd)
{ {
#if HAVE_LIBT1 #if HAVE_LIBT1
@ -1135,6 +1139,7 @@ PHP_MSHUTDOWN_FUNCTION(gd)
#endif #endif
return SUCCESS; return SUCCESS;
} }
#endif
/* }}} */ /* }}} */

View file

@ -61,12 +61,14 @@ static struct {
} GifScreen; } GifScreen;
#endif #endif
#if 0
static struct { static struct {
int transparent; int transparent;
int delayTime; int delayTime;
int inputFlag; int inputFlag;
int disposal; int disposal;
} Gif89 = { -1, -1, -1, 0 }; } Gif89 = { -1, -1, -1, 0 };
#endif
#define STACK_SIZE ((1<<(MAX_LWZ_BITS))*2) #define STACK_SIZE ((1<<(MAX_LWZ_BITS))*2)
@ -87,14 +89,12 @@ typedef struct {
} LZW_STATIC_DATA; } LZW_STATIC_DATA;
static int ReadColorMap (gdIOCtx *fd, int number, unsigned char (*buffer)[256]); 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 int GetDataBlock (gdIOCtx *fd, unsigned char *buf); static int GetDataBlock (gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP);
static int GetCode (gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag); 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, int flag, int input_code_size); 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); /*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); */
int ZeroDataBlock;
gdImagePtr gdImageCreateFromGifSource(gdSourcePtr inSource) /* {{{ */ gdImagePtr gdImageCreateFromGifSource(gdSourcePtr inSource) /* {{{ */
{ {
@ -126,22 +126,25 @@ gdImagePtr gdImageCreateFromGifCtx(gdIOCtxPtr fd) /* {{{ */
{ {
/* 1.4 int imageNumber; */ /* 1.4 int imageNumber; */
int BitPixel; int BitPixel;
#if 0
int ColorResolution; int ColorResolution;
int Background; int Background;
int AspectRatio; int AspectRatio;
#endif
int Transparent = (-1); int Transparent = (-1);
unsigned char buf[16]; unsigned char buf[16];
unsigned char c; unsigned char c;
unsigned char ColorMap[3][MAXCOLORMAPSIZE]; unsigned char ColorMap[3][MAXCOLORMAPSIZE];
unsigned char localColorMap[3][MAXCOLORMAPSIZE]; unsigned char localColorMap[3][MAXCOLORMAPSIZE];
int imw, imh; int imw, imh, screen_width, screen_height;
int useGlobalColormap; int gif87a, useGlobalColormap;
int bitPixel; int bitPixel;
int i; int i;
/*1.4//int imageCount = 0; */ /*1.4//int imageCount = 0; */
int ZeroDataBlock = FALSE;
gdImagePtr im = 0; gdImagePtr im = 0;
ZeroDataBlock = FALSE;
/*1.4//imageNumber = 1; */ /*1.4//imageNumber = 1; */
if (! ReadOK(fd,buf,6)) { if (! ReadOK(fd,buf,6)) {
@ -151,19 +154,26 @@ gdImagePtr gdImageCreateFromGifCtx(gdIOCtxPtr fd) /* {{{ */
return 0; return 0;
} }
if ((strncmp((char *)buf+3, "87a", 3) != 0) && (strncmp((char *)buf+3, "89a", 3) != 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; return 0;
} }
if (! ReadOK(fd,buf,7)) { if (! ReadOK(fd,buf,7)) {
return 0; return 0;
} }
BitPixel = 2<<(buf[4]&0x07); BitPixel = 2<<(buf[4]&0x07);
#if 0
ColorResolution = (int) (((buf[4]&0x70)>>3)+1); ColorResolution = (int) (((buf[4]&0x70)>>3)+1);
Background = buf[5]; Background = buf[5];
AspectRatio = buf[6]; AspectRatio = buf[6];
#endif
imw = LM_to_uint(buf[0],buf[1]); screen_width = imw = LM_to_uint(buf[0],buf[1]);
imh = LM_to_uint(buf[2],buf[3]); screen_height = imh = LM_to_uint(buf[2],buf[3]);
if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */ if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */
if (ReadColorMap(fd, BitPixel, ColorMap)) { if (ReadColorMap(fd, BitPixel, ColorMap)) {
@ -171,6 +181,9 @@ gdImagePtr gdImageCreateFromGifCtx(gdIOCtxPtr fd) /* {{{ */
} }
} }
for (;;) { for (;;) {
int top, left;
int width, height;
if (! ReadOK(fd,&c,1)) { if (! ReadOK(fd,&c,1)) {
return 0; return 0;
} }
@ -182,7 +195,7 @@ gdImagePtr gdImageCreateFromGifCtx(gdIOCtxPtr fd) /* {{{ */
if (! ReadOK(fd,&c,1)) { if (! ReadOK(fd,&c,1)) {
return 0; return 0;
} }
DoExtension(fd, c, &Transparent); DoExtension(fd, c, &Transparent, &ZeroDataBlock);
continue; continue;
} }
@ -199,29 +212,33 @@ gdImagePtr gdImageCreateFromGifCtx(gdIOCtxPtr fd) /* {{{ */
useGlobalColormap = ! BitSet(buf[8], LOCALCOLORMAP); useGlobalColormap = ! BitSet(buf[8], LOCALCOLORMAP);
bitPixel = 1<<((buf[8]&0x07)+1); bitPixel = 1<<((buf[8]&0x07)+1);
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(width, height))) {
return 0;
}
im->interlace = BitSet(buf[8], INTERLACE);
if (!useGlobalColormap) { if (!useGlobalColormap) {
if (ReadColorMap(fd, bitPixel, localColorMap)) { if (ReadColorMap(fd, bitPixel, localColorMap)) {
return 0; return 0;
} }
} ReadImage(im, fd, width, height, localColorMap,
BitSet(buf[8], INTERLACE), &ZeroDataBlock);
if (!(im = gdImageCreate(imw, imh))) {
return 0;
}
im->interlace = BitSet(buf[8], INTERLACE);
if (! useGlobalColormap) {
ReadImage(im, fd, imw, imh, localColorMap,
BitSet(buf[8], INTERLACE));
/*1.4//imageCount != imageNumber); */
} else { } else {
ReadImage(im, fd, imw, imh, ReadImage(im, fd, width, height,
ColorMap, ColorMap,
BitSet(buf[8], INTERLACE)); BitSet(buf[8], INTERLACE), &ZeroDataBlock);
/*1.4//imageCount != imageNumber); */
} }
if (Transparent != (-1)) { if (Transparent != (-1)) {
gdImageColorTransparent(im, Transparent); gdImageColorTransparent(im, Transparent);
} }
@ -273,34 +290,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)
{ {
unsigned char buf[256]; unsigned char buf[256];
switch (label) { switch (label) {
case 0xf9: /* Graphic Control Extension */ case 0xf9: /* Graphic Control Extension */
memset(buf, 0, 4); /* initialize a few bytes in the case the next function fails */ memset(buf, 0, 4); /* initialize a few bytes in the case the next function fails */
(void) GetDataBlock(fd, (unsigned char*) buf); (void) GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP);
#if 0
Gif89.disposal = (buf[0] >> 2) & 0x7; Gif89.disposal = (buf[0] >> 2) & 0x7;
Gif89.inputFlag = (buf[0] >> 1) & 0x1; Gif89.inputFlag = (buf[0] >> 1) & 0x1;
Gif89.delayTime = LM_to_uint(buf[1],buf[2]); Gif89.delayTime = LM_to_uint(buf[1],buf[2]);
#endif
if ((buf[0] & 0x1) != 0) if ((buf[0] & 0x1) != 0)
*Transparent = buf[3]; *Transparent = buf[3];
while (GetDataBlock(fd, (unsigned char*) buf) > 0) while (GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP) > 0);
;
return FALSE; return FALSE;
default: default:
break; break;
} }
while (GetDataBlock(fd, (unsigned char*) buf) > 0) while (GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP) > 0)
; ;
return FALSE; return FALSE;
} }
/* }}} */ /* }}} */
static int GetDataBlock_(gdIOCtx *fd, unsigned char *buf) /* {{{ */ static int
GetDataBlock_(gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP)
{ {
unsigned char count; unsigned char count;
@ -308,7 +328,7 @@ static int GetDataBlock_(gdIOCtx *fd, unsigned char *buf) /* {{{ */
return -1; return -1;
} }
ZeroDataBlock = count == 0; *ZeroDataBlockP = count == 0;
if ((count != 0) && (! ReadOK(fd, buf, count))) { if ((count != 0) && (! ReadOK(fd, buf, count))) {
return -1; return -1;
@ -318,14 +338,16 @@ 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 rv;
int i; int i;
char *tmp = NULL;
rv = GetDataBlock_(fd,buf);
rv = GetDataBlock_(fd,buf, ZeroDataBlockP);
if (VERBOSE) { if (VERBOSE) {
char *tmp = NULL;
if (rv > 0) { if (rv > 0) {
tmp = safe_emalloc(3 * rv, sizeof(char), 1); tmp = safe_emalloc(3 * rv, sizeof(char), 1);
for (i=0;i<rv;i++) { for (i=0;i<rv;i++) {
@ -341,7 +363,8 @@ static int GetDataBlock(gdIOCtx *fd, unsigned char *buf) /* {{{ */
} }
/* }}} */ /* }}} */
static int GetCode_(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag) /* {{{ */ static int
GetCode_(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP)
{ {
int i, j, ret; int i, j, ret;
unsigned char count; unsigned char count;
@ -364,7 +387,7 @@ static int GetCode_(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag)
scd->buf[0] = scd->buf[scd->last_byte-2]; scd->buf[0] = scd->buf[scd->last_byte-2];
scd->buf[1] = scd->buf[scd->last_byte-1]; scd->buf[1] = scd->buf[scd->last_byte-1];
if ((count = GetDataBlock(fd, &scd->buf[2])) <= 0) if ((count = GetDataBlock(fd, &scd->buf[2], ZeroDataBlockP)) <= 0)
scd->done = TRUE; scd->done = TRUE;
scd->last_byte = 2 + count; scd->last_byte = 2 + count;
@ -380,17 +403,19 @@ static int GetCode_(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag)
return ret; return ret;
} }
static int GetCode(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag) /* {{{ */ static int
GetCode(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP)
{ {
int rv; int rv;
rv = GetCode_(fd, scd, code_size, flag); rv = GetCode_(fd, scd, code_size,flag, ZeroDataBlockP);
if (VERBOSE) php_gd_error_ex(E_NOTICE, "[GetCode(,%d,%d) returning %d]",code_size,flag,rv); if (VERBOSE) printf("[GetCode(,%d,%d) returning %d]\n",code_size,flag,rv);
return(rv); return(rv);
} }
/* }}} */ /* }}} */
static int LWZReadByte_(gdIOCtx *fd, LZW_STATIC_DATA *sd, int flag, int input_code_size) /* {{{ */ static int
LWZReadByte_(gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP)
{ {
int code, incode, i; int code, incode, i;
@ -402,7 +427,7 @@ static int LWZReadByte_(gdIOCtx *fd, LZW_STATIC_DATA *sd, int flag, int input_co
sd->max_code_size = 2*sd->clear_code; sd->max_code_size = 2*sd->clear_code;
sd->max_code = sd->clear_code+2; sd->max_code = sd->clear_code+2;
GetCode(fd, &sd->scd, 0, TRUE); GetCode(fd, &sd->scd, 0, TRUE, ZeroDataBlockP);
sd->fresh = TRUE; sd->fresh = TRUE;
@ -420,7 +445,7 @@ static int LWZReadByte_(gdIOCtx *fd, LZW_STATIC_DATA *sd, int flag, int input_co
sd->fresh = FALSE; sd->fresh = FALSE;
do { do {
sd->firstcode = sd->oldcode = sd->firstcode = sd->oldcode =
GetCode(fd, &sd->scd, sd->code_size, FALSE); GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP);
} while (sd->firstcode == sd->clear_code); } while (sd->firstcode == sd->clear_code);
return sd->firstcode; return sd->firstcode;
} }
@ -428,7 +453,7 @@ static int LWZReadByte_(gdIOCtx *fd, LZW_STATIC_DATA *sd, int flag, int input_co
if (sd->sp > sd->stack) if (sd->sp > sd->stack)
return *--sd->sp; return *--sd->sp;
while ((code = GetCode(fd, &sd->scd, sd->code_size, FALSE)) >= 0) { while ((code = GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP)) >= 0) {
if (code == sd->clear_code) { if (code == sd->clear_code) {
for (i = 0; i < sd->clear_code; ++i) { for (i = 0; i < sd->clear_code; ++i) {
sd->table[0][i] = 0; sd->table[0][i] = 0;
@ -441,16 +466,16 @@ static int LWZReadByte_(gdIOCtx *fd, LZW_STATIC_DATA *sd, int flag, int input_co
sd->max_code = sd->clear_code+2; sd->max_code = sd->clear_code+2;
sd->sp = sd->stack; sd->sp = sd->stack;
sd->firstcode = sd->oldcode = sd->firstcode = sd->oldcode =
GetCode(fd, &sd->scd, sd->code_size, FALSE); GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP);
return sd->firstcode; return sd->firstcode;
} else if (code == sd->end_code) { } else if (code == sd->end_code) {
int count; int count;
unsigned char buf[260]; unsigned char buf[260];
if (ZeroDataBlock) if (*ZeroDataBlockP)
return -2; return -2;
while ((count = GetDataBlock(fd, buf)) > 0) while ((count = GetDataBlock(fd, buf, ZeroDataBlockP)) > 0)
; ;
if (count != 0) if (count != 0)
@ -503,17 +528,19 @@ static int LWZReadByte_(gdIOCtx *fd, LZW_STATIC_DATA *sd, int flag, int input_co
} }
/* }}} */ /* }}} */
static int LWZReadByte(gdIOCtx *fd, LZW_STATIC_DATA *sd, 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; int rv;
rv = LWZReadByte_(fd, sd, flag, input_code_size); rv = LWZReadByte_(fd, sd, flag, input_code_size, ZeroDataBlockP);
if (VERBOSE) php_gd_error_ex(E_NOTICE, "[LWZReadByte(,%d,%d) returning %d]",flag,input_code_size,rv); if (VERBOSE) printf("[LWZReadByte(,%d,%d) returning %d]\n",flag,input_code_size,rv);
return(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; unsigned char c;
int v; int v;
@ -541,7 +568,7 @@ static void ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned
} }
/* Many (perhaps most) of these colors will remain marked open. */ /* Many (perhaps most) of these colors will remain marked open. */
im->colorsTotal = gdMaxColors; im->colorsTotal = gdMaxColors;
if (LWZReadByte(fd, &sd, TRUE, c) < 0) { if (LWZReadByte(fd, &sd, TRUE, c, ZeroDataBlockP) < 0) {
return; return;
} }
@ -555,7 +582,7 @@ static void ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned
/* return; */ /* return; */
/*} */ /*} */
while ((v = LWZReadByte(fd, &sd, FALSE, c)) >= 0 ) { while ((v = LWZReadByte(fd, &sd, FALSE, c, ZeroDataBlockP)) >= 0 ) {
/* This how we recognize which colors are actually used. */ /* This how we recognize which colors are actually used. */
if (im->open[v]) { if (im->open[v]) {
im->open[v] = 0; im->open[v] = 0;
@ -597,7 +624,7 @@ static void ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned
} }
fini: fini:
if (LWZReadByte(fd, &sd, FALSE, c)>=0) { if (LWZReadByte(fd, &sd, FALSE, c, ZeroDataBlockP) >=0) {
/* Ignore extra */ /* Ignore extra */
} }
} }

View file

@ -64,7 +64,7 @@ extern zend_module_entry gd_module_entry;
/* gd.c functions */ /* gd.c functions */
PHP_MINFO_FUNCTION(gd); PHP_MINFO_FUNCTION(gd);
PHP_MINIT_FUNCTION(gd); PHP_MINIT_FUNCTION(gd);
#if HAVE_LIBT1 #if HAVE_LIBT1 || HAVE_GD_FONTMUTEX
PHP_MSHUTDOWN_FUNCTION(gd); PHP_MSHUTDOWN_FUNCTION(gd);
#endif #endif
#if HAVE_GD_STRINGFT #if HAVE_GD_STRINGFT

View file

@ -11,4 +11,5 @@ $im = imagecreatefromgif(dirname(__FILE__) . '/bug37360.gif');
var_dump($im); var_dump($im);
?> ?>
--EXPECTF-- --EXPECTF--
resource(%d) of type (gd) Warning: imagecreatefromgif(): '%s' is not a valid GIF file in %s on line %d
bool(false)