Skip to content

Commit 7ecfb65

Browse files
janoHhvm Bot
authored and
Hhvm Bot
committed
Fix some color related crashes in libgd
Summary: Various paths use the color as an index into a 256 element table without checking it, and passing -7 as a color to imageline would unconditionally cause it to treat the image as truecolor, seg-faulting if it wasn't. Reviewed By: alexmalyshev Differential Revision: D3658241 fbshipit-source-id: 0f4a9f32dce0a733b5749451b239badd0bfc4d49
1 parent 1112060 commit 7ecfb65

File tree

7 files changed

+30
-4
lines changed

7 files changed

+30
-4
lines changed

hphp/runtime/ext/gd/ext_gd.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3921,9 +3921,8 @@ Variant HHVM_FUNCTION(imagecolorsforindex, const Resource& image,
39213921
int64_t index) {
39223922
gdImagePtr im = get_valid_image_resource(image);
39233923
if (!im) return false;
3924-
if ((index >= 0 && gdImageTrueColor(im)) ||
3925-
(!gdImageTrueColor(im) && index >= 0 &&
3926-
index < gdImageColorsTotal(im))) {
3924+
if (index >= 0 &&
3925+
(gdImageTrueColor(im) || index < gdImageColorsTotal(im))) {
39273926
return make_map_array(
39283927
s_red, gdImageRed(im,index),
39293928
s_green, gdImageGreen(im,index),

hphp/runtime/ext/gd/libgd/gd.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,6 +1017,12 @@ void gdImageAABlend (gdImagePtr im)
10171017
int p_color, p_red, p_green, p_blue;
10181018
int px, py;
10191019

1020+
if (!gdImageTrueColor(im) && color >= gdImageColorsTotal(im)) {
1021+
color = gdImageColorsTotal(im) - 1;
1022+
}
1023+
if (color < 0) {
1024+
color = 0;
1025+
}
10201026
color_red = gdImageRed(im, color);
10211027
color_green = gdImageGreen(im, color);
10221028
color_blue = gdImageBlue(im, color);
@@ -1290,6 +1296,8 @@ inline static void gdImageSetAAPixelColor(gdImagePtr im, int x, int y, int color
12901296
**/
12911297
void gdImageAALine (gdImagePtr im, int x1, int y1, int x2, int y2, int col)
12921298
{
1299+
if (!gdImageTrueColor(im)) return;
1300+
12931301
/* keep them as 32bits */
12941302
long x, y, inc;
12951303
long dx, dy,tmp;

hphp/runtime/ext/gd/libgd/gd_crop.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,10 @@ gdImagePtr gdImageCropThreshold(gdImagePtr im, const unsigned int color,
238238
return nullptr;
239239
}
240240

241+
if (!gdImageTrueColor(im) && color > gdImageColorsTotal(im)) {
242+
return nullptr;
243+
}
244+
241245
/* TODO: Add gdImageGetRowPtr and works with ptr at the row level
242246
* for the true color and palette images
243247
* new formats will simply work with ptr

hphp/runtime/ext/gd/libgd/gd_gd2.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,10 +666,12 @@ static void _gdImageGd2 (gdImagePtr im, gdIOCtx * out, int cs, int fmt)
666666

667667
/* Force fmt to a valid value since we don't return anything. */
668668
if ((fmt != GD2_FMT_RAW) && (fmt != GD2_FMT_COMPRESSED)) {
669-
fmt = im->trueColor ? GD2_FMT_TRUECOLOR_COMPRESSED : GD2_FMT_COMPRESSED;
669+
fmt = GD2_FMT_COMPRESSED;
670670
}
671671
if (im->trueColor) {
672672
fmt += 2;
673+
assert(fmt == GD2_FMT_TRUECOLOR_RAW ||
674+
fmt == GD2_FMT_TRUECOLOR_COMPRESSED);
673675
}
674676
/* Make sure chunk size is valid. These are arbitrary values; 64 because it seems
675677
* a little silly to expect performance improvements on a 64x64 bit scale, and

hphp/runtime/ext/gd/libgd/gd_topal.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,6 +1818,10 @@ static void gdImageTrueColorToPaletteBody (gdImagePtr oim, int dither, int color
18181818
{
18191819
colorsWanted = maxColors;
18201820
}
1821+
if (colorsWanted <= 0) {
1822+
colorsWanted = 1;
1823+
}
1824+
18211825
if (!cimP) {
18221826
nim->pixels = (unsigned char **) gdCalloc (sizeof (unsigned char *), oim->sy);
18231827
if (!nim->pixels)

hphp/test/slow/ext_gd/colorcrash.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
$img=imagecreatetruecolor(10, 10);
3+
imagetruecolortopalette($img, false, PHP_INT_MAX / 8);
4+
5+
$img = imagecreate(100, 100);
6+
imageline($img, 0, 0, 100, 100, -7);
7+
imagepolygon($img, array(10,10,10,50,50,50,50,10,10,10), 5, -7);
8+
echo "done\n";
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
done

0 commit comments

Comments
 (0)