summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph M. Becker <cmb@php.net>2016-09-30 23:25:23 +0200
committerChristoph M. Becker <cmbecker69@gmx.de>2016-09-30 23:38:13 +0200
commit9acfb1a3a5268febb123b7e5fbd4eaf072c83537 (patch)
treecf92dfbd72302d9b7009e95ab3ce14d11f9490f6
parentc0219b323e0048440acbdd9ad74624c4bc33c335 (diff)
downloadphp-git-9acfb1a3a5268febb123b7e5fbd4eaf072c83537.tar.gz
Fix #73213: Integer overflow in imageline() with antialiasing
We port the respective fixes <https://github.com/libgd/libgd/commit/eca37d620> and <https://github.com/libgd/libgd/commit/837b7327> to our bundled libgd.
-rw-r--r--NEWS3
-rw-r--r--ext/gd/libgd/gd.c46
-rw-r--r--ext/gd/tests/bug73213.phpt22
-rw-r--r--ext/gd/tests/bug73213.pngbin0 -> 195 bytes
4 files changed, 54 insertions, 17 deletions
diff --git a/NEWS b/NEWS
index fae5b65ccd..e9e4b9486f 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,9 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? 2016, PHP 5.6.28
+-GD:
+ . Fixed bug #73213 (Integer overflow in imageline() with antialiasing). (cmb)
+
- Standard:
. Fixed bug #73203 (passing additional_parameters causes mail to fail). (cmb)
diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c
index 0b4b42fa27..033d4fa5f0 100644
--- a/ext/gd/libgd/gd.c
+++ b/ext/gd/libgd/gd.c
@@ -1298,7 +1298,7 @@ inline static void gdImageSetAAPixelColor(gdImagePtr im, int x, int y, int color
void gdImageAALine (gdImagePtr im, int x1, int y1, int x2, int y2, int col)
{
/* keep them as 32bits */
- long x, y, inc;
+ long x, y, inc, frac;
long dx, dy,tmp;
if (y1 < 0 && y2 < 0) {
@@ -1368,16 +1368,22 @@ void gdImageAALine (gdImagePtr im, int x1, int y1, int x2, int y2, int col)
dx = x2 - x1;
dy = y2 - y1;
}
- x = x1 << 16;
- y = y1 << 16;
+ y = y1;
inc = (dy * 65536) / dx;
- while ((x >> 16) <= x2) {
- gdImageSetAAPixelColor(im, x >> 16, y >> 16, col, (y >> 8) & 0xFF);
- if ((y >> 16) + 1 < im->sy) {
- gdImageSetAAPixelColor(im, x >> 16, (y >> 16) + 1,col, (~y >> 8) & 0xFF);
+ frac = 0;
+ for (x = x1; x <= x2; x++) {
+ gdImageSetAAPixelColor(im, x, y, col, (frac >> 8) & 0xFF);
+ if (y + 1 < im->sy) {
+ gdImageSetAAPixelColor(im, x, y + 1, col, (~frac >> 8) & 0xFF);
+ }
+ frac += inc;
+ if (frac >= 65536) {
+ frac -= 65536;
+ y++;
+ } else if (frac < 0) {
+ frac += 65536;
+ y--;
}
- x += (1 << 16);
- y += inc;
}
} else {
if (dy < 0) {
@@ -1390,16 +1396,22 @@ void gdImageAALine (gdImagePtr im, int x1, int y1, int x2, int y2, int col)
dx = x2 - x1;
dy = y2 - y1;
}
- x = x1 << 16;
- y = y1 << 16;
+ x = x1;
inc = (dx * 65536) / dy;
- while ((y>>16) <= y2) {
- gdImageSetAAPixelColor(im, x >> 16, y >> 16, col, (x >> 8) & 0xFF);
- if ((x >> 16) + 1 < im->sx) {
- gdImageSetAAPixelColor(im, (x >> 16) + 1, (y >> 16),col, (~x >> 8) & 0xFF);
+ frac = 0;
+ for (y = y1; y <= y2; y++) {
+ gdImageSetAAPixelColor(im, x, y, col, (frac >> 8) & 0xFF);
+ if (x + 1 < im->sx) {
+ gdImageSetAAPixelColor(im, x + 1, y, col, (~frac >> 8) & 0xFF);
+ }
+ frac += inc;
+ if (frac >= 65536) {
+ frac -= 65536;
+ x++;
+ } else if (frac < 0) {
+ frac += 65536;
+ x--;
}
- x += inc;
- y += (1<<16);
}
}
}
diff --git a/ext/gd/tests/bug73213.phpt b/ext/gd/tests/bug73213.phpt
new file mode 100644
index 0000000000..86c4078fd9
--- /dev/null
+++ b/ext/gd/tests/bug73213.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Bug #73213 (Integer overflow in imageline() with antialiasing)
+--SKIPIF--
+<?php
+if (!extension_loaded('gd')) die('skip gd extension not available');
+?>
+--FILE--
+<?php
+require_once __DIR__ . DIRECTORY_SEPARATOR . 'func.inc';
+
+$im = imagecreatetruecolor(32768, 1);
+$black = imagecolorallocate($im, 0, 0, 0);
+imageantialias($im, true);
+
+imageline($im, 0,0, 32767,0, $black);
+
+test_image_equals_file(__DIR__ . DIRECTORY_SEPARATOR . 'bug73213.png', $im);
+?>
+===DONE===
+--EXPECT--
+The images are equal.
+===DONE===
diff --git a/ext/gd/tests/bug73213.png b/ext/gd/tests/bug73213.png
new file mode 100644
index 0000000000..4cf0ed51fe
--- /dev/null
+++ b/ext/gd/tests/bug73213.png
Binary files differ