mirror of
https://github.com/php/php-src.git
synced 2025-08-16 14:08:47 +02:00
Fixed bug #47997 (stream_copy_to_stream returns 1 on empty streams)
This commit is contained in:
parent
0c6cf02985
commit
14c717f449
6 changed files with 53 additions and 14 deletions
1
NEWS
1
NEWS
|
@ -12,6 +12,7 @@ PHP NEWS
|
||||||
disable this behaviour using "http"=>array("auto_decode"=>0) in stream
|
disable this behaviour using "http"=>array("auto_decode"=>0) in stream
|
||||||
context. (Dmitry)
|
context. (Dmitry)
|
||||||
|
|
||||||
|
- Fixed bug #47997 (stream_copy_to_stream returns 1 on empty streams). (Arnaud)
|
||||||
- Fixed bug #47880 (crashes in call_user_func_array()). (Dmitry)
|
- Fixed bug #47880 (crashes in call_user_func_array()). (Dmitry)
|
||||||
- Fixed bug #47856 (stristr() converts needle to lower-case). (Ilia)
|
- Fixed bug #47856 (stristr() converts needle to lower-case). (Ilia)
|
||||||
- Fixed bug #47851 (is_callable throws fatal error). (Dmitry)
|
- Fixed bug #47851 (is_callable throws fatal error). (Dmitry)
|
||||||
|
|
|
@ -627,7 +627,10 @@ PHP_FUNCTION(file_put_contents)
|
||||||
|
|
||||||
switch (Z_TYPE_P(data)) {
|
switch (Z_TYPE_P(data)) {
|
||||||
case IS_RESOURCE:
|
case IS_RESOURCE:
|
||||||
numbytes = php_stream_copy_to_stream(srcstream, stream, PHP_STREAM_COPY_ALL);
|
numbytes = (int) php_stream_copy_to_stream_ex(srcstream, stream, PHP_STREAM_COPY_ALL);
|
||||||
|
if ((size_t)numbytes == PHP_STREAM_FAILURE) {
|
||||||
|
numbytes = -1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case IS_NULL:
|
case IS_NULL:
|
||||||
case IS_LONG:
|
case IS_LONG:
|
||||||
|
@ -1783,7 +1786,7 @@ safe_to_copy:
|
||||||
deststream = php_stream_open_wrapper(dest, "wb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL);
|
deststream = php_stream_open_wrapper(dest, "wb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL);
|
||||||
|
|
||||||
if (srcstream && deststream) {
|
if (srcstream && deststream) {
|
||||||
ret = php_stream_copy_to_stream(srcstream, deststream, PHP_STREAM_COPY_ALL) == 0 ? FAILURE : SUCCESS;
|
ret = php_stream_copy_to_stream_ex(srcstream, deststream, PHP_STREAM_COPY_ALL) == PHP_STREAM_FAILURE ? FAILURE : SUCCESS;
|
||||||
}
|
}
|
||||||
if (srcstream) {
|
if (srcstream) {
|
||||||
php_stream_close(srcstream);
|
php_stream_close(srcstream);
|
||||||
|
|
|
@ -443,6 +443,7 @@ PHP_FUNCTION(stream_copy_to_stream)
|
||||||
php_stream *src, *dest;
|
php_stream *src, *dest;
|
||||||
zval *zsrc, *zdest;
|
zval *zsrc, *zdest;
|
||||||
long maxlen = PHP_STREAM_COPY_ALL, pos = 0;
|
long maxlen = PHP_STREAM_COPY_ALL, pos = 0;
|
||||||
|
size_t ret;
|
||||||
|
|
||||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr|ll", &zsrc, &zdest, &maxlen, &pos) == FAILURE) {
|
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr|ll", &zsrc, &zdest, &maxlen, &pos) == FAILURE) {
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
|
@ -456,7 +457,12 @@ PHP_FUNCTION(stream_copy_to_stream)
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
RETURN_LONG(php_stream_copy_to_stream(src, dest, maxlen));
|
ret = php_stream_copy_to_stream_ex(src, dest, maxlen);
|
||||||
|
|
||||||
|
if (ret == PHP_STREAM_FAILURE) {
|
||||||
|
RETURN_FALSE;
|
||||||
|
}
|
||||||
|
RETURN_LONG(ret);
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
|
@ -420,9 +420,14 @@ END_EXTERN_C()
|
||||||
* Uses mmap if the src is a plain file and at offset 0 */
|
* Uses mmap if the src is a plain file and at offset 0 */
|
||||||
#define PHP_STREAM_COPY_ALL ((size_t)-1)
|
#define PHP_STREAM_COPY_ALL ((size_t)-1)
|
||||||
|
|
||||||
|
#define PHP_STREAM_FAILURE ((size_t)-1)
|
||||||
|
|
||||||
BEGIN_EXTERN_C()
|
BEGIN_EXTERN_C()
|
||||||
|
ZEND_ATTRIBUTE_DEPRECATED
|
||||||
PHPAPI size_t _php_stream_copy_to_stream(php_stream *src, php_stream *dest, size_t maxlen STREAMS_DC TSRMLS_DC);
|
PHPAPI size_t _php_stream_copy_to_stream(php_stream *src, php_stream *dest, size_t maxlen STREAMS_DC TSRMLS_DC);
|
||||||
#define php_stream_copy_to_stream(src, dest, maxlen) _php_stream_copy_to_stream((src), (dest), (maxlen) STREAMS_CC TSRMLS_CC)
|
#define php_stream_copy_to_stream(src, dest, maxlen) _php_stream_copy_to_stream((src), (dest), (maxlen) STREAMS_CC TSRMLS_CC)
|
||||||
|
PHPAPI size_t _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size_t maxlen STREAMS_DC TSRMLS_DC);
|
||||||
|
#define php_stream_copy_to_stream_ex(src, dest, maxlen) _php_stream_copy_to_stream_ex((src), (dest), (maxlen) STREAMS_CC TSRMLS_CC)
|
||||||
|
|
||||||
|
|
||||||
/* read all data from stream and put into a buffer. Caller must free buffer when done.
|
/* read all data from stream and put into a buffer. Caller must free buffer when done.
|
||||||
|
|
|
@ -214,9 +214,9 @@ PHPAPI int _php_stream_cast(php_stream *stream, int castas, void **ret, int show
|
||||||
|
|
||||||
newstream = php_stream_fopen_tmpfile();
|
newstream = php_stream_fopen_tmpfile();
|
||||||
if (newstream) {
|
if (newstream) {
|
||||||
size_t copied = php_stream_copy_to_stream(stream, newstream, PHP_STREAM_COPY_ALL);
|
size_t copied = php_stream_copy_to_stream_ex(stream, newstream, PHP_STREAM_COPY_ALL);
|
||||||
|
|
||||||
if (copied == 0) {
|
if (copied == PHP_STREAM_FAILURE) {
|
||||||
php_stream_close(newstream);
|
php_stream_close(newstream);
|
||||||
} else {
|
} else {
|
||||||
int retcode = php_stream_cast(newstream, castas | flags, ret, show_err);
|
int retcode = php_stream_cast(newstream, castas | flags, ret, show_err);
|
||||||
|
@ -332,7 +332,7 @@ PHPAPI int _php_stream_make_seekable(php_stream *origstream, php_stream **newstr
|
||||||
(*newstream)->open_lineno = origstream->open_lineno;
|
(*newstream)->open_lineno = origstream->open_lineno;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (php_stream_copy_to_stream(origstream, *newstream, PHP_STREAM_COPY_ALL) == 0) {
|
if (php_stream_copy_to_stream_ex(origstream, *newstream, PHP_STREAM_COPY_ALL) == PHP_STREAM_FAILURE) {
|
||||||
php_stream_close(*newstream);
|
php_stream_close(*newstream);
|
||||||
*newstream = NULL;
|
*newstream = NULL;
|
||||||
return PHP_STREAM_CRITICAL;
|
return PHP_STREAM_CRITICAL;
|
||||||
|
|
|
@ -1297,7 +1297,8 @@ PHPAPI size_t _php_stream_copy_to_mem(php_stream *src, char **buf, size_t maxlen
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
PHPAPI size_t _php_stream_copy_to_stream(php_stream *src, php_stream *dest, size_t maxlen STREAMS_DC TSRMLS_DC)
|
/* Returns the number of bytes moved, or PHP_STREAM_FAILURE on failure. */
|
||||||
|
PHPAPI size_t _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size_t maxlen STREAMS_DC TSRMLS_DC)
|
||||||
{
|
{
|
||||||
char buf[CHUNK_SIZE];
|
char buf[CHUNK_SIZE];
|
||||||
size_t readchunk;
|
size_t readchunk;
|
||||||
|
@ -1314,8 +1315,6 @@ PHPAPI size_t _php_stream_copy_to_stream(php_stream *src, php_stream *dest, size
|
||||||
}
|
}
|
||||||
|
|
||||||
if (php_stream_stat(src, &ssbuf) == 0) {
|
if (php_stream_stat(src, &ssbuf) == 0) {
|
||||||
/* in the event that the source file is 0 bytes, return 1 to indicate success
|
|
||||||
* because opening the file to write had already created a copy */
|
|
||||||
if (ssbuf.sb.st_size == 0
|
if (ssbuf.sb.st_size == 0
|
||||||
#ifdef S_ISFIFO
|
#ifdef S_ISFIFO
|
||||||
&& !S_ISFIFO(ssbuf.sb.st_mode)
|
&& !S_ISFIFO(ssbuf.sb.st_mode)
|
||||||
|
@ -1324,7 +1323,7 @@ PHPAPI size_t _php_stream_copy_to_stream(php_stream *src, php_stream *dest, size
|
||||||
&& !S_ISCHR(ssbuf.sb.st_mode)
|
&& !S_ISCHR(ssbuf.sb.st_mode)
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1339,7 +1338,13 @@ PHPAPI size_t _php_stream_copy_to_stream(php_stream *src, php_stream *dest, size
|
||||||
|
|
||||||
php_stream_mmap_unmap(src);
|
php_stream_mmap_unmap(src);
|
||||||
|
|
||||||
return mapped;
|
/* we've got at least 1 byte to read.
|
||||||
|
* less than 1 is an error */
|
||||||
|
|
||||||
|
if (mapped > 0) {
|
||||||
|
return mapped;
|
||||||
|
}
|
||||||
|
return PHP_STREAM_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1364,14 +1369,14 @@ PHPAPI size_t _php_stream_copy_to_stream(php_stream *src, php_stream *dest, size
|
||||||
while(towrite) {
|
while(towrite) {
|
||||||
didwrite = php_stream_write(dest, writeptr, towrite);
|
didwrite = php_stream_write(dest, writeptr, towrite);
|
||||||
if (didwrite == 0) {
|
if (didwrite == 0) {
|
||||||
return 0; /* error */
|
return PHP_STREAM_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
towrite -= didwrite;
|
towrite -= didwrite;
|
||||||
writeptr += didwrite;
|
writeptr += didwrite;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return haveread;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maxlen - haveread == 0) {
|
if (maxlen - haveread == 0) {
|
||||||
|
@ -1379,7 +1384,26 @@ PHPAPI size_t _php_stream_copy_to_stream(php_stream *src, php_stream *dest, size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return haveread;
|
/* we've got at least 1 byte to read.
|
||||||
|
* less than 1 is an error */
|
||||||
|
|
||||||
|
if (haveread > 0) {
|
||||||
|
return haveread;
|
||||||
|
}
|
||||||
|
return PHP_STREAM_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the number of bytes moved.
|
||||||
|
* Returns 1 when source len is 0.
|
||||||
|
* Deprecated in favor of php_stream_copy_to_stream_ex() */
|
||||||
|
ZEND_ATTRIBUTE_DEPRECATED
|
||||||
|
PHPAPI size_t _php_stream_copy_to_stream(php_stream *src, php_stream *dest, size_t maxlen STREAMS_DC TSRMLS_DC)
|
||||||
|
{
|
||||||
|
size_t ret = _php_stream_copy_to_stream_ex(src, dest, maxlen STREAMS_REL_CC TSRMLS_CC);
|
||||||
|
if (ret == 0 && maxlen != 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue