]> granicus.if.org Git - php/commitdiff
MFH: Better fix for #47997
authorArnaud Le Blanc <lbarnaud@php.net>
Sun, 19 Apr 2009 17:10:52 +0000 (17:10 +0000)
committerArnaud Le Blanc <lbarnaud@php.net>
Sun, 19 Apr 2009 17:10:52 +0000 (17:10 +0000)
ext/standard/file.c
ext/standard/streamsfuncs.c
main/php_streams.h
main/streams/cast.c
main/streams/streams.c

index 9007d425d03ffb3976b35165747936b22a9ec8a9..df600f527e1c739751fd333fee389f00fccfd8bf 100644 (file)
@@ -629,12 +629,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:
@@ -1839,7 +1842,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);
index 60d6b441627662c55b56c193e3fac61622210b7b..6a46019c39dc0a855096ca3e4ae3b000c5f771c0 100644 (file)
@@ -437,7 +437,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;
@@ -451,12 +452,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);
 }
 /* }}} */
 
index 4986287025cf5684f316eaf1d6b648fe88791976..1a9c313262d223dd36c6b04b985c6c8af72fb615 100755 (executable)
@@ -416,13 +416,11 @@ 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()
 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.
index 82ee4636ed9c5e2fcea6e3d264fecf193ad300fe..1b451b0deb12627bc1193d8511883dadaa4d5f21 100644 (file)
@@ -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);
@@ -327,7 +327,7 @@ PHPAPI int _php_stream_make_seekable(php_stream *origstream, php_stream **newstr
        if (*newstream == NULL)
                return PHP_STREAM_FAILED;
 
-       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;
index 393655a68ad3b6651e9c4116f9488e71bebedf75..8e7fd84cff9abf435e3013db32fdf8a1f16c1bcd 100755 (executable)
@@ -1288,17 +1288,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) {
@@ -1314,7 +1320,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;
                }
        }
 
@@ -1328,14 +1335,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;
                }
        }
 
@@ -1359,7 +1368,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;
@@ -1374,13 +1384,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.
@@ -1388,11 +1400,12 @@ PHPAPI size_t _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, s
  * Deprecated in favor of php_stream_copy_to_stream_ex() */
 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;
 }
 /* }}} */