Skip to content

Fix bug #79945: Stream wrappers in imagecreatefrompng causes segfault #12696

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions ext/gd/tests/bug79945.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
--TEST--
Bug #79945 (using php wrappers in imagecreatefrompng causes segmentation fault)
--EXTENSIONS--
gd
--SKIPIF--
<?php
set_error_handler(function($errno, $errstr) {
if (str_contains($errstr, 'Cannot cast a filtered stream on this system')) {
die('skip: fopencookie not support on this system');
}
});
imagecreatefrompng('php://filter/read=convert.base64-encode/resource=' . __DIR__ . '/test.png');
restore_error_handler();
?>
--FILE--
<?php
imagecreatefrompng('php://filter/read=convert.base64-encode/resource=' . __DIR__ . '/test.png');
?>
--CLEAN--
--EXPECTF--

Warning: imagecreatefrompng(): "php://filter/read=convert.base64-encode/resource=%s" is not a valid PNG file in %s on line %d
3 changes: 3 additions & 0 deletions main/php_streams.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ struct _php_stream {
* PHP_STREAM_FCLOSE_XXX as appropriate */
uint8_t fclose_stdiocast:2;

/* whether stdio cast flushing is in progress */
int8_t fclose_stdiocast_flush_in_progress:1;

char mode[16]; /* "rwb" etc. ala stdio */

uint32_t flags; /* PHP_STREAM_FLAG_XXX */
Expand Down
9 changes: 7 additions & 2 deletions main/streams/streams.c
Original file line number Diff line number Diff line change
Expand Up @@ -1294,8 +1294,13 @@ PHPAPI zend_off_t _php_stream_tell(php_stream *stream)
PHPAPI int _php_stream_seek(php_stream *stream, zend_off_t offset, int whence)
{
if (stream->fclose_stdiocast == PHP_STREAM_FCLOSE_FOPENCOOKIE) {
/* flush to commit data written to the fopencookie FILE* */
fflush(stream->stdiocast);
/* flush can call seek internally so we need to prevent an infinite loop */
if (!stream->fclose_stdiocast_flush_in_progress) {
stream->fclose_stdiocast_flush_in_progress = 1;
/* flush to commit data written to the fopencookie FILE* */
fflush(stream->stdiocast);
stream->fclose_stdiocast_flush_in_progress = 0;
}
}

/* handle the case where we are in the buffer */
Expand Down