php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #45905 imagefilledrectangle() clipping error
Submitted: 2008-08-24 22:06 UTC Modified: 2009-07-07 11:08 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: markril at hotmail dot com Assigned: pajoye (profile)
Status: Closed Package: GD related
PHP Version: 5.2.6 OS: *
Private report: No CVE-ID: None
 [2008-08-24 22:06 UTC] markril at hotmail dot com
Description:
------------
When using the GD library to render rectangles, certain rectangles
outside the rendering surface are not clipped properly.  Rectangles
with all negative coords will sometimes render pixels on the surface.
Also, if the coords are large enough (positive and/or negative) the
rendering time increases dramatically when no rectangle should be
visible.  See the attached reproduce code for an example script.

See below for a fix in the GD code.

Reproduce code:
---------------
<?php

$img = imagecreatetruecolor(100, 100);

$gray = imagecolorallocate($img, 192, 192, 192);
$red = imagecolorallocate($img, 255, 0, 0);

imagefilledrectangle($img, 0, 0, 99, 99, $gray);

// The following call should be clipped and not affect the
// the light gray 100x100 rectangle, but it plots a red pixel
// at (0,0) and causes the image generation time to skyrocket
// (at least on my slow server).  You can make the coords more
// negative to increase the time if your server is fast.
// Comment out this line and the delay and pixel go away.
imagefilledrectangle($img, -30010, -30010, -30000, -30000, $red);

header("Content-type: image/png");
imagepng($img);

?>


Expected result:
----------------
Rectangles outside the rendering surface should be clipped.

Actual result:
--------------
Rectangles outside the rendering surface sometimes leave stray pixels
on the rendering surface.  Also, time needed to render the image can
skyrocket when large rectangle coords are used (shouldn't take
virtually any time since no rendering should be going on).

I looked in the GD source code and found the bug in the clipping
logic for the gdImageFilledRectangle function.  Below is my fixed
and tested version.  It also now allows the points to be specified
in any order like imagerectangle() permits.

// from ext/gd/libgd/gd.c:

void gdImageFilledRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
{
	int x, y;

	if (x1 > x2) {
		x = x1;
		x1 = x2;
		x2 = x;
	}
	if (y1 > y2) {
		y = y1;
		y1 = y2;
		y2 = y;
	}
	if (x1 < 0) {
		x1 = 0;
	}
	if (x2 >= gdImageSX(im)) {
		x2 = gdImageSX(im) - 1;
	}
	if (y1 < 0) {
		y1 = 0;
	}
	if (y2 >= gdImageSY(im)) {
		y2 = gdImageSY(im) - 1;
	}

	for (y = y1; y <= y2; y++) {
		for (x = x1; x <= x2; x++) {
			gdImageSetPixel (im, x, y, color);
		}
	}
}

I was at the www.libgd.org site and the last release candidate was
Nov '07 and I'm not sure if GD is being supported there anymore so
I posted this code here for now.


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-08-25 05:10 UTC] pajoye@php.net
> I was at the www.libgd.org site and the last release candidate was
> Nov '07 and I'm not sure if GD is being supported there anymore so
> I posted this code here for now.

The last stable release was in November and it is stable supported (see the commits and discussions).

 [2009-07-07 11:08 UTC] pajoye@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 16:01:28 2024 UTC