diff --git a/ext/gd/tests/bug79945.phpt b/ext/gd/tests/bug79945.phpt new file mode 100644 index 0000000000000..b985ddd48be31 --- /dev/null +++ b/ext/gd/tests/bug79945.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #79945 (using php wrappers in imagecreatefrompng causes segmentation fault) +--EXTENSIONS-- +gd +--SKIPIF-- + +--FILE-- + +--CLEAN-- +--EXPECTF-- + +Warning: imagecreatefrompng(): "php://filter/read=convert.base64-encode/resource=%s" is not a valid PNG file in %s on line %d diff --git a/main/php_streams.h b/main/php_streams.h index e7cbc7369ed45..0837472d2f6b9 100644 --- a/main/php_streams.h +++ b/main/php_streams.h @@ -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 */ diff --git a/main/streams/streams.c b/main/streams/streams.c index 4cd211ad85fe5..e1399927b2783 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -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 */