summaryrefslogtreecommitdiff
path: root/ext/gd
diff options
context:
space:
mode:
authorChristoph M. Becker <cmbecker69@gmx.de>2018-11-25 15:41:27 +0100
committerChristoph M. Becker <cmbecker69@gmx.de>2018-11-25 15:41:27 +0100
commitb47b8886dd17d080c74c401f7893ba9f4ccb83d3 (patch)
treed1534664c9716cf9ec25639817d0fd2e53d5901b /ext/gd
parentff02d509099b0e3788fe99a48c784f47ca47c61b (diff)
downloadphp-git-b47b8886dd17d080c74c401f7893ba9f4ccb83d3.tar.gz
Fix #77198: auto cropping has insufficient precision
We apply the upstream patch[1], and also fix the erroneous bailout at the end of `gdImageAutoCrop()`, since `crop.x` and `crop.y` may very well be zero. [1] <https://github.com/libgd/libgd/commit/bda85aaeeb1d7467d92c892ba4c30eaa53d7a6d4>
Diffstat (limited to 'ext/gd')
-rw-r--r--ext/gd/libgd/gd_crop.c44
-rw-r--r--ext/gd/tests/bug77198_auto.phpt50
-rw-r--r--ext/gd/tests/bug77198_threshold.phpt47
3 files changed, 113 insertions, 28 deletions
diff --git a/ext/gd/libgd/gd_crop.c b/ext/gd/libgd/gd_crop.c
index 58b630317d..0b918c74c8 100644
--- a/ext/gd/libgd/gd_crop.c
+++ b/ext/gd/libgd/gd_crop.c
@@ -163,30 +163,24 @@ gdImagePtr gdImageCropAuto(gdImagePtr im, const unsigned int mode)
}
}
- /* Nothing to do > bye
- * Duplicate the image?
- */
- if (y == height - 1) {
+ /* Whole image would be cropped > bye */
+ if (match) {
return NULL;
}
- crop.y = y -1;
+ crop.y = y - 1;
+
match = 1;
for (y = height - 1; match && y >= 0; y--) {
for (x = 0; match && x < width; x++) {
match = (color == gdImageGetPixel(im, x,y));
}
}
-
- if (y == 0) {
- crop.height = height - crop.y + 1;
- } else {
- crop.height = y - crop.y + 2;
- }
+ crop.height = y - crop.y + 2;
match = 1;
for (x = 0; match && x < width; x++) {
- for (y = 0; match && y < crop.y + crop.height - 1; y++) {
+ for (y = 0; match && y < crop.y + crop.height; y++) {
match = (color == gdImageGetPixel(im, x,y));
}
}
@@ -194,12 +188,13 @@ gdImagePtr gdImageCropAuto(gdImagePtr im, const unsigned int mode)
match = 1;
for (x = width - 1; match && x >= 0; x--) {
- for (y = 0; match && y < crop.y + crop.height - 1; y++) {
+ for (y = 0; match && y < crop.y + crop.height; y++) {
match = (color == gdImageGetPixel(im, x,y));
}
}
crop.width = x - crop.x + 2;
- if (crop.x <= 0 || crop.y <= 0 || crop.width <= 0 || crop.height <= 0) {
+
+ if (crop.x < 0 || crop.y < 0 || crop.width <= 0 || crop.height <= 0) {
return NULL;
}
return gdImageCrop(im, &crop);
@@ -258,31 +253,24 @@ gdImagePtr gdImageCropThreshold(gdImagePtr im, const unsigned int color, const f
}
}
- /* Pierre
- * Nothing to do > bye
- * Duplicate the image?
- */
- if (y == height - 1) {
+ /* Whole image would be cropped > bye */
+ if (match) {
return NULL;
}
- crop.y = y -1;
+ crop.y = y - 1;
+
match = 1;
for (y = height - 1; match && y >= 0; y--) {
for (x = 0; match && x < width; x++) {
match = (gdColorMatch(im, color, gdImageGetPixel(im, x, y), threshold)) > 0;
}
}
-
- if (y == 0) {
- crop.height = height - crop.y + 1;
- } else {
- crop.height = y - crop.y + 2;
- }
+ crop.height = y - crop.y + 2;
match = 1;
for (x = 0; match && x < width; x++) {
- for (y = 0; match && y < crop.y + crop.height - 1; y++) {
+ for (y = 0; match && y < crop.y + crop.height; y++) {
match = (gdColorMatch(im, color, gdImageGetPixel(im, x,y), threshold)) > 0;
}
}
@@ -290,7 +278,7 @@ gdImagePtr gdImageCropThreshold(gdImagePtr im, const unsigned int color, const f
match = 1;
for (x = width - 1; match && x >= 0; x--) {
- for (y = 0; match && y < crop.y + crop.height - 1; y++) {
+ for (y = 0; match && y < crop.y + crop.height; y++) {
match = (gdColorMatch(im, color, gdImageGetPixel(im, x,y), threshold)) > 0;
}
}
diff --git a/ext/gd/tests/bug77198_auto.phpt b/ext/gd/tests/bug77198_auto.phpt
new file mode 100644
index 0000000000..d06f2be663
--- /dev/null
+++ b/ext/gd/tests/bug77198_auto.phpt
@@ -0,0 +1,50 @@
+--TEST--
+Bug #77198 (auto cropping has insufficient precision)
+--SKIPIF--
+<?php
+if (!extension_loaded('gd')) die('skip gd extension not available');
+if (!GD_BUNDLED) die('upstream bugfix has not been released');
+?>
+--FILE--
+<?php
+
+function createWhiteImageWithBlackPixelAt($x, $y)
+{
+ $im = imagecreatetruecolor(8, 8);
+ imagefilledrectangle($im, 0, 0, 7, 7, 0xffffff);
+ imagesetpixel($im, $x, $y, 0x000000);
+ return $im;
+}
+
+for ($y = 0; $y < 8; $y++) {
+ for ($x = 0; $x < 8; $x++) {
+ if (($x == 0 && ($y == 0 || $y == 7)) || ($x == 7 && ($y == 0 || $y == 7))) {
+ continue; // skip the corners
+ }
+ $orig = createWhiteImageWithBlackPixelAt($x, $y);
+ $cropped = imagecropauto($orig, IMG_CROP_SIDES);
+ if (!$cropped) {
+ printf("Pixel at %d, %d: unexpected NULL crop\n", $x, $y);
+ } else {
+ $width = imagesx($cropped);
+ if ($width !== 1) {
+ printf("Pixel at %d, %d: unexpected width (%d)\n", $x, $y, $width);
+ }
+ $height = imagesy($cropped);
+ if ($height !== 1) {
+ printf("Pixel at %d, %d: unexpected height (%d)\n", $x, $y, $height);
+ }
+ $color = imagecolorat($cropped, 0, 0);
+ if ($color !== 0x000000) {
+ printf("Pixel at %d, %d: unexpected color (%d)\n", $x, $y, $color);
+ }
+ imagedestroy($cropped);
+ }
+ imagedestroy($orig);
+ }
+}
+
+?>
+===DONE===
+--EXPECT--
+===DONE===
diff --git a/ext/gd/tests/bug77198_threshold.phpt b/ext/gd/tests/bug77198_threshold.phpt
new file mode 100644
index 0000000000..fd03660c84
--- /dev/null
+++ b/ext/gd/tests/bug77198_threshold.phpt
@@ -0,0 +1,47 @@
+--TEST--
+Bug #77198 (threshold cropping has insufficient precision)
+--SKIPIF--
+<?php
+if (!extension_loaded('gd')) die('skip gd extension not available');
+if (!GD_BUNDLED) die('upstream bugfix has not been released');
+?>
+--FILE--
+<?php
+
+function createWhiteImageWithBlackPixelAt($x, $y)
+{
+ $im = imagecreatetruecolor(8, 8);
+ imagefilledrectangle($im, 0, 0, 7, 7, 0xffffff);
+ imagesetpixel($im, $x, $y, 0x000000);
+ return $im;
+}
+
+for ($y = 0; $y < 8; $y++) {
+ for ($x = 0; $x < 8; $x++) {
+ $orig = createWhiteImageWithBlackPixelAt($x, $y);
+ $cropped = imagecropauto($orig, IMG_CROP_THRESHOLD, 1, 0xffffff);
+ if (!$cropped) {
+ printf("Pixel at %d, %d: unexpected NULL crop\n", $x, $y);
+ } else {
+ $width = imagesx($cropped);
+ if ($width !== 1) {
+ printf("Pixel at %d, %d: unexpected width (%d)\n", $x, $y, $width);
+ }
+ $height = imagesy($cropped);
+ if ($height !== 1) {
+ printf("Pixel at %d, %d: unexpected height (%d)\n", $x, $y, $height);
+ }
+ $color = imagecolorat($cropped, 0, 0);
+ if ($color !== 0x000000) {
+ printf("Pixel at %d, %d: unexpected color (%d)\n", $x, $y, $color);
+ }
+ imagedestroy($cropped);
+ }
+ imagedestroy($orig);
+ }
+}
+
+?>
+===DONE===
+--EXPECT--
+===DONE===