diff options
| author | Jakub Zelenka <bukka@php.net> | 2016-06-19 17:05:48 +0100 |
|---|---|---|
| committer | Jakub Zelenka <bukka@php.net> | 2016-06-19 17:05:48 +0100 |
| commit | e63a8540a60e95aa5bd8e269add1b02afcc1b79b (patch) | |
| tree | b83a144eec24cc81adab0b9a778f7a730d8df79e /ext/gd | |
| parent | 7a4cc73641bb3eb878f7184bcbd026ee663cf2a9 (diff) | |
| parent | 53071e647049f099f7f7a0771ddb63fc2cdd621c (diff) | |
| download | php-git-e63a8540a60e95aa5bd8e269add1b02afcc1b79b.tar.gz | |
Merge branch 'openssl_error_store' into openssl_aead
Diffstat (limited to 'ext/gd')
| -rw-r--r-- | ext/gd/gd.c | 4 | ||||
| -rw-r--r-- | ext/gd/libgd/gd.c | 60 | ||||
| -rw-r--r-- | ext/gd/libgd/gd_gd2.c | 6 | ||||
| -rw-r--r-- | ext/gd/libgd/gd_interpolation.c | 42 | ||||
| -rw-r--r-- | ext/gd/libgd/gd_webp.c | 12 | ||||
| -rw-r--r-- | ext/gd/libgd/xbm.c | 2 | ||||
| -rw-r--r-- | ext/gd/tests/bug43475.phpt | 59 | ||||
| -rw-r--r-- | ext/gd/tests/bug43475.png | bin | 0 -> 4697 bytes | |||
| -rw-r--r-- | ext/gd/tests/bug53640.phpt | 2 | ||||
| -rw-r--r-- | ext/gd/tests/bug71912.phpt | 16 | ||||
| -rw-r--r-- | ext/gd/tests/bug71952.phpt | 14 | ||||
| -rw-r--r-- | ext/gd/tests/bug72227.phpt | 15 | ||||
| -rw-r--r-- | ext/gd/tests/bug72337.phpt | 14 | ||||
| -rw-r--r-- | ext/gd/tests/github_bug_215.phpt | 43 | ||||
| -rw-r--r-- | ext/gd/tests/invalid_neg_size.gd2 | bin | 0 -> 1676 bytes |
15 files changed, 274 insertions, 15 deletions
diff --git a/ext/gd/gd.c b/ext/gd/gd.c index d863523852..b09990938d 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -4667,6 +4667,10 @@ PHP_FUNCTION(imagescale) } } + if (tmp_h <= 0 || tmp_w <= 0) { + RETURN_FALSE; + } + new_width = tmp_w; new_height = tmp_h; diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c index b427831672..5c7b5ce1ba 100644 --- a/ext/gd/libgd/gd.c +++ b/ext/gd/libgd/gd.c @@ -1049,11 +1049,13 @@ void gdImageAABlend (gdImagePtr im) } } +static void _gdImageFilledHRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color); + static void gdImageHLine(gdImagePtr im, int y, int x1, int x2, int col) { if (im->thick > 1) { int thickhalf = im->thick >> 1; - gdImageFilledRectangle(im, x1, y - thickhalf, x2, y + im->thick - thickhalf - 1, col); + _gdImageFilledHRectangle(im, x1, y - thickhalf, x2, y + im->thick - thickhalf - 1, col); } else { if (x2 < x1) { int t = x2; @@ -1767,6 +1769,12 @@ void gdImageFillToBorder (gdImagePtr im, int x, int y, int border, int color) return; } + if (!im->trueColor) { + if ((color > (im->colorsTotal - 1)) || (border > (im->colorsTotal - 1)) || (color < 0)) { + return; + } + } + restoreAlphaBlending = im->alphaBlendingFlag; im->alphaBlendingFlag = 0; @@ -2112,10 +2120,53 @@ void gdImageRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color) } } -void gdImageFilledRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color) +static void _gdImageFilledHRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color) { int x, y; + if (x1 == x2 && y1 == y2) { + gdImageSetPixel(im, x1, y1, color); + return; + } + + if (x1 > x2) { + x = x1; + x1 = x2; + x2 = x; + } + + if (y1 > y2) { + y = y1; + y1 = y2; + y2 = y; + } + + if (x1 < 0) { + x1 = 0; + } + + if (x2 >= gdImageSX(im)) { + x2 = gdImageSX(im) - 1; + } + + if (y1 < 0) { + y1 = 0; + } + + if (y2 >= gdImageSY(im)) { + y2 = gdImageSY(im) - 1; + } + + for (x = x1; (x <= x2); x++) { + for (y = y1; (y <= y2); y++) { + gdImageSetPixel (im, x, y, color); + } + } +} + +static void _gdImageFilledVRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color) +{ + int x, y; if (x1 == x2 && y1 == y2) { gdImageSetPixel(im, x1, y1, color); @@ -2157,6 +2208,11 @@ void gdImageFilledRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int } } +void gdImageFilledRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color) +{ + _gdImageFilledVRectangle(im, x1, y1, x2, y2, color); +} + void gdImageCopy (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h) { int c; diff --git a/ext/gd/libgd/gd_gd2.c b/ext/gd/libgd/gd_gd2.c index efc6ef47af..6726fee826 100644 --- a/ext/gd/libgd/gd_gd2.c +++ b/ext/gd/libgd/gd_gd2.c @@ -145,9 +145,15 @@ static int _gd2GetHeader(gdIOCtxPtr in, int *sx, int *sy, int *cs, int *vers, in cidx = gdCalloc(sidx, 1); for (i = 0; i < nc; i++) { if (gdGetInt(&cidx[i].offset, in) != 1) { + gdFree(cidx); goto fail1; } if (gdGetInt(&cidx[i].size, in) != 1) { + gdFree(cidx); + goto fail1; + } + if (cidx[i].offset < 0 || cidx[i].size < 0) { + gdFree(cidx); goto fail1; } } diff --git a/ext/gd/libgd/gd_interpolation.c b/ext/gd/libgd/gd_interpolation.c index a06e333add..6d703b8b30 100644 --- a/ext/gd/libgd/gd_interpolation.c +++ b/ext/gd/libgd/gd_interpolation.c @@ -932,9 +932,6 @@ static inline LineContribType *_gdContributionsCalc(unsigned int line_size, unsi double dTotalWeight = 0.0; int iSrc; - res->ContribRow[u].Left = iLeft; - res->ContribRow[u].Right = iRight; - /* Cut edge points to fit in filter window in case of spill-off */ if (iRight - iLeft + 1 > windows_size) { if (iLeft < ((int)src_size - 1 / 2)) { @@ -944,6 +941,9 @@ static inline LineContribType *_gdContributionsCalc(unsigned int line_size, unsi } } + res->ContribRow[u].Left = iLeft; + res->ContribRow[u].Right = iRight; + for (iSrc = iLeft; iSrc <= iRight; iSrc++) { dTotalWeight += (res->ContribRow[u].Weights[iSrc-iLeft] = scale_f_d * (*pFilter)(scale_f_d * (dCenter - (double)iSrc))); } @@ -1059,6 +1059,10 @@ gdImagePtr gdImageScaleTwoPass(const gdImagePtr src, const unsigned int src_widt gdImagePtr tmp_im; gdImagePtr dst; + if (new_width == 0 || new_height == 0) { + return NULL; + } + /* Convert to truecolor if it isn't; this code requires it. */ if (!src->trueColor) { gdImagePaletteToTrueColor(src); @@ -1087,6 +1091,10 @@ gdImagePtr Scale(const gdImagePtr src, const unsigned int src_width, const unsig { gdImagePtr tmp_im; + if (new_width == 0 || new_height == 0) { + return NULL; + } + tmp_im = gdImageCreateTrueColor(new_width, src_height); if (tmp_im == NULL) { return NULL; @@ -1096,7 +1104,7 @@ gdImagePtr Scale(const gdImagePtr src, const unsigned int src_width, const unsig _gdScaleHoriz(src, src_width, src_height, tmp_im, new_width, src_height); _gdScaleVert(tmp_im, new_width, src_height, dst, new_width, new_height); - gdFree(tmp_im); + gdImageDestroy(tmp_im); return dst; } @@ -1120,6 +1128,10 @@ gdImagePtr gdImageScaleNearestNeighbour(gdImagePtr im, const unsigned int width, unsigned long dst_offset_y = 0; unsigned int i; + if (new_width == 0 || new_height == 0) { + return NULL; + } + dst_img = gdImageCreateTrueColor(new_width, new_height); if (dst_img == NULL) { @@ -1221,6 +1233,10 @@ static gdImagePtr gdImageScaleBilinearPalette(gdImagePtr im, const unsigned int gdImagePtr new_img; const int transparent = im->transparent; + if (new_width == 0 || new_height == 0) { + return NULL; + } + new_img = gdImageCreateTrueColor(new_width, new_height); if (new_img == NULL) { return NULL; @@ -1313,6 +1329,10 @@ static gdImagePtr gdImageScaleBilinearTC(gdImagePtr im, const unsigned int new_w long i; gdImagePtr new_img; + if (new_width == 0 || new_height == 0) { + return NULL; + } + new_img = gdImageCreateTrueColor(new_width, new_height); if (!new_img){ return NULL; @@ -1412,6 +1432,10 @@ gdImagePtr gdImageScaleBicubicFixed(gdImagePtr src, const unsigned int width, co unsigned int dst_offset_y = 0; long i; + if (new_width == 0 || new_height == 0) { + return NULL; + } + /* impact perf a bit, but not that much. Implementation for palette images can be done at a later point. */ @@ -1634,7 +1658,11 @@ gdImagePtr gdImageScale(const gdImagePtr src, const unsigned int new_width, cons gdImagePtr im_scaled = NULL; if (src == NULL || src->interpolation_id < 0 || src->interpolation_id > GD_METHOD_COUNT) { - return 0; + return NULL; + } + + if (new_width == 0 || new_height == 0) { + return NULL; } switch (src->interpolation_id) { @@ -1680,6 +1708,10 @@ gdImagePtr gdImageRotateNearestNeighbour(gdImagePtr src, const float degrees, co unsigned int i; gdImagePtr dst; + if (new_width == 0 || new_height == 0) { + return NULL; + } + dst = gdImageCreateTrueColor(new_width, new_height); if (!dst) { return NULL; diff --git a/ext/gd/libgd/gd_webp.c b/ext/gd/libgd/gd_webp.c index eef65f79fb..da0cc9d5b8 100644 --- a/ext/gd/libgd/gd_webp.c +++ b/ext/gd/libgd/gd_webp.c @@ -14,6 +14,8 @@ gdImagePtr gdImageCreateFromWebp (FILE * inFile) { gdImagePtr im; gdIOCtx *in = gdNewFileCtx(inFile); + if (!in) + return 0; im = gdImageCreateFromWebpCtx(in); in->gd_free(in); @@ -37,13 +39,14 @@ gdImagePtr gdImageCreateFromWebpCtx (gdIOCtx * infile) int width, height; uint8_t *filedata = NULL; uint8_t *argb = NULL; - unsigned char *read, *temp; size_t size = 0, n; gdImagePtr im; int x, y; uint8_t *p; do { + unsigned char *read, *temp; + temp = gdRealloc(filedata, size+GD_WEBP_ALLOC_STEP); if (temp) { filedata = temp; @@ -64,19 +67,19 @@ gdImagePtr gdImageCreateFromWebpCtx (gdIOCtx * infile) if (WebPGetInfo(filedata,size, &width, &height) == 0) { zend_error(E_ERROR, "gd-webp cannot get webp info"); - gdFree(temp); + gdFree(filedata); return NULL; } im = gdImageCreateTrueColor(width, height); if (!im) { - gdFree(temp); + gdFree(filedata); return NULL; } argb = WebPDecodeARGB(filedata, size, &width, &height); if (!argb) { zend_error(E_ERROR, "gd-webp cannot allocate temporary buffer"); - gdFree(temp); + gdFree(filedata); gdImageDestroy(im); return NULL; } @@ -92,7 +95,6 @@ gdImagePtr gdImageCreateFromWebpCtx (gdIOCtx * infile) gdFree(filedata); /* do not use gdFree here, in case gdFree/alloc is mapped to something else than libc */ free(argb); - gdFree(temp); im->saveAlphaFlag = 1; return im; } diff --git a/ext/gd/libgd/xbm.c b/ext/gd/libgd/xbm.c index d127a1d4ff..b351814abb 100644 --- a/ext/gd/libgd/xbm.c +++ b/ext/gd/libgd/xbm.c @@ -210,7 +210,7 @@ void gdImageXbmCtx(gdImagePtr image, char* file_name, int fg, gdIOCtx * out) if (gdImageGetPixel(image, x, y) == fg) { c |= b; } - if ((b == 128) || (x == sx && y == sy)) { + if ((b == 128) || (x == sx - 1)) { b = 1; if (p) { gdCtxPrintf(out, ", "); diff --git a/ext/gd/tests/bug43475.phpt b/ext/gd/tests/bug43475.phpt new file mode 100644 index 0000000000..b29b9800a5 --- /dev/null +++ b/ext/gd/tests/bug43475.phpt @@ -0,0 +1,59 @@ +--TEST-- +Bug #43475 (Thick styled lines have scrambled patterns) +--SKIPIF-- +<?php + if (!extension_loaded('gd')) die("skip gd extension not available\n"); +?> +--FILE-- +<?php +require_once __DIR__ . '/similarity.inc'; + +function setStyleAndThickness($im, $color, $thickness) +{ + $style = array(); + $i = 0; + while ($i < 16 * $thickness) { + $style[$i++] = $color; + } + while ($i < 20 * $thickness) { + $style[$i++] = IMG_COLOR_TRANSPARENT; + } + while ($i < 28 * $thickness) { + $style[$i++] = $color; + } + while ($i < 32 * $thickness) { + $style[$i++] = IMG_COLOR_TRANSPARENT; + } + imagesetstyle($im, $style); + imagesetthickness($im, $thickness); +} + +$im = imagecreate(800, 800); +imagecolorallocate($im, 255, 255, 255); +$black = imagecolorallocate($im, 0, 0, 0); + +setStyleAndThickness($im, $black, 1); +imageline($im, 50, 250, 550, 250, IMG_COLOR_STYLED); +imageline($im, 550, 250, 550, 750, IMG_COLOR_STYLED); +imageline($im, 550, 750, 50, 250, IMG_COLOR_STYLED); + +setStyleAndThickness($im, $black, 2); +imageline($im, 100, 200, 600, 200, IMG_COLOR_STYLED); +imageline($im, 600, 200, 600, 700, IMG_COLOR_STYLED); +imageline($im, 600, 700, 100, 200, IMG_COLOR_STYLED); + +setStyleAndThickness($im, $black, 4); +imageline($im, 150, 150, 650, 150, IMG_COLOR_STYLED); +imageline($im, 650, 150, 650, 650, IMG_COLOR_STYLED); +imageline($im, 650, 650, 150, 150, IMG_COLOR_STYLED); + +setStyleAndThickness($im, $black, 6); +imageline($im, 200, 100, 700, 100, IMG_COLOR_STYLED); +imageline($im, 700, 100, 700, 600, IMG_COLOR_STYLED); +imageline($im, 700, 600, 200, 100, IMG_COLOR_STYLED); + +$ex = imagecreatefrompng(__DIR__ . '/bug43475.png'); +var_dump(calc_image_dissimilarity($ex, $im) < 1e-5); +?> +--EXPECT-- +bool(true) diff --git a/ext/gd/tests/bug43475.png b/ext/gd/tests/bug43475.png Binary files differnew file mode 100644 index 0000000000..774270f63d --- /dev/null +++ b/ext/gd/tests/bug43475.png diff --git a/ext/gd/tests/bug53640.phpt b/ext/gd/tests/bug53640.phpt index a16b7c24c0..ee875de19a 100644 --- a/ext/gd/tests/bug53640.phpt +++ b/ext/gd/tests/bug53640.phpt @@ -12,8 +12,6 @@ $white = imagecolorallocate($im, 255, 255, 255); imagefilledrectangle($im, 2, 2, 6, 6, $white); imagexbm($im, NULL); ?> ---XFAIL-- -Padding is not implemented yet --EXPECT-- #define image_width 9 #define image_height 9 diff --git a/ext/gd/tests/bug71912.phpt b/ext/gd/tests/bug71912.phpt new file mode 100644 index 0000000000..c86188b0f2 --- /dev/null +++ b/ext/gd/tests/bug71912.phpt @@ -0,0 +1,16 @@ +--TEST-- +Bug #71912 (libgd: signedness vulnerability) +--SKIPIF-- +<?php + if(!extension_loaded('gd')){ die('skip gd extension not available'); } + if(!function_exists('imagecreatefromgd2')) die('skip imagecreatefromgd2() not available'); +?> +--FILE-- +<?php +imagecreatefromgd2(__DIR__ . DIRECTORY_SEPARATOR . "invalid_neg_size.gd2"); +?> +OK +--EXPECTF-- + +Warning: imagecreatefromgd2(): '%s%einvalid_neg_size.gd2' is not a valid GD2 file in %s%ebug71912.php on line %d +OK diff --git a/ext/gd/tests/bug71952.phpt b/ext/gd/tests/bug71952.phpt new file mode 100644 index 0000000000..f1f66bf26d --- /dev/null +++ b/ext/gd/tests/bug71952.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #71952 (Corruption inside imageaffinematrixget) +--SKIPIF-- +<?php + if(!extension_loaded('gd')){ die('skip gd extension not available'); } +?> +--FILE-- +<?php +$vals=[str_repeat("A","200"),0,1,2,3,4,5,6,7,8,9]; +imageaffinematrixget(4,$vals[0]); +var_dump($vals[0]); +?> +--EXPECTF-- +string(200) "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
\ No newline at end of file diff --git a/ext/gd/tests/bug72227.phpt b/ext/gd/tests/bug72227.phpt new file mode 100644 index 0000000000..6252be7d0e --- /dev/null +++ b/ext/gd/tests/bug72227.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #72227: imagescale out-of-bounds read +--SKIPIF-- +<?php + if (!extension_loaded('gd')) die("skip gd extension not available\n"); +?> +--FILE-- +<?php + +$img = imagecreatetruecolor ( 100, 100); +imagescale($img, 13, 1, IMG_BICUBIC); +?> +DONE +--EXPECT-- +DONE
\ No newline at end of file diff --git a/ext/gd/tests/bug72337.phpt b/ext/gd/tests/bug72337.phpt new file mode 100644 index 0000000000..7b8a869577 --- /dev/null +++ b/ext/gd/tests/bug72337.phpt @@ -0,0 +1,14 @@ +--TEST-- + #72337 segfault in imagescale with new dimensions being <=0) +--SKIPIF-- +<?php + if (!function_exists('imagescale')) die("skip gd extension not available\n"); +?> +--FILE-- +<?php +$im = imagecreatetruecolor(1, 1); +imagescale($im, 0, 0, IMG_BICUBIC_FIXED); +echo "OK"; +?> +--EXPECT-- +OK diff --git a/ext/gd/tests/github_bug_215.phpt b/ext/gd/tests/github_bug_215.phpt new file mode 100644 index 0000000000..f44a5401e1 --- /dev/null +++ b/ext/gd/tests/github_bug_215.phpt @@ -0,0 +1,43 @@ +--TEST-- +Github #215 (imagefilltoborder stack overflow when invalid pallete index used) +--SKIPIF-- +<?php +if (!extension_loaded("gd")) die("skip GD not present"); +?> +--FILE-- +<?php +$image = imagecreate( 10, 10 ); +$bgd = imagecolorallocate( $image, 0, 0, 0 ); +$border = imagecolorallocate( $image, 255, 0, 0 ); +$fillcolor = imagecolorallocate( $image, 255, 0, 0 ); + +/* Use unallocated color index */ +imagefilltoborder( $image, 0,0, $border+10, $fillcolor); +echo "#1 passes\n"; + +/* Use negative color index */ +imagefilltoborder( $image, 0,0, -$border, $fillcolor); +echo "#2 passes\n"; + + +/* Use unallocated color index */ +imagefilltoborder( $image, 0,0, $border, $fillcolor+10); +echo "#3 passes\n"; + +/* Use negative color index */ +imagefilltoborder( $image, 0,0, $border, -$fillcolor); +echo "#4 passes\n"; + + +/* Use negative color index */ +imagefilltoborder( $image, 0,0, $border+10, $fillcolor+10); +echo "#5 passes"; + + +?> +--EXPECT-- +#1 passes +#2 passes +#3 passes +#4 passes +#5 passes diff --git a/ext/gd/tests/invalid_neg_size.gd2 b/ext/gd/tests/invalid_neg_size.gd2 Binary files differnew file mode 100644 index 0000000000..3075f15a81 --- /dev/null +++ b/ext/gd/tests/invalid_neg_size.gd2 |
