From 8ea9eb8560c02818a06369cdc33a2b2367964526 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Sun, 19 Apr 2009 17:10:35 +0000 Subject: [PATCH] MFH: Better fix for #47997 --- ext/standard/file.c | 11 +++++++---- ext/standard/streamsfuncs.c | 9 +++++---- main/php_streams.h | 6 ++---- main/streams/cast.c | 6 +++--- main/streams/streams.c | 37 +++++++++++++++++++++++++------------ 5 files changed, 42 insertions(+), 27 deletions(-) diff --git a/ext/standard/file.c b/ext/standard/file.c index a3b96b3b1b5..ae4fcb1f4a0 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -626,12 +626,15 @@ PHP_FUNCTION(file_put_contents) } switch (Z_TYPE_P(data)) { - case IS_RESOURCE: - numbytes = (int) php_stream_copy_to_stream_ex(srcstream, stream, PHP_STREAM_COPY_ALL); - if ((size_t)numbytes == PHP_STREAM_FAILURE) { + case IS_RESOURCE: { + size_t len; + if (php_stream_copy_to_stream_ex(srcstream, stream, PHP_STREAM_COPY_ALL, &len) != SUCCESS) { numbytes = -1; + } else { + numbytes = len; } break; + } case IS_NULL: case IS_LONG: case IS_DOUBLE: @@ -1786,7 +1789,7 @@ safe_to_copy: deststream = php_stream_open_wrapper(dest, "wb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL); if (srcstream && deststream) { - ret = php_stream_copy_to_stream_ex(srcstream, deststream, PHP_STREAM_COPY_ALL) == PHP_STREAM_FAILURE ? FAILURE : SUCCESS; + ret = php_stream_copy_to_stream_ex(srcstream, deststream, PHP_STREAM_COPY_ALL, NULL); } if (srcstream) { php_stream_close(srcstream); diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index 426849e81e8..508a95c9b09 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -443,7 +443,8 @@ PHP_FUNCTION(stream_copy_to_stream) php_stream *src, *dest; zval *zsrc, *zdest; long maxlen = PHP_STREAM_COPY_ALL, pos = 0; - size_t ret; + size_t len; + int ret; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr|ll", &zsrc, &zdest, &maxlen, &pos) == FAILURE) { RETURN_FALSE; @@ -457,12 +458,12 @@ PHP_FUNCTION(stream_copy_to_stream) RETURN_FALSE; } - ret = php_stream_copy_to_stream_ex(src, dest, maxlen); + ret = php_stream_copy_to_stream_ex(src, dest, maxlen, &len); - if (ret == PHP_STREAM_FAILURE) { + if (ret != SUCCESS) { RETURN_FALSE; } - RETURN_LONG(ret); + RETURN_LONG(len); } /* }}} */ diff --git a/main/php_streams.h b/main/php_streams.h index fab62c19af4..803c86793a0 100755 --- a/main/php_streams.h +++ b/main/php_streams.h @@ -420,14 +420,12 @@ END_EXTERN_C() * Uses mmap if the src is a plain file and at offset 0 */ #define PHP_STREAM_COPY_ALL ((size_t)-1) -#define PHP_STREAM_FAILURE ((size_t)-1) - 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); #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) +PHPAPI size_t _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size_t maxlen, size_t *len STREAMS_DC TSRMLS_DC); +#define php_stream_copy_to_stream_ex(src, dest, maxlen, len) _php_stream_copy_to_stream_ex((src), (dest), (maxlen), (len) STREAMS_CC TSRMLS_CC) /* read all data from stream and put into a buffer. Caller must free buffer when done. diff --git a/main/streams/cast.c b/main/streams/cast.c index 06805c709c9..5e613575378 100644 --- a/main/streams/cast.c +++ b/main/streams/cast.c @@ -214,9 +214,9 @@ PHPAPI int _php_stream_cast(php_stream *stream, int castas, void **ret, int show newstream = php_stream_fopen_tmpfile(); if (newstream) { - size_t copied = php_stream_copy_to_stream_ex(stream, newstream, PHP_STREAM_COPY_ALL); + int ret = php_stream_copy_to_stream_ex(stream, newstream, PHP_STREAM_COPY_ALL, NULL); - if (copied == PHP_STREAM_FAILURE) { + if (ret != SUCCESS) { php_stream_close(newstream); } else { 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; #endif - if (php_stream_copy_to_stream_ex(origstream, *newstream, PHP_STREAM_COPY_ALL) == PHP_STREAM_FAILURE) { + if (php_stream_copy_to_stream_ex(origstream, *newstream, PHP_STREAM_COPY_ALL, NULL) != SUCCESS) { php_stream_close(*newstream); *newstream = NULL; return PHP_STREAM_CRITICAL; diff --git a/main/streams/streams.c b/main/streams/streams.c index c5aebe78127..def2acec3d8 100755 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -1297,17 +1297,23 @@ PHPAPI size_t _php_stream_copy_to_mem(php_stream *src, char **buf, size_t maxlen return len; } -/* 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) +/* Returns SUCCESS/FAILURE and sets *len to the number of bytes moved */ +PHPAPI size_t _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size_t maxlen, size_t *len STREAMS_DC TSRMLS_DC) { char buf[CHUNK_SIZE]; size_t readchunk; size_t haveread = 0; size_t didread; + size_t dummy; php_stream_statbuf ssbuf; + if (!len) { + len = &dummy; + } + if (maxlen == 0) { - return 0; + *len = 0; + return SUCCESS; } if (maxlen == PHP_STREAM_COPY_ALL) { @@ -1323,7 +1329,8 @@ PHPAPI size_t _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, s && !S_ISCHR(ssbuf.sb.st_mode) #endif ) { - return 0; + *len = 0; + return SUCCESS; } } @@ -1337,14 +1344,16 @@ PHPAPI size_t _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, s mapped = php_stream_write(dest, p, mapped); php_stream_mmap_unmap(src); + + *len = mapped; /* we've got at least 1 byte to read. * less than 1 is an error */ if (mapped > 0) { - return mapped; + return SUCCESS; } - return PHP_STREAM_FAILURE; + return FAILURE; } } @@ -1369,7 +1378,8 @@ PHPAPI size_t _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, s while(towrite) { didwrite = php_stream_write(dest, writeptr, towrite); if (didwrite == 0) { - return PHP_STREAM_FAILURE; + *len = haveread - (didread - towrite); + return FAILURE; } towrite -= didwrite; @@ -1384,13 +1394,15 @@ PHPAPI size_t _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, s } } + *len = haveread; + /* we've got at least 1 byte to read. * less than 1 is an error */ if (haveread > 0) { - return haveread; + return SUCCESS; } - return PHP_STREAM_FAILURE; + return FAILURE; } /* Returns the number of bytes moved. @@ -1399,11 +1411,12 @@ PHPAPI size_t _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, s 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) { + size_t len; + int ret = _php_stream_copy_to_stream_ex(src, dest, maxlen, &len STREAMS_REL_CC TSRMLS_CC); + if (ret == SUCCESS && len == 0 && maxlen != 0) { return 1; } - return ret; + return len; } /* }}} */