From: markril at hotmail dot com Operating system: debian/any PHP version: 5.2.6 PHP Bug Type: GD related Bug description: imagefilledrectangle() clipping error
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. -- Edit bug report at http://bugs.php.net/?id=45905&edit=1 -- Try a CVS snapshot (PHP 5.2): http://bugs.php.net/fix.php?id=45905&r=trysnapshot52 Try a CVS snapshot (PHP 5.3): http://bugs.php.net/fix.php?id=45905&r=trysnapshot53 Try a CVS snapshot (PHP 6.0): http://bugs.php.net/fix.php?id=45905&r=trysnapshot60 Fixed in CVS: http://bugs.php.net/fix.php?id=45905&r=fixedcvs Fixed in release: http://bugs.php.net/fix.php?id=45905&r=alreadyfixed Need backtrace: http://bugs.php.net/fix.php?id=45905&r=needtrace Need Reproduce Script: http://bugs.php.net/fix.php?id=45905&r=needscript Try newer version: http://bugs.php.net/fix.php?id=45905&r=oldversion Not developer issue: http://bugs.php.net/fix.php?id=45905&r=support Expected behavior: http://bugs.php.net/fix.php?id=45905&r=notwrong Not enough info: http://bugs.php.net/fix.php?id=45905&r=notenoughinfo Submitted twice: http://bugs.php.net/fix.php?id=45905&r=submittedtwice register_globals: http://bugs.php.net/fix.php?id=45905&r=globals PHP 4 support discontinued: http://bugs.php.net/fix.php?id=45905&r=php4 Daylight Savings: http://bugs.php.net/fix.php?id=45905&r=dst IIS Stability: http://bugs.php.net/fix.php?id=45905&r=isapi Install GNU Sed: http://bugs.php.net/fix.php?id=45905&r=gnused Floating point limitations: http://bugs.php.net/fix.php?id=45905&r=float No Zend Extensions: http://bugs.php.net/fix.php?id=45905&r=nozend MySQL Configuration Error: http://bugs.php.net/fix.php?id=45905&r=mysqlcfg