PHP Bugs  
php.net | support | documentation | report a bug | advanced search | search howto | statistics | login

go to bug id or search bugs for  

Bug #24174 Seg. fault when calling imagecreatefromstring
Submitted:13 Jun 2003 8:33am UTC Modified: 16 Jun 2003 1:33pm UTC
From:legion at altlinux dot org Assigned to:
Status:Closed Category:GD related
Version:4.3.2 OS:ALTLinux
View/Vote Developer Edit Submission

[13 Jun 2003 8:33am UTC] legion at altlinux dot org
Description:
------------
Script segfaults when calling function imagecreatefromstring() with
built-in font. 

PHP version: 4.3.2 (cvs snapshot 20030609)
GD version: 2.0.4

Reproduce code:
---------------
$tmpfilename = tempnam ("/tmp", "FOO");
$im     = imagecreate(200, 100);
$black = imagecolorallocate ($im, 0, 0, 0);
$orange = imagecolorallocate($im, 220, 210, 60);
imagefill($im, 0, 0, $black);
$string = '::: Oops! :::';
imagestring($im, 3, 0, 10, $string, $orange);
imagejpeg($im, $tmpfilename);
imagedestroy($im);
$fp = fopen($tmpfilename, 'r');
while (!feof ($fp)) { $content .= fgets($fp, 4096); }
fclose($fp);
$img = imagecreatefromstring($content);
// following function will be work
// $img = imagecreatefromjpeg($tmpfilename);

header ("Content-type: image/jpeg");
imagejpeg($img);
imagedestroy($img);
unlink($tmpfilename);

Expected result:
----------------
Must be generate jpeg image. 

Actual result:
--------------
Segmentation fault
[13 Jun 2003 8:36am UTC] sniper@php.net
And what was the configure line you used to configure PHP?
(note: This does NOT crash for me)
[15 Jun 2003 11:57am UTC] legion at altlinux dot org
This was my configure command:
configure --with-gd=/usr --enable-gd-native-ttf --with-jpeg-dir=/usr
--with-xpm-dir=/usr/X11R6 --with-t1lib --with-ttf=/usr
--with-png-dir=/usr --with-zlib-dir=/usr --with-freetype-dir=/usr 

What is the version libgd do you use ? Maybe this is problem on my
side...
[15 Jun 2003 2:20pm UTC] derick@php.net
I would recomment to use the bundled GD library which you can enable by
using --with-gd (without path). Can you try that?
[15 Jun 2003 4:40pm UTC] sniper@php.net
And if you get the same segfault with --with-gd (ie. the bundled GD),
then provide a GDB backtrace.
[16 Jun 2003 11:49am UTC] legion at altlinux dot org
I did what you asked me. I even got computer for tests. I install last
version s of gd-2.0.15 and php4-STABLE-200306161530. When i use the
bundled GD library everything is ok, but if i use external GD then
happens segfault.
[16 Jun 2003 11:54am UTC] derick@php.net
There is the solution then, use the bundled library (which has some bugs
fixed the external one hasn't)
[16 Jun 2003 12:40pm UTC] legion at altlinux dot org
This is  not the solution at all. Then next bug is: i can't use function
imagegif() in your solution. Can i post it ?
[16 Jun 2003 1:00pm UTC] pajoye@php.net
<Then next bug is: i can't use function
imagegif() in your solution. Can i post it ?>

No, this is not a bug. Even Boutell does not support gif export.

I strongly suggest you to use only the bundled GD (and thinking about
alternatives for the gif format), its quality and its integration to php
is really better.

pierre
[16 Jun 2003 1:25pm UTC] legion at altlinux dot org
This is the official position of mantainers of this module ? You don't
support external GD library and use your own fork. Am i right ?
[16 Jun 2003 1:33pm UTC] rasmus@php.net
Not really, but what do you want us to do?  We can't fix segfaults in
3rd-party libraries.  Well, we can, we can fix them and redistribute
them, exactly like we are doing.  So either use the 3rd-party stuff and
hope you get one which doesn't segfault or use the one we bundle that we
have tested and fixed.
[3 Jul 2003 1:55am UTC] tim at sparkart dot com
I ran into this same issue and went and spent some time debugging it.

Here is the backtrace:

#0  0x40359f9d in _int_free () from /lib/libc.so.6
#1  0x40358dda in free () from /lib/libc.so.6
#2  0x400c3e3f in gdFree (ptr=0x8224114) at gdhelpers.c:100
#3  0x400bae28 in gdFreeDynamicCtx (ctx=0x8224114) at gd_io_dp.c:154
#4  0x0806dcaa in _php_image_create_from_string (data=0x82105c4,
tn=0x81922e2 "JPEG", 
    ioctx_func_p=0x806433c <gdImageCreateFromJpegCtx>) at
/usr/local/build/php-4.3.2/ext/gd/gd.c:1286
#5  0x0806de1f in zif_imagecreatefromstring (ht=1,
return_value=0x8215ed4, this_ptr=0x0, return_value_used=1)
    at /usr/local/build/php-4.3.2/ext/gd/gd.c:1315
#6  0x08189f24 in execute (op_array=0x8216074) at
/usr/local/build/php-4.3.2/Zend/zend_execute.c:1606
#7  0x0817838c in zend_execute_scripts (type=8, retval=0x0,
file_count=3) at /usr/local/build/php-4.3.2/Zend/zend.c:869
#8  0x081442d3 in php_execute_script (primary_file=0xbffff830) at
/usr/local/build/php-4.3.2/main/main.c:1671
#9  0x081908dc in main (argc=2, argv=0xbffff8e4) at
/usr/local/build/php-4.3.2/sapi/cgi/cgi_main.c:1501
#10 0x402fadc4 in __libc_start_main () from /lib/libc.so.6

It looks like the cause of the seg fault is the GD library (I used
gd-2.0.15gif) trying to free some of the memory that php is using. 
Specifically php's pointer to the image data.

So the work around was to null out the data pointer on php's side before
it made its call to GD to free up stuff it was using.

Details:

The call made from php that eventually causes the seg fault is in
ext/gd/gd.c around line 1284 in the _php_image_create_from_string
function:

io_ctx->gd_free(io_ctx);

This calls the gdFreeDynamicCtx function in gd_io_dp.c (line 141 in my
copy).

To null out the data pointer contained under the io_ctx variables to
prevent GD from trying to free the memory I added the following above
the gd_free call:

**((void***)(io_ctx+1)) = NULL;

Its kinda messy since we don't have access to any of the GD structs. 
The equivalent code on the GD side of things, for example in the
gdFreeDynamicCtx function, would be something like:

((dynamicPtr*)((dpIOCtx*)ctx)->dp)->data = NULL;

Here is what the whole section of code in ext/gd/gd.c looks like (in my
copy):

...
        if (!im) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Passed data
is not in '%s' format", tn);
                return NULL;
        }
        // tp - 7/2/2003  - we don't want gd trying to free() our data
        **((void***)(io_ctx+1)) = NULL;
#if HAVE_LIBGD204
        io_ctx->gd_free(io_ctx);
#else
        io_ctx->free(io_ctx);
#endif
...

PHP's built in Gd library doesn't try to free the PHP's data so this
work around shouldn't effect any of the built in stuff (assuming the
structs have the same layouts).

RSS feed | show source 

PHP Copyright © 2001-2009 The PHP Group
All rights reserved.
Last updated: Sat Nov 21 10:30:49 2009 UTC