--- php-4.3.10/ext/standard/image.c 2004-10-04 14:44:07.000000000 -0600 +++ php-4.3.11RC1/ext/standard/image.c 2005-03-06 10:05:41.000000000 -0700 @@ -422,35 +422,39 @@ /* {{{ php_skip_variable * skip over a variable-length block; assumes proper length marker */ -static void php_skip_variable(php_stream * stream TSRMLS_DC) +static int php_skip_variable(php_stream * stream TSRMLS_DC) { off_t length = ((unsigned int)php_read2(stream TSRMLS_CC)); - length = length-2; - if (length) - { - php_stream_seek(stream, (long)length, SEEK_CUR); + if (length < 2) { + return 0; } + length = length - 2; + php_stream_seek(stream, (long)length, SEEK_CUR); + return 1; } /* }}} */ /* {{{ php_read_APP */ -static void php_read_APP(php_stream * stream, unsigned int marker, zval *info TSRMLS_DC) +static int php_read_APP(php_stream * stream, unsigned int marker, zval *info TSRMLS_DC) { unsigned short length; unsigned char *buffer; unsigned char markername[ 16 ]; zval *tmp; length = php_read2(stream TSRMLS_CC); + if (length < 2) { + return 0; + } length -= 2; /* length includes itself */ buffer = emalloc(length); if (php_stream_read(stream, buffer, (long) length) <= 0) { efree(buffer); - return; + return 0; } sprintf(markername, "APP%d", marker - M_APP0); @@ -461,6 +465,7 @@ } efree(buffer); + return 1; } /* }}} */ @@ -502,7 +507,9 @@ if (php_stream_seek(stream, length-8, SEEK_CUR)) /* file error after info */ return result; } else { - php_skip_variable(stream TSRMLS_CC); + if (!php_skip_variable(stream TSRMLS_CC)) { + return result; + } } break; @@ -523,9 +532,13 @@ case M_APP14: case M_APP15: if (info) { - php_read_APP(stream, marker, info TSRMLS_CC); /* read all the app markes... */ + if (!php_read_APP(stream, marker, info TSRMLS_CC)) { /* read all the app markes... */ + return result; + } } else { - php_skip_variable(stream TSRMLS_CC); + if (!php_skip_variable(stream TSRMLS_CC)) { + return result; + } } break; @@ -534,7 +547,9 @@ return result; /* we're about to hit image data, or are at EOF. stop processing. */ default: - php_skip_variable(stream TSRMLS_CC); /* anything else isn't interesting */ + if (!php_skip_variable(stream TSRMLS_CC)) { /* anything else isn't interesting */ + return result; + } break; } } @@ -613,17 +628,28 @@ dummy_short = php_read2(stream TSRMLS_CC); /* Lsiz */ dummy_short = php_read2(stream TSRMLS_CC); /* Rsiz */ - result->height = php_read4(stream TSRMLS_CC); /* Xsiz */ result->width = php_read4(stream TSRMLS_CC); /* Ysiz */ + result->height = php_read4(stream TSRMLS_CC); /* Xsiz */ +#if MBO_0 dummy_int = php_read4(stream TSRMLS_CC); /* XOsiz */ dummy_int = php_read4(stream TSRMLS_CC); /* YOsiz */ dummy_int = php_read4(stream TSRMLS_CC); /* XTsiz */ dummy_int = php_read4(stream TSRMLS_CC); /* YTsiz */ dummy_int = php_read4(stream TSRMLS_CC); /* XTOsiz */ dummy_int = php_read4(stream TSRMLS_CC); /* YTOsiz */ +#else + if (php_stream_seek(stream, 24, SEEK_CUR)) { + efree(result); + return NULL; + } +#endif result->channels = php_read2(stream TSRMLS_CC); /* Csiz */ + if (result->channels < 0 || result->channels > 256) { + efree(result); + return NULL; + } /* Collect bit depth info */ highest_bit_depth = bit_depth = 0; @@ -685,8 +711,15 @@ break; } + /* Stop if this was the last box */ + if ((int)box_length <= 0) { + break; + } + /* Skip over LBox (Which includes both TBox and LBox itself */ - php_stream_seek(stream, box_length - 8, SEEK_CUR); + if (php_stream_seek(stream, box_length - 8, SEEK_CUR)) { + break; + } } if (result == NULL) { @@ -849,43 +882,47 @@ */ static struct gfxinfo *php_handle_iff(php_stream * stream TSRMLS_DC) { - struct gfxinfo *result = NULL; + struct gfxinfo * result; unsigned char a[10]; int chunkId; int size; + short width, height, bits; if (php_stream_read(stream, a, 8) != 8) return NULL; if (strncmp(a+4, "ILBM", 4) && strncmp(a+4, "PBM ", 4)) return NULL; - - result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); /* loop chunks to find BMHD chunk */ do { if (php_stream_read(stream, a, 8) != 8) { - efree(result); return NULL; } chunkId = php_ifd_get32s(a+0, 1); size = php_ifd_get32s(a+4, 1); + if (size < 0) { + return NULL; + } if ((size & 1) == 1) { size++; } if (chunkId == 0x424d4844) { /* BMHD chunk */ - if (php_stream_read(stream, a, 9) != 9) { - efree(result); + if (size < 9 || php_stream_read(stream, a, 9) != 9) { return NULL; } - result->width = php_ifd_get16s(a+0, 1); - result->height = php_ifd_get16s(a+2, 1); - result->bits = a[8] & 0xff; + width = php_ifd_get16s(a+0, 1); + height = php_ifd_get16s(a+2, 1); + bits = a[8] & 0xff; + if (width > 0 && height > 0 && bits > 0 && bits < 33) { + result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); + result->width = width; + result->height = height; + result->bits = bits; result->channels = 0; - if (result->width > 0 && result->height > 0 && result->bits > 0 && result->bits < 33) return result; + } } else { if (php_stream_seek(stream, size, SEEK_CUR)) { - efree(result); return NULL; } }