Streams segfault
| From: | Rasmus Lerdorf | Date: | Fri, 23 Aug 2002 17:39:18 +0000 |
| Subject: | Streams segfault | ||
| Groups: | php.dev | ||
| Request: | Send a blank email to php-dev+get-87357@lists.php.net to get a copy of this message | ||
Wez, this looks like a streams related problem. On Linux, when using the
streams open_wrapper to open a file and that file is actually a directory
we get a segfault that looks like this:
Program received signal SIGSEGV, Segmentation fault.
0x4032abb8 in _php_stream_eof (stream=0x819b25c) at /home/rasmus/php4/main/streams.c:323
323 return stream->filterhead->fops->eof(stream, stream->filterhead TSRMLS_CC);
(gdb) bt
#0 0x4032abb8 in _php_stream_eof (stream=0x819b25c) at /home/rasmus/php4/main/streams.c:323
#1 0x40211baf in zif_imageloadfont (ht=1, return_value=0x819b0f4, this_ptr=0x0,
return_value_used=0) at /home/rasmus/php4/ext/gd/gd.c:519
#2 0x40366cb1 in execute (op_array=0x819afbc) at /home/rasmus/php4/Zend/zend_execute.c:1591
#3 0x403554c4 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at
/home/rasmus/php4/Zend/zend.c:812
#4 0x403204fa in php_execute_script (primary_file=0xbffff520) at /home/rasmus/php4/main/main.c:1524
#5 0x4036bc86 in apache_php_module_main (r=0x8191084, display_source_mode=0) at
/home/rasmus/php4/sapi/apache/sapi_apache.c:55
#6 0x4036cb68 in send_php (r=0x8191084, display_source_mode=0, filename=0x8191b94
"/home/rasmus/phpweb/foo.php")
at /home/rasmus/php4/sapi/apache/mod_php4.c:563
#7 0x4036cbd5 in send_parsed_php (r=0x8191084) at /home/rasmus/php4/sapi/apache/mod_php4.c:578
#8 0x0806a53f in ap_invoke_handler ()
#9 0x0807e71f in process_request_internal ()
#10 0x0807e780 in ap_process_request ()
#11 0x08075be9 in child_main ()
#12 0x08075d94 in make_child ()
#13 0x08075f08 in startup_children ()
#14 0x08076580 in standalone_main ()
#15 0x08076dd3 in main ()
#16 0x400b51c4 in __libc_start_main () from /lib/libc.so.6
(gdb) p *stream
$1 = {ops = 0x5a5a5a5a, abstract = 0x5a5a5a5a, filterhead = 0x5a5a5a5a, filtertail = 0x5a5a5a5a,
wrapper = 0x5a5a5a5a,
wrapperthis = 0x5a5a5a5a, wrapperdata = 0x5a5a5a5a, fgetss_state = 1515870810, is_persistent =
1515870810, mode = 'Z' <repeats 16 times>,
rsrc_id = 1515870810, in_free = 1515870810, fclose_stdiocast = 1515870810, stdiocast = 0x5a5a5a5a,
__exposed = 1515870810,
__orig_path = 0x5a5a5a5a "", context = 0x5a5a5a5a}
(gdb) p *stream->filterhead
$3 = {fops = 0x0, abstract = 0x0, next = 0x0, prev = 0x0, is_persistent = 0, stream = 0x0}
and hence the segfault.
This comes from some code in gd.c that looks like this:
stream = php_stream_open_wrapper(Z_STRVAL_PP(file), "rb",
IGNORE_PATH|IGNORE_URL_WIN|REPORT_ERRORS, NULL);
if (stream == NULL) {
RETURN_FALSE;
}
font = (gdFontPtr)emalloc(sizeof(gdFont));
b = 0;
while (b < hdr_size && (n = php_stream_read(stream, (char*)&font[b], hdr_size -
b)))
b += n;
if (!n) {
php_stream_close(stream);
efree(font);
if (php_stream_eof(stream)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "End of file while reading
header");
Segfault is on the php_stream_eof() call.
Not quite sure whose job it is to check whether the file to be opened is
actually a file. Or whether we even want to. Let them open whatever they
want and they will get garbage, but we need to avoid the segfault.
To reproduce, use this one-line script:
<?
imageloadfont("foo");
?>
And do a "mkdir foo" in the directory.
-Rasmus