From 6499581af76cfe986e12330faabb3a7c36d45ffc Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" 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 033d4fa5f0..058f1c9759 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 0000000000..548921d559 --- /dev/null +++ b/ext/gd/tests/bug72482.phpt @@ -0,0 +1,19 @@ +--TEST-- +Bug #72482 (Ilegal write/read access caused by gdImageAALine overflow) +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECT-- +===DONE=== diff --git a/ext/gd/tests/bug72482_2.phpt b/ext/gd/tests/bug72482_2.phpt new file mode 100644 index 0000000000..a8a08faa53 --- /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-- + +--FILE-- + +===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#rbwx%Q+LSt4~FDm5STuC3UQR@LXL*{D`QWfb@-- RCx8Yqc)I$ztaD0e0s!PaBk2GD literal 0 HcmV?d00001 -- 2.40.0