Browse Source

Better fix for #47997

experimental/first_unicode_implementation
Arnaud Le Blanc 17 years ago
parent
commit
6b213bffb6
  1. 11
      ext/standard/file.c
  2. 9
      ext/standard/streamsfuncs.c
  3. 12
      main/php_streams.h
  4. 6
      main/streams/cast.c
  5. 70
      main/streams/streams.c

11
ext/standard/file.c

@ -661,12 +661,15 @@ PHP_FUNCTION(file_put_contents)
}
switch (Z_TYPE_P(data)) {
case IS_RESOURCE:
numchars = (int) php_stream_copy_to_stream_ex(srcstream, stream, PHP_STREAM_COPY_ALL);
if ((size_t)numchars == PHP_STREAM_FAILURE) {
case IS_RESOURCE: {
size_t len;
if (php_stream_copy_to_stream_ex(srcstream, stream, PHP_STREAM_COPY_ALL, &len) != SUCCESS) {
numchars = -1;
} else {
numchars = len;
}
break;
}
case IS_ARRAY:
if (zend_hash_num_elements(Z_ARRVAL_P(data))) {
zval **tmp;
@ -1952,7 +1955,7 @@ safe_to_copy:
deststream = php_stream_open_wrapper(dest, "wb", 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);

9
ext/standard/streamsfuncs.c

@ -458,7 +458,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;
@ -472,12 +473,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);
}
/* }}} */

12
main/php_streams.h

@ -525,8 +525,6 @@ 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_ucopy_to_stream(php_stream *src, php_stream *dest, size_t maxlen, size_t maxchars STREAMS_DC TSRMLS_DC);
@ -537,12 +535,12 @@ PHPAPI size_t _php_stream_copy_to_stream(php_stream *src, php_stream *dest, size
? _php_stream_copy_to_stream((src), (dest), (maxlen) STREAMS_CC TSRMLS_CC) \
: _php_stream_ucopy_to_stream((src), (dest), -1, (maxlen) STREAMS_CC TSRMLS_CC) )
PHPAPI size_t _php_stream_ucopy_to_stream_ex(php_stream *src, php_stream *dest, size_t maxlen, size_t maxchars STREAMS_DC TSRMLS_DC);
PHPAPI size_t _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size_t maxlen STREAMS_DC TSRMLS_DC);
PHPAPI size_t _php_stream_ucopy_to_stream_ex(php_stream *src, php_stream *dest, size_t maxlen, size_t maxchars, size_t *len STREAMS_DC TSRMLS_DC);
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);
/* Preserve "characters" semantics by having maxlen refer to maxchars in a unicode context */
#define php_stream_copy_to_stream_ex(src, dest, maxlen) ( ((src)->readbuf_type == IS_STRING) \
? _php_stream_copy_to_stream_ex((src), (dest), (maxlen) STREAMS_CC TSRMLS_CC) \
: _php_stream_ucopy_to_stream_ex((src), (dest), -1, (maxlen) STREAMS_CC TSRMLS_CC) )
#define php_stream_copy_to_stream_ex(src, dest, maxlen, len) ( ((src)->readbuf_type == IS_STRING) \
? _php_stream_copy_to_stream_ex((src), (dest), (maxlen), (len) STREAMS_CC TSRMLS_CC) \
: _php_stream_ucopy_to_stream_ex((src), (dest), -1, (maxlen), (len) STREAMS_CC TSRMLS_CC) )
/* read all data from stream and put into a buffer. Caller must free buffer when done.
* The copy will use mmap if available. */

6
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;

70
main/streams/streams.c

@ -1768,18 +1768,24 @@ PHPAPI size_t _php_stream_copy_to_mem_ex(php_stream *src, zend_uchar rettype, vo
}
/* Designed for copying UChars (taking into account both maxlen and maxchars) */
PHPAPI size_t _php_stream_ucopy_to_stream_ex(php_stream *src, php_stream *dest, size_t maxlen, size_t maxchars STREAMS_DC TSRMLS_DC)
PHPAPI size_t _php_stream_ucopy_to_stream_ex(php_stream *src, php_stream *dest, size_t maxlen, size_t maxchars, size_t *len STREAMS_DC TSRMLS_DC)
{
size_t haveread = 0;
php_stream_statbuf ssbuf;
size_t dummy;
if (!len) {
len = &dummy;
}
if (src->readbuf_type == IS_STRING) {
/* Called incorrectly, don't do that. */
return _php_stream_copy_to_stream_ex(src, dest, maxlen STREAMS_CC TSRMLS_CC);
return _php_stream_copy_to_stream_ex(src, dest, maxlen, len STREAMS_CC TSRMLS_CC);
}
if (maxlen == 0 || maxchars == 0) {
return 0;
*len = 0;
return SUCCESS;
}
if (maxlen == PHP_STREAM_COPY_ALL) {
@ -1795,7 +1801,8 @@ PHPAPI size_t _php_stream_ucopy_to_stream_ex(php_stream *src, php_stream *dest,
&& !S_ISCHR(ssbuf.sb.st_mode)
#endif
) {
return 0;
*len = 0;
return SUCCESS;
}
}
@ -1827,7 +1834,8 @@ PHPAPI size_t _php_stream_ucopy_to_stream_ex(php_stream *src, php_stream *dest,
while(towrite) {
didwrite = php_stream_write_unicode(dest, writeptr, towrite);
if (didwrite == 0) {
return PHP_STREAM_FAILURE;
*len = haveread - (didread - towrite);
return FAILURE;
}
towrite -= didwrite;
@ -1841,41 +1849,50 @@ PHPAPI size_t _php_stream_ucopy_to_stream_ex(php_stream *src, php_stream *dest,
break;
}
}
*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;
}
/* see _php_stream_copy_to_stream() */
ZEND_ATTRIBUTE_DEPRECATED
PHPAPI size_t _php_stream_ucopy_to_stream(php_stream *src, php_stream *dest, size_t maxlen, size_t maxchars STREAMS_DC TSRMLS_DC)
{
size_t ret = _php_stream_ucopy_to_stream_ex(src, dest, maxlen, maxchars STREAMS_REL_CC TSRMLS_CC);
if (ret == 0 && maxlen != 0 && maxchars != 0) {
size_t len;
int ret = _php_stream_ucopy_to_stream_ex(src, dest, maxlen, maxchars, &len STREAMS_REL_CC TSRMLS_CC);
if (ret == SUCCESS && maxlen != 0 && maxchars != 0) {
return 1;
}
return ret;
return len;
}
/* Optimized for copying octets from source stream */
/* 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)
{
size_t haveread = 0;
php_stream_statbuf ssbuf;
size_t dummy;
if (!len) {
len = &dummy;
}
if (src->readbuf_type == IS_UNICODE) {
/* Called incorrectly, don't do that. */
return _php_stream_ucopy_to_stream_ex(src, dest, maxlen, -1 STREAMS_CC TSRMLS_CC);
return _php_stream_ucopy_to_stream_ex(src, dest, maxlen, -1, len STREAMS_CC TSRMLS_CC);
}
if (maxlen == 0) {
return 0;
*len = 0;
return SUCCESS;
}
if (maxlen == PHP_STREAM_COPY_ALL) {
@ -1891,7 +1908,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;
}
}
@ -1905,14 +1923,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;
}
}
@ -1939,7 +1959,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;
@ -1954,13 +1975,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.
@ -1969,11 +1992,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;
}
/* }}} */

Loading…
Cancel
Save