diff --git a/NEWS b/NEWS index 0602993d5c6..7dbd6504689 100644 --- a/NEWS +++ b/NEWS @@ -38,6 +38,10 @@ PHP NEWS . Fix segfault and assertion failure with refcounted props and arrays. (nielsdos) +- Streams: + . Fixed bug #75708 (getimagesize with "&$imageinfo" fails on StreamWrappers). + (Jakub Zelenka) + - XSL: . Add missing module dependency. (nielsdos) diff --git a/ext/standard/image.c b/ext/standard/image.c index 7375d75fc64..d5455963f31 100644 --- a/ext/standard/image.c +++ b/ext/standard/image.c @@ -394,6 +394,20 @@ static int php_skip_variable(php_stream * stream) } /* }}} */ +static size_t php_read_stream_all_chunks(php_stream *stream, char *buffer, size_t length) +{ + size_t read_total = 0; + do { + ssize_t read_now = php_stream_read(stream, buffer, length - read_total); + read_total += read_now; + if (read_now < stream->chunk_size && read_total != length) { + return 0; + } + } while (read_total < length); + + return read_total; +} + /* {{{ php_read_APP */ static int php_read_APP(php_stream * stream, unsigned int marker, zval *info) { @@ -410,7 +424,7 @@ static int php_read_APP(php_stream * stream, unsigned int marker, zval *info) buffer = emalloc(length); - if (php_stream_read(stream, buffer, (size_t) length) != length) { + if (php_read_stream_all_chunks(stream, buffer, length) != length) { efree(buffer); return 0; } diff --git a/ext/standard/tests/image/bug75708.jpg b/ext/standard/tests/image/bug75708.jpg new file mode 100644 index 00000000000..26cb754fab1 Binary files /dev/null and b/ext/standard/tests/image/bug75708.jpg differ diff --git a/ext/standard/tests/image/bug75708.phpt b/ext/standard/tests/image/bug75708.phpt new file mode 100644 index 00000000000..956a99b6af6 --- /dev/null +++ b/ext/standard/tests/image/bug75708.phpt @@ -0,0 +1,56 @@ +--TEST-- +Bug #75708 (getimagesize with "&$imageinfo" fails on StreamWrappers) +--FILE-- +handle = fopen(str_replace('fs://', __DIR__ . '/', $file), $mode); + return true; + } + function stream_read($count) { + return fread($this->handle, $count); + } + function stream_eof() { + return feof($this->handle); + } + function stream_seek($offset, $whence) { + return fseek($this->handle, $offset, $whence) === 0; + } + function stream_stat() { + return fstat($this->handle); + } + function url_stat($file) { + return stat(str_replace('fs://', '', $file)); + } + function stream_tell() { + return ftell($this->handle); + } + function stream_close() { + fclose($this->handle); + } +} + +stream_register_wrapper('fs', 'FSStreamWrapper'); + +var_dump(getimagesize('fs://bug75708.jpg', $info)); + +?> +--EXPECT-- +array(7) { + [0]=> + int(10) + [1]=> + int(10) + [2]=> + int(2) + [3]=> + string(22) "width="10" height="10"" + ["bits"]=> + int(8) + ["channels"]=> + int(3) + ["mime"]=> + string(10) "image/jpeg" +} +