php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #72482
Patch fix-72482 revision 2016-10-25 14:10 UTC by cmb@php.net

Patch fix-72482 for GD related Bug #72482

Patch version 2016-10-25 14:10 UTC

Return to Bug #72482 | Download this patch
Patch Revisions:

Developer: cmb@php.net

From 564173205e350308055889340a3a8d0f4bc4db6b Mon Sep 17 00:00:00 2001
From: "Christoph M. Becker" <cmbecker69@gmx.de>
Date: Tue, 25 Oct 2016 15:14:22 +0200
Subject: [PATCH] Fix #72482: Ilegal write/read access caused by gdImageAALine
 overflow

Instead of rolling our own bounds check we use clip_1d() as it's done
in gdImageLine() and in external libgd. We must not pass the image
width and height, respectively, but rather the largest ordinate value
that is allowed to be accessed, i.e. width-1 and height-1,
respectively.
---
 ext/gd/libgd/gd.c            |  51 +++----------------------------------------
 ext/gd/tests/bug72482.phpt   |  19 ++++++++++++++++
 ext/gd/tests/bug72482_2.phpt |  21 ++++++++++++++++++
 ext/gd/tests/bug72482_2.png  | Bin 0 -> 118 bytes
 4 files changed, 43 insertions(+), 48 deletions(-)
 create mode 100644 ext/gd/tests/bug72482.phpt
 create mode 100644 ext/gd/tests/bug72482_2.phpt
 create mode 100644 ext/gd/tests/bug72482_2.png

diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c
index 033d4fa..058f1c9 100644
--- a/ext/gd/libgd/gd.c
+++ b/ext/gd/libgd/gd.c
@@ -1117,7 +1117,7 @@ void gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
 	}
 
 	/* 2.0.10: Nick Atty: clip to edges of drawing rectangle, return if no points need to be drawn */
-	if (!clip_1d(&x1,&y1,&x2,&y2,gdImageSX(im)) || !clip_1d(&y1,&x1,&y2,&x2,gdImageSY(im))) {
+	if (!clip_1d(&x1,&y1,&x2,&y2,gdImageSX(im)-1) || !clip_1d(&y1,&x1,&y2,&x2,gdImageSY(im)-1)) {
 		return;
 	}
 
@@ -1301,55 +1301,10 @@ void gdImageAALine (gdImagePtr im, int x1, int y1, int x2, int y2, int col)
 	long x, y, inc, frac;
 	long dx, dy,tmp;
 
-	if (y1 < 0 && y2 < 0) {
-		return;
-	}
-	if (y1 < 0) {
-		x1 += (y1 * (x1 - x2)) / (y2 - y1);
-		y1 = 0;
-	}
-	if (y2 < 0) {
-		x2 += (y2 * (x1 - x2)) / (y2 - y1);
-		y2 = 0;
-	}
-
-	/* bottom edge */
-	if (y1 >= im->sy && y2 >= im->sy) {
-		return;
-	}
-	if (y1 >= im->sy) {
-		x1 -= ((im->sy - y1) * (x1 - x2)) / (y2 - y1);
-		y1 = im->sy - 1;
-	}
-	if (y2 >= im->sy) {
-		x2 -= ((im->sy - y2) * (x1 - x2)) / (y2 - y1);
-		y2 = im->sy - 1;
-	}
-
-	/* left edge */
-	if (x1 < 0 && x2 < 0) {
-		return;
-	}
-	if (x1 < 0) {
-		y1 += (x1 * (y1 - y2)) / (x2 - x1);
-		x1 = 0;
-	}
-	if (x2 < 0) {
-		y2 += (x2 * (y1 - y2)) / (x2 - x1);
-		x2 = 0;
-	}
-	/* right edge */
-	if (x1 >= im->sx && x2 >= im->sx) {
+	/* 2.0.10: Nick Atty: clip to edges of drawing rectangle, return if no points need to be drawn */
+	if (!clip_1d(&x1,&y1,&x2,&y2,gdImageSX(im)-1) || !clip_1d(&y1,&x1,&y2,&x2,gdImageSY(im)-1)) {
 		return;
 	}
-	if (x1 >= im->sx) {
-		y1 -= ((im->sx - x1) * (y1 - y2)) / (x2 - x1);
-		x1 = im->sx - 1;
-	}
-	if (x2 >= im->sx) {
-		y2 -= ((im->sx - x2) * (y1 - y2)) / (x2 - x1);
-		x2 = im->sx - 1;
-	}
 
 	dx = x2 - x1;
 	dy = y2 - y1;
diff --git a/ext/gd/tests/bug72482.phpt b/ext/gd/tests/bug72482.phpt
new file mode 100644
index 0000000..ac92077
--- /dev/null
+++ b/ext/gd/tests/bug72482.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Bug #72482 (Ilegal write/read access caused by gdImageAALine overflow)
+--SKIPIF--
+<?php
+if (!extension_loaded('gd')) die('skip gd extension not available');
+?>
+--FILE--
+<?php
+$img = imagecreatetruecolor(13, 1007);
+imageantialias($img, true);
+imageline($img, 0, 0, 1073745919, 1073745919, 4096);
+
+$img = imagecreatetruecolor(100, 100);
+imageantialias($img, true);
+imageline($img, 1094795585, 0, 2147483647, 255, 0xff);
+?>
+===DONE===
+--EXPECT--
+===DONE===
diff --git a/ext/gd/tests/bug72482_2.phpt b/ext/gd/tests/bug72482_2.phpt
new file mode 100644
index 0000000..9836884
--- /dev/null
+++ b/ext/gd/tests/bug72482_2.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Bug 72482 (Ilegal write/read access caused by gdImageAALine overflow)
+--SKIPIF--
+<?php
+if (!extension_loaded('gd')) die('skip gd extension not available');
+?>
+--FILE--
+<?php
+require_once __DIR__ . DIRECTORY_SEPARATOR . 'func.inc';
+
+$im = imagecreatetruecolor(10, 10);
+imagefilledrectangle($im, 0, 0, 9, 9, imagecolorallocate($im, 255, 255, 255));
+imageantialias($im, true);
+imageline($im, 0, 0, 10, 10, imagecolorallocate($im, 0, 0, 0));
+
+test_image_equals_file(__DIR__ . DIRECTORY_SEPARATOR . 'bug72482_2.png', $im);
+?>
+===DONE===
+--EXPECT--
+The images are equal.
+===DONE===
diff --git a/ext/gd/tests/bug72482_2.png b/ext/gd/tests/bug72482_2.png
new file mode 100644
index 0000000000000000000000000000000000000000..da90b2a2670cfd245674894361fcafe868e2bae4
GIT binary patch
literal 118
zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V6Od#Ih<F90Y&~5ZLnNlwUNGciP~c!bu<if<
zVp$&^rKzkQ{j5wIdIL838Xfy>#rbwx%Q+LSt4~FDm5STuC3UQR@LXL*{D`QWfb@--
RCx8Yqc)I$ztaD0e0s!PaBk2GD

literal 0
HcmV?d00001

-- 
2.8.1.windows.1

 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Thu Jun 22 18:02:00 2017 UTC