summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-07-22 17:25:28 +0200
committerNikita Popov <nikita.ppv@gmail.com>2019-07-22 17:26:01 +0200
commita1e2c8870ebfdc1c2d9fa25327bc3dad5bd68c91 (patch)
tree1ba6ec4f9b3f51ef407c2903af2ad7815f8b69ca
parent7a1540fa2872a67080f2161faff226c1effebf76 (diff)
parentd59aac58b3e7da7ad01a194fe9840d89725ea229 (diff)
downloadphp-git-a1e2c8870ebfdc1c2d9fa25327bc3dad5bd68c91.tar.gz
Merge branch 'PHP-7.4'
-rw-r--r--ext/bz2/bug71263.phpt53
-rw-r--r--ext/bz2/bz2.c28
-rw-r--r--ext/bz2/tests/004.phpt8
-rw-r--r--ext/bz2/tests/bug72613.phpt2
-rw-r--r--ext/com_dotnet/com_persist.c6
-rw-r--r--ext/curl/interface.c4
-rw-r--r--ext/exif/exif.c6
-rw-r--r--ext/gd/gd.c8
-rw-r--r--ext/hash/hash.c23
-rw-r--r--ext/iconv/tests/bug76249.phpt5
-rw-r--r--ext/mysqlnd/mysqlnd_net.c28
-rw-r--r--ext/mysqlnd/mysqlnd_protocol_frame_codec.c7
-rw-r--r--ext/mysqlnd/mysqlnd_structs.h2
-rw-r--r--ext/mysqlnd/mysqlnd_vio.c17
-rw-r--r--ext/openssl/xp_ssl.c8
-rw-r--r--ext/pdo_oci/oci_statement.c4
-rw-r--r--ext/pdo_pgsql/pgsql_driver.c4
-rw-r--r--ext/pgsql/pgsql.c8
-rw-r--r--ext/pgsql/php_pgsql.h4
-rw-r--r--ext/phar/dirstream.c6
-rw-r--r--ext/phar/dirstream.h4
-rw-r--r--ext/phar/stream.c8
-rw-r--r--ext/phar/stream.h4
-rw-r--r--ext/phar/tests/027.phpt2
-rw-r--r--ext/soap/php_http.c8
-rw-r--r--ext/spl/spl_directory.c20
-rw-r--r--ext/sqlite3/sqlite3.c12
-rw-r--r--ext/sqlite3/tests/sqlite3_30_blobopen.phpt4
-rw-r--r--ext/standard/exec.c5
-rw-r--r--ext/standard/file.c37
-rw-r--r--ext/standard/file.h2
-rw-r--r--ext/standard/ftp_fopen_wrapper.c6
-rw-r--r--ext/standard/md5.c2
-rw-r--r--ext/standard/php_fopen_wrapper.c12
-rw-r--r--ext/standard/sha1.c2
-rw-r--r--ext/standard/tests/file/007_variation1.phpt4
-rw-r--r--ext/standard/tests/file/007_variation11-win32-mb.phpt4
-rw-r--r--ext/standard/tests/file/007_variation11-win32.phpt4
-rw-r--r--ext/standard/tests/file/007_variation11.phpt4
-rw-r--r--ext/standard/tests/file/007_variation13-win32.phpt4
-rw-r--r--ext/standard/tests/file/007_variation13.phpt4
-rw-r--r--ext/standard/tests/file/007_variation15.phpt4
-rw-r--r--ext/standard/tests/file/007_variation17.phpt4
-rw-r--r--ext/standard/tests/file/007_variation19.phpt4
-rw-r--r--ext/standard/tests/file/007_variation21.phpt4
-rw-r--r--ext/standard/tests/file/007_variation23.phpt4
-rw-r--r--ext/standard/tests/file/007_variation3.phpt4
-rw-r--r--ext/standard/tests/file/007_variation5.phpt4
-rw-r--r--ext/standard/tests/file/007_variation7.phpt4
-rw-r--r--ext/standard/tests/file/007_variation9.phpt4
-rw-r--r--ext/standard/tests/file/fputcsv_variation14.phpt54
-rw-r--r--ext/standard/tests/file/fwrite.phpt2
-rw-r--r--ext/standard/tests/file/fwrite_variation1-win32-mb.phpt48
-rw-r--r--ext/standard/tests/file/fwrite_variation1.phpt48
-rw-r--r--ext/standard/tests/network/bug20134.phpt2
-rw-r--r--ext/standard/tests/streams/bug44818.phpt4
-rw-r--r--ext/standard/tests/streams/eagain_is_not_an_error.phpt16
-rw-r--r--ext/standard/tests/streams/nonblocking_stdin.phpt11
-rw-r--r--ext/zip/zip_stream.c10
-rw-r--r--ext/zlib/tests/bug71417.phpt82
-rw-r--r--ext/zlib/tests/bug_52944.phpt2
-rw-r--r--ext/zlib/tests/gzread_variation1.phpt6
-rw-r--r--ext/zlib/zlib_fopen_wrapper.c11
-rw-r--r--main/php_streams.h16
-rw-r--r--main/php_variables.c4
-rw-r--r--main/streams/glob_wrapper.c4
-rw-r--r--main/streams/memory.c10
-rw-r--r--main/streams/plain_wrapper.c34
-rw-r--r--main/streams/streams.c181
-rw-r--r--main/streams/userspace.c29
-rw-r--r--main/streams/xp_socket.c26
-rw-r--r--sapi/phpdbg/phpdbg.c2
-rw-r--r--sapi/phpdbg/phpdbg.h2
73 files changed, 647 insertions, 376 deletions
diff --git a/ext/bz2/bug71263.phpt b/ext/bz2/bug71263.phpt
new file mode 100644
index 0000000000..387c06bfdb
--- /dev/null
+++ b/ext/bz2/bug71263.phpt
@@ -0,0 +1,53 @@
+--TEST--
+Bug #71263: fread() does not detects decoding errors from filter bzip2.decompress
+--FILE--
+<?php
+
+// Should notices be generated?
+
+function test($case) {
+ $plain = "The quick brown fox jumps over the lazy dog.";
+ $fn = "bug71263.bz2";
+ $compressed = (string) bzcompress($plain);
+ echo "Compressed len = ", strlen($compressed), "\n";
+
+ if ($case == 1) {
+ // Set a random byte in the middle of the compressed data
+ // --> php_bz2_decompress_filter() detects fatal error
+ // --> fread() displays empty string then garbage, no errors detected:
+ $compressed[strlen($compressed) - 15] = 'X';
+ } else if ($case == 2) {
+ // Truncate the compressed data
+ // --> php_bz2_decompress_filter() does not detect errors,
+ // --> fread() displays the empty string:
+ $compressed = substr($compressed, 0, strlen($compressed) - 20);
+ } else {
+ // Corrupted final CRC
+ // --> php_bz2_decompress_filter() detects fatal error
+ // --> fread() displays an empty string, then the correct plain text, no error detected:
+ $compressed[strlen($compressed)-2] = 'X';
+ }
+
+ file_put_contents($fn, $compressed);
+
+ $r = fopen($fn, "r");
+ stream_filter_append($r, 'bzip2.decompress', STREAM_FILTER_READ);
+ while (!feof($r)) {
+ $s = fread($r, 100);
+ echo "read: "; var_dump($s);
+ }
+ fclose($r);
+ unlink($fn);
+}
+
+test(1);
+test(2);
+test(3);
+?>
+--EXPECT--
+Compressed len = 81
+read: bool(false)
+Compressed len = 81
+read: string(0) ""
+Compressed len = 81
+read: bool(false)
diff --git a/ext/bz2/bz2.c b/ext/bz2/bz2.c
index cf1029f4d0..7b54766575 100644
--- a/ext/bz2/bz2.c
+++ b/ext/bz2/bz2.c
@@ -133,7 +133,7 @@ struct php_bz2_stream_data_t {
/* {{{ BZip2 stream implementation */
-static size_t php_bz2iop_read(php_stream *stream, char *buf, size_t count)
+static ssize_t php_bz2iop_read(php_stream *stream, char *buf, size_t count)
{
struct php_bz2_stream_data_t *self = (struct php_bz2_stream_data_t *)stream->abstract;
size_t ret = 0;
@@ -149,6 +149,9 @@ static size_t php_bz2iop_read(php_stream *stream, char *buf, size_t count)
/* it is not safe to keep reading after an error, see #72613 */
stream->eof = 1;
if (just_read < 0) {
+ if (ret) {
+ return ret;
+ }
return -1;
}
break;
@@ -160,20 +163,24 @@ static size_t php_bz2iop_read(php_stream *stream, char *buf, size_t count)
return ret;
}
-static size_t php_bz2iop_write(php_stream *stream, const char *buf, size_t count)
+static ssize_t php_bz2iop_write(php_stream *stream, const char *buf, size_t count)
{
- size_t wrote = 0;
+ ssize_t wrote = 0;
struct php_bz2_stream_data_t *self = (struct php_bz2_stream_data_t *)stream->abstract;
-
do {
int just_wrote;
size_t remain = count - wrote;
int to_write = (int)(remain <= INT_MAX ? remain : INT_MAX);
just_wrote = BZ2_bzwrite(self->bz_file, (char*)buf, to_write);
-
- if (just_wrote < 1) {
+ if (just_wrote < 0) {
+ if (wrote == 0) {
+ return just_wrote;
+ }
+ return wrote;
+ }
+ if (just_wrote == 0) {
break;
}
@@ -381,11 +388,12 @@ static PHP_FUNCTION(bzread)
php_error_docref(NULL, E_WARNING, "length may not be negative");
RETURN_FALSE;
}
- data = zend_string_alloc(len, 0);
- ZSTR_LEN(data) = php_stream_read(stream, ZSTR_VAL(data), ZSTR_LEN(data));
- ZSTR_VAL(data)[ZSTR_LEN(data)] = '\0';
- RETURN_NEW_STR(data);
+ data = php_stream_read_to_str(stream, len);
+ if (!data) {
+ RETURN_FALSE;
+ }
+ RETURN_STR(data);
}
/* }}} */
diff --git a/ext/bz2/tests/004.phpt b/ext/bz2/tests/004.phpt
index b9fa649b58..15eb90f89a 100644
--- a/ext/bz2/tests/004.phpt
+++ b/ext/bz2/tests/004.phpt
@@ -76,7 +76,7 @@ array(2) {
}
string(2) "OK"
int(0)
-string(0) ""
+bool(false)
array(2) {
["errno"]=>
int(-5)
@@ -85,7 +85,7 @@ array(2) {
}
string(16) "DATA_ERROR_MAGIC"
int(-5)
-string(0) ""
+bool(false)
array(2) {
["errno"]=>
int(-4)
@@ -94,7 +94,7 @@ array(2) {
}
string(10) "DATA_ERROR"
int(-4)
-string(0) ""
+bool(false)
array(2) {
["errno"]=>
int(-5)
@@ -103,7 +103,7 @@ array(2) {
}
string(16) "DATA_ERROR_MAGIC"
int(-5)
-string(0) ""
+bool(false)
array(2) {
["errno"]=>
int(-4)
diff --git a/ext/bz2/tests/bug72613.phpt b/ext/bz2/tests/bug72613.phpt
index 049e065554..d9463e212a 100644
--- a/ext/bz2/tests/bug72613.phpt
+++ b/ext/bz2/tests/bug72613.phpt
@@ -20,4 +20,4 @@ bzclose($fp);
?>
DONE
--EXPECT--
-DONE
+ERROR: bzread()
diff --git a/ext/com_dotnet/com_persist.c b/ext/com_dotnet/com_persist.c
index e78503be3c..97810ec8cc 100644
--- a/ext/com_dotnet/com_persist.c
+++ b/ext/com_dotnet/com_persist.c
@@ -118,13 +118,13 @@ static HRESULT STDMETHODCALLTYPE stm_read(IStream *This, void *pv, ULONG cb, ULO
static HRESULT STDMETHODCALLTYPE stm_write(IStream *This, void const *pv, ULONG cb, ULONG *pcbWritten)
{
- ULONG nwrote;
+ ssize_t nwrote;
FETCH_STM();
- nwrote = (ULONG)php_stream_write(stm->stream, pv, cb);
+ nwrote = php_stream_write(stm->stream, pv, cb);
if (pcbWritten) {
- *pcbWritten = nwrote > 0 ? nwrote : 0;
+ *pcbWritten = nwrote > 0 ? (ULONG)nwrote : 0;
}
if (nwrote > 0) {
return S_OK;
diff --git a/ext/curl/interface.c b/ext/curl/interface.c
index 6b42ddafa6..6a25359597 100644
--- a/ext/curl/interface.c
+++ b/ext/curl/interface.c
@@ -2133,9 +2133,9 @@ PHP_FUNCTION(curl_copy_handle)
static size_t read_cb(char *buffer, size_t size, size_t nitems, void *arg) /* {{{ */
{
php_stream *stream = (php_stream *) arg;
- size_t numread = php_stream_read(stream, buffer, nitems * size);
+ ssize_t numread = php_stream_read(stream, buffer, nitems * size);
- if (numread == (size_t)-1) {
+ if (numread < 0) {
return CURL_READFUNC_ABORT;
}
return numread;
diff --git a/ext/exif/exif.c b/ext/exif/exif.c
index 505cb94e7e..39374d25cc 100644
--- a/ext/exif/exif.c
+++ b/ext/exif/exif.c
@@ -3258,7 +3258,7 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
}
fgot = php_stream_read(ImageInfo->infile, value_ptr, byte_count);
php_stream_seek(ImageInfo->infile, fpos, SEEK_SET);
- if (fgot<byte_count) {
+ if (fgot != byte_count) {
EFREE_IF(outside);
EXIF_ERRLOG_FILEEOF(ImageInfo)
return FALSE;
@@ -4087,7 +4087,7 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offse
ImageInfo->Thumbnail.data = safe_emalloc(ImageInfo->Thumbnail.size, 1, 0);
php_stream_seek(ImageInfo->infile, ImageInfo->Thumbnail.offset, SEEK_SET);
fgot = php_stream_read(ImageInfo->infile, ImageInfo->Thumbnail.data, ImageInfo->Thumbnail.size);
- if (fgot < ImageInfo->Thumbnail.size) {
+ if (fgot != ImageInfo->Thumbnail.size) {
EXIF_ERRLOG_THUMBEOF(ImageInfo)
efree(ImageInfo->Thumbnail.data);
@@ -4125,7 +4125,7 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offse
ImageInfo->Thumbnail.data = safe_emalloc(ImageInfo->Thumbnail.size, 1, 0);
php_stream_seek(ImageInfo->infile, ImageInfo->Thumbnail.offset, SEEK_SET);
fgot = php_stream_read(ImageInfo->infile, ImageInfo->Thumbnail.data, ImageInfo->Thumbnail.size);
- if (fgot < ImageInfo->Thumbnail.size) {
+ if (fgot != ImageInfo->Thumbnail.size) {
EXIF_ERRLOG_THUMBEOF(ImageInfo)
efree(ImageInfo->Thumbnail.data);
ImageInfo->Thumbnail.data = NULL;
diff --git a/ext/gd/gd.c b/ext/gd/gd.c
index e3a90786f2..f0137d118b 100644
--- a/ext/gd/gd.c
+++ b/ext/gd/gd.c
@@ -1409,11 +1409,11 @@ PHP_FUNCTION(imageloadfont)
*/
font = (gdFontPtr) emalloc(sizeof(gdFont));
b = 0;
- while (b < hdr_size && (n = php_stream_read(stream, (char*)&font[b], hdr_size - b))) {
+ while (b < hdr_size && (n = php_stream_read(stream, (char*)&font[b], hdr_size - b)) > 0) {
b += n;
}
- if (!n) {
+ if (n <= 0) {
efree(font);
if (php_stream_eof(stream)) {
php_error_docref(NULL, E_WARNING, "End of file while reading header");
@@ -1452,11 +1452,11 @@ PHP_FUNCTION(imageloadfont)
font->data = emalloc(body_size);
b = 0;
- while (b < body_size && (n = php_stream_read(stream, &font->data[b], body_size - b))) {
+ while (b < body_size && (n = php_stream_read(stream, &font->data[b], body_size - b)) > 0) {
b += n;
}
- if (!n) {
+ if (n <= 0) {
efree(font->data);
efree(font);
if (php_stream_eof(stream)) {
diff --git a/ext/hash/hash.c b/ext/hash/hash.c
index 5b0c8570c9..2fbff0d102 100644
--- a/ext/hash/hash.c
+++ b/ext/hash/hash.c
@@ -149,12 +149,16 @@ static void php_hash_do_hash(INTERNAL_FUNCTION_PARAMETERS, int isfilename, zend_
if (isfilename) {
char buf[1024];
- size_t n;
+ ssize_t n;
while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
ops->hash_update(context, (unsigned char *) buf, n);
}
php_stream_close(stream);
+ if (n < 0) {
+ efree(context);
+ RETURN_FALSE;
+ }
} else {
ops->hash_update(context, (unsigned char *) data, data_len);
}
@@ -277,13 +281,20 @@ static void php_hash_do_hash_hmac(INTERNAL_FUNCTION_PARAMETERS, int isfilename,
if (isfilename) {
char buf[1024];
- size_t n;
+ ssize_t n;
ops->hash_init(context);
ops->hash_update(context, K, ops->block_size);
while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
ops->hash_update(context, (unsigned char *) buf, n);
}
php_stream_close(stream);
+ if (n < 0) {
+ efree(context);
+ efree(K);
+ zend_string_release(digest);
+ RETURN_FALSE;
+ }
+
ops->hash_final((unsigned char *) ZSTR_VAL(digest), context);
} else {
php_hash_hmac_round((unsigned char *) ZSTR_VAL(digest), ops, context, K, (unsigned char *) data, data_len);
@@ -447,14 +458,14 @@ PHP_FUNCTION(hash_update_stream)
while (length) {
char buf[1024];
- zend_long n, toread = 1024;
+ zend_long toread = 1024;
+ ssize_t n;
if (length > 0 && toread > length) {
toread = length;
}
if ((n = php_stream_read(stream, buf, toread)) <= 0) {
- /* Nada mas */
RETURN_LONG(didread);
}
hash->ops->hash_update(hash->context, (unsigned char *) buf, n);
@@ -476,7 +487,7 @@ PHP_FUNCTION(hash_update_file)
php_stream *stream;
zend_string *filename;
char buf[1024];
- size_t n;
+ ssize_t n;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "OP|r", &zhash, php_hashcontext_ce, &filename, &zcontext) == FAILURE) {
return;
@@ -497,7 +508,7 @@ PHP_FUNCTION(hash_update_file)
}
php_stream_close(stream);
- RETURN_TRUE;
+ RETURN_BOOL(n >= 0);
}
/* }}} */
diff --git a/ext/iconv/tests/bug76249.phpt b/ext/iconv/tests/bug76249.phpt
index 0a2dcaed2f..25bbf2a41f 100644
--- a/ext/iconv/tests/bug76249.phpt
+++ b/ext/iconv/tests/bug76249.phpt
@@ -10,11 +10,10 @@ rewind($fh);
if (false === @stream_filter_append($fh, 'convert.iconv.ucs-2/utf8//IGNORE', STREAM_FILTER_READ, [])) {
stream_filter_append($fh, 'convert.iconv.ucs-2/utf-8//IGNORE', STREAM_FILTER_READ, []);
}
-$a = stream_get_contents($fh);
-var_dump(strlen($a));
+var_dump(stream_get_contents($fh));
?>
DONE
--EXPECTF--
Warning: stream_get_contents(): iconv stream filter ("ucs-2"=>"utf%A8//IGNORE"): invalid multibyte sequence in %sbug76249.php on line %d
-int(3)
+string(0) ""
DONE
diff --git a/ext/mysqlnd/mysqlnd_net.c b/ext/mysqlnd/mysqlnd_net.c
index 9f684288e6..f886b6e005 100644
--- a/ext/mysqlnd/mysqlnd_net.c
+++ b/ext/mysqlnd/mysqlnd_net.c
@@ -88,7 +88,7 @@ MYSQLND_METHOD(mysqlnd_net, network_read_ex)(MYSQLND_NET * const net, zend_uchar
enum_func_status return_value = PASS;
php_stream * net_stream = net->data->m.get_stream(net);
size_t old_chunk_size = net_stream->chunk_size;
- size_t to_read = count, ret;
+ size_t to_read = count;
zend_uchar * p = buffer;
DBG_ENTER("mysqlnd_net::network_read_ex");
@@ -96,7 +96,8 @@ MYSQLND_METHOD(mysqlnd_net, network_read_ex)(MYSQLND_NET * const net, zend_uchar
net_stream->chunk_size = MIN(to_read, net->data->options.net_read_buffer_size);
while (to_read) {
- if (!(ret = php_stream_read(net_stream, (char *) p, to_read))) {
+ ssize_t ret = php_stream_read(net_stream, (char *) p, to_read);
+ if (ret <= 0) {
DBG_ERR_FMT("Error while reading header from socket");
return_value = FAIL;
break;
@@ -112,11 +113,11 @@ MYSQLND_METHOD(mysqlnd_net, network_read_ex)(MYSQLND_NET * const net, zend_uchar
/* {{{ mysqlnd_net::network_write_ex */
-static size_t
+static ssize_t
MYSQLND_METHOD(mysqlnd_net, network_write_ex)(MYSQLND_NET * const net, const zend_uchar * const buffer, const size_t count,
MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info)
{
- size_t ret;
+ ssize_t ret;
DBG_ENTER("mysqlnd_net::network_write_ex");
DBG_INF_FMT("sending %u bytes", count);
ret = php_stream_write(net->data->m.get_stream(net), (char *)buffer, count);
@@ -364,11 +365,12 @@ MYSQLND_METHOD(mysqlnd_net, send_ex)(MYSQLND_NET * const net, zend_uchar * const
{
zend_uchar safe_buf[((MYSQLND_HEADER_SIZE) + (sizeof(zend_uchar)) - 1) / (sizeof(zend_uchar))];
zend_uchar * safe_storage = safe_buf;
- size_t bytes_sent, packets_sent = 1;
+ size_t packets_sent = 1;
size_t left = count;
zend_uchar * p = (zend_uchar *) buffer;
zend_uchar * compress_buf = NULL;
size_t to_be_sent;
+ ssize_t bytes_sent;
DBG_ENTER("mysqlnd_net::send_ex");
DBG_INF_FMT("count=" MYSQLND_SZ_T_SPEC " compression=%u", count, net->data->compressed);
@@ -458,7 +460,7 @@ MYSQLND_METHOD(mysqlnd_net, send_ex)(MYSQLND_NET * const net, zend_uchar * const
indeed it then loop once more, then to_be_sent will become 0, left will stay 0. Empty
packet will be sent and this loop will end.
*/
- } while (bytes_sent && (left > 0 || to_be_sent == MYSQLND_MAX_PACKET_SIZE));
+ } while (bytes_sent > 0 && (left > 0 || to_be_sent == MYSQLND_MAX_PACKET_SIZE));
DBG_INF_FMT("packet_size="MYSQLND_SZ_T_SPEC" packet_no=%u", left, net->packet_no);
@@ -472,7 +474,7 @@ MYSQLND_METHOD(mysqlnd_net, send_ex)(MYSQLND_NET * const net, zend_uchar * const
}
/* Even for zero size payload we have to send a packet */
- if (!bytes_sent) {
+ if (bytes_sent <= 0) {
DBG_ERR_FMT("Can't %u send bytes", count);
SET_CLIENT_ERROR(*error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
}
@@ -866,10 +868,14 @@ MYSQLND_METHOD(mysqlnd_net, consume_uneaten_data)(MYSQLND_NET * const net, enum
if (PHP_STREAM_OPTION_RETURN_ERR != was_blocked) {
/* Do a read of 1 byte */
- int bytes_consumed;
+ ssize_t bytes_consumed;
do {
- skipped_bytes += (bytes_consumed = php_stream_read(net_stream, tmp_buf, sizeof(tmp_buf)));
+ bytes_consumed = php_stream_read(net_stream, tmp_buf, sizeof(tmp_buf));
+ if (bytes_consumed <= 0) {
+ break;
+ }
+ skipped_bytes += bytes_consumed;
} while (bytes_consumed == sizeof(tmp_buf));
if (was_blocked) {
@@ -877,9 +883,9 @@ MYSQLND_METHOD(mysqlnd_net, consume_uneaten_data)(MYSQLND_NET * const net, enum
}
if (bytes_consumed) {
- DBG_ERR_FMT("Skipped %u bytes. Last command %s hasn't consumed all the output from the server",
+ DBG_ERR_FMT("Skipped %zu bytes. Last command %s hasn't consumed all the output from the server",
bytes_consumed, mysqlnd_command_to_text[net->last_command]);
- php_error_docref(NULL, E_WARNING, "Skipped %u bytes. Last command %s hasn't "
+ php_error_docref(NULL, E_WARNING, "Skipped %zu bytes. Last command %s hasn't "
"consumed all the output from the server",
bytes_consumed, mysqlnd_command_to_text[net->last_command]);
}
diff --git a/ext/mysqlnd/mysqlnd_protocol_frame_codec.c b/ext/mysqlnd/mysqlnd_protocol_frame_codec.c
index 0fc5b38c5f..038a1eb6ad 100644
--- a/ext/mysqlnd/mysqlnd_protocol_frame_codec.c
+++ b/ext/mysqlnd/mysqlnd_protocol_frame_codec.c
@@ -68,11 +68,12 @@ MYSQLND_METHOD(mysqlnd_pfc, send)(MYSQLND_PFC * const pfc, MYSQLND_VIO * const v
{
zend_uchar safe_buf[((MYSQLND_HEADER_SIZE) + (sizeof(zend_uchar)) - 1) / (sizeof(zend_uchar))];
zend_uchar * safe_storage = safe_buf;
- size_t bytes_sent, packets_sent = 1;
+ size_t packets_sent = 1;
size_t left = count;
zend_uchar * p = (zend_uchar *) buffer;
zend_uchar * compress_buf = NULL;
size_t to_be_sent;
+ ssize_t bytes_sent;
DBG_ENTER("mysqlnd_pfc::send");
DBG_INF_FMT("count=" MYSQLND_SZ_T_SPEC " compression=%u", count, pfc->data->compressed);
@@ -161,7 +162,7 @@ MYSQLND_METHOD(mysqlnd_pfc, send)(MYSQLND_PFC * const pfc, MYSQLND_VIO * const v
indeed it then loop once more, then to_be_sent will become 0, left will stay 0. Empty
packet will be sent and this loop will end.
*/
- } while (bytes_sent && (left > 0 || to_be_sent == MYSQLND_MAX_PACKET_SIZE));
+ } while (bytes_sent > 0 && (left > 0 || to_be_sent == MYSQLND_MAX_PACKET_SIZE));
DBG_INF_FMT("packet_size="MYSQLND_SZ_T_SPEC" packet_no=%u", left, pfc->data->packet_no);
@@ -175,7 +176,7 @@ MYSQLND_METHOD(mysqlnd_pfc, send)(MYSQLND_PFC * const pfc, MYSQLND_VIO * const v
}
/* Even for zero size payload we have to send a packet */
- if (!bytes_sent) {
+ if (bytes_sent <= 0) {
DBG_ERR_FMT("Can't %u send bytes", count);
SET_CLIENT_ERROR(error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
}
diff --git a/ext/mysqlnd/mysqlnd_structs.h b/ext/mysqlnd/mysqlnd_structs.h
index 62128a2799..9880d1643d 100644
--- a/ext/mysqlnd/mysqlnd_structs.h
+++ b/ext/mysqlnd/mysqlnd_structs.h
@@ -382,7 +382,7 @@ typedef void (*func_mysqlnd_vio__post_connect_set_opt)(MYSQLND_VIO * const vi
typedef enum_func_status (*func_mysqlnd_vio__enable_ssl)(MYSQLND_VIO * const vio);
typedef enum_func_status (*func_mysqlnd_vio__disable_ssl)(MYSQLND_VIO * const vio);
typedef enum_func_status (*func_mysqlnd_vio__network_read)(MYSQLND_VIO * const vio, zend_uchar * const buffer, const size_t count, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info);
-typedef size_t (*func_mysqlnd_vio__network_write)(MYSQLND_VIO * const vio, const zend_uchar * const buf, const size_t count, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info);
+typedef ssize_t (*func_mysqlnd_vio__network_write)(MYSQLND_VIO * const vio, const zend_uchar * const buf, const size_t count, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info);
typedef size_t (*func_mysqlnd_vio__consume_uneaten_data)(MYSQLND_VIO * const vio, enum php_mysqlnd_server_command cmd);
diff --git a/ext/mysqlnd/mysqlnd_vio.c b/ext/mysqlnd/mysqlnd_vio.c
index 99c41f0fe7..a5685e6707 100644
--- a/ext/mysqlnd/mysqlnd_vio.c
+++ b/ext/mysqlnd/mysqlnd_vio.c
@@ -79,14 +79,15 @@ MYSQLND_METHOD(mysqlnd_vio, network_read)(MYSQLND_VIO * const vio, zend_uchar *
{
enum_func_status return_value = PASS;
php_stream * net_stream = vio->data->m.get_stream(vio);
- size_t to_read = count, ret;
+ size_t to_read = count;
zend_uchar * p = buffer;
DBG_ENTER("mysqlnd_vio::network_read");
DBG_INF_FMT("count="MYSQLND_SZ_T_SPEC, count);
while (to_read) {
- if (!(ret = php_stream_read(net_stream, (char *) p, to_read))) {
+ ssize_t ret = php_stream_read(net_stream, (char *) p, to_read);
+ if (ret <= 0) {
DBG_ERR_FMT("Error while reading header from socket");
return_value = FAIL;
break;
@@ -101,11 +102,11 @@ MYSQLND_METHOD(mysqlnd_vio, network_read)(MYSQLND_VIO * const vio, zend_uchar *
/* {{{ mysqlnd_vio::network_write */
-static size_t
+static ssize_t
MYSQLND_METHOD(mysqlnd_vio, network_write)(MYSQLND_VIO * const vio, const zend_uchar * const buffer, const size_t count,
MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info)
{
- size_t ret;
+ ssize_t ret;
DBG_ENTER("mysqlnd_vio::network_write");
DBG_INF_FMT("sending %u bytes", count);
ret = php_stream_write(vio->data->m.get_stream(vio), (char *)buffer, count);
@@ -451,10 +452,14 @@ MYSQLND_METHOD(mysqlnd_vio, consume_uneaten_data)(MYSQLND_VIO * const net, enum
if (PHP_STREAM_OPTION_RETURN_ERR != was_blocked) {
/* Do a read of 1 byte */
- int bytes_consumed;
+ ssize_t bytes_consumed;
do {
- skipped_bytes += (bytes_consumed = php_stream_read(net_stream, tmp_buf, sizeof(tmp_buf)));
+ bytes_consumed = php_stream_read(net_stream, tmp_buf, sizeof(tmp_buf));
+ if (bytes_consumed <= 0) {
+ break;
+ }
+ skipped_bytes += bytes_consumed;
} while (bytes_consumed == sizeof(tmp_buf));
if (was_blocked) {
diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c
index 3910bf815b..41f8f2308f 100644
--- a/ext/openssl/xp_ssl.c
+++ b/ext/openssl/xp_ssl.c
@@ -127,7 +127,7 @@ extern int php_openssl_get_ssl_stream_data_index();
extern int php_openssl_get_x509_list_id(void);
static struct timeval php_openssl_subtract_timeval(struct timeval a, struct timeval b);
static int php_openssl_compare_timeval(struct timeval a, struct timeval b);
-static size_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, size_t count);
+static ssize_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, size_t count);
const php_stream_ops php_openssl_socket_ops;
@@ -2079,13 +2079,13 @@ static int php_openssl_enable_crypto(php_stream *stream,
}
/* }}} */
-static size_t php_openssl_sockop_read(php_stream *stream, char *buf, size_t count) /* {{{ */
+static ssize_t php_openssl_sockop_read(php_stream *stream, char *buf, size_t count) /* {{{ */
{
return php_openssl_sockop_io( 1, stream, buf, count );
}
/* }}} */
-static size_t php_openssl_sockop_write(php_stream *stream, const char *buf, size_t count) /* {{{ */
+static ssize_t php_openssl_sockop_write(php_stream *stream, const char *buf, size_t count) /* {{{ */
{
return php_openssl_sockop_io( 0, stream, (char*)buf, count );
}
@@ -2097,7 +2097,7 @@ static size_t php_openssl_sockop_write(php_stream *stream, const char *buf, size
* for the duration of the operation, using select to do our waits. If we time out, or we have an error
* report that back to PHP
*/
-static size_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, size_t count) /* {{{ */
+static ssize_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, size_t count) /* {{{ */
{
php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t*)stream->abstract;
diff --git a/ext/pdo_oci/oci_statement.c b/ext/pdo_oci/oci_statement.c
index b983f20116..5d01ae1dab 100644
--- a/ext/pdo_oci/oci_statement.c
+++ b/ext/pdo_oci/oci_statement.c
@@ -634,7 +634,7 @@ struct oci_lob_self {
ub4 offset;
};
-static size_t oci_blob_write(php_stream *stream, const char *buf, size_t count)
+static ssize_t oci_blob_write(php_stream *stream, const char *buf, size_t count)
{
struct oci_lob_self *self = (struct oci_lob_self*)stream->abstract;
ub4 amt;
@@ -647,7 +647,7 @@ static size_t oci_blob_write(php_stream *stream, const char *buf, size_t count)
NULL, NULL, 0, SQLCS_IMPLICIT);
if (r != OCI_SUCCESS) {
- return (size_t)-1;
+ return (ssize_t)-1;
}
self->offset += amt;
diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c
index 5aae5d0a38..15b2bd16c9 100644
--- a/ext/pdo_pgsql/pgsql_driver.c
+++ b/ext/pdo_pgsql/pgsql_driver.c
@@ -124,13 +124,13 @@ static int pdo_pgsql_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *in
/* }}} */
/* {{{ pdo_pgsql_create_lob_stream */
-static size_t pgsql_lob_write(php_stream *stream, const char *buf, size_t count)
+static ssize_t pgsql_lob_write(php_stream *stream, const char *buf, size_t count)
{
struct pdo_pgsql_lob_self *self = (struct pdo_pgsql_lob_self*)stream->abstract;
return lo_write(self->conn, self->lfd, (char*)buf, count);
}
-static size_t pgsql_lob_read(php_stream *stream, char *buf, size_t count)
+static ssize_t pgsql_lob_read(php_stream *stream, char *buf, size_t count)
{
struct pdo_pgsql_lob_self *self = (struct pdo_pgsql_lob_self*)stream->abstract;
return lo_read(self->conn, self->lfd, buf, count);
diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c
index 967eb05155..9f51256ac5 100644
--- a/ext/pgsql/pgsql.c
+++ b/ext/pgsql/pgsql.c
@@ -5372,15 +5372,15 @@ PHP_FUNCTION(pg_get_pid)
}
/* }}} */
-static size_t php_pgsql_fd_write(php_stream *stream, const char *buf, size_t count) /* {{{ */
+static ssize_t php_pgsql_fd_write(php_stream *stream, const char *buf, size_t count) /* {{{ */
{
- return 0;
+ return -1;
}
/* }}} */
-static size_t php_pgsql_fd_read(php_stream *stream, char *buf, size_t count) /* {{{ */
+static ssize_t php_pgsql_fd_read(php_stream *stream, char *buf, size_t count) /* {{{ */
{
- return 0;
+ return -1;
}
/* }}} */
diff --git a/ext/pgsql/php_pgsql.h b/ext/pgsql/php_pgsql.h
index 0294ea10a9..cecd2cc95b 100644
--- a/ext/pgsql/php_pgsql.h
+++ b/ext/pgsql/php_pgsql.h
@@ -225,8 +225,8 @@ static void php_pgsql_get_field_info(INTERNAL_FUNCTION_PARAMETERS, int entry_typ
static void php_pgsql_data_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type);
static void php_pgsql_do_async(INTERNAL_FUNCTION_PARAMETERS,int entry_type);
-static size_t php_pgsql_fd_write(php_stream *stream, const char *buf, size_t count);
-static size_t php_pgsql_fd_read(php_stream *stream, char *buf, size_t count);
+static ssize_t php_pgsql_fd_write(php_stream *stream, const char *buf, size_t count);
+static ssize_t php_pgsql_fd_read(php_stream *stream, char *buf, size_t count);
static int php_pgsql_fd_close(php_stream *stream, int close_handle);
static int php_pgsql_fd_flush(php_stream *stream);
static int php_pgsql_fd_set_option(php_stream *stream, int option, int value, void *ptrparam);
diff --git a/ext/phar/dirstream.c b/ext/phar/dirstream.c
index a589e48756..cb14f9e986 100644
--- a/ext/phar/dirstream.c
+++ b/ext/phar/dirstream.c
@@ -89,7 +89,7 @@ static int phar_dir_seek(php_stream *stream, zend_off_t offset, int whence, zend
/**
* Used for readdir() on an opendir()ed phar directory handle
*/
-static size_t phar_dir_read(php_stream *stream, char *buf, size_t count) /* {{{ */
+static ssize_t phar_dir_read(php_stream *stream, char *buf, size_t count) /* {{{ */
{
size_t to_read;
HashTable *data = (HashTable *)stream->abstract;
@@ -118,9 +118,9 @@ static size_t phar_dir_read(php_stream *stream, char *buf, size_t count) /* {{{
/**
* Dummy: Used for writing to a phar directory (i.e. not used)
*/
-static size_t phar_dir_write(php_stream *stream, const char *buf, size_t count) /* {{{ */
+static ssize_t phar_dir_write(php_stream *stream, const char *buf, size_t count) /* {{{ */
{
- return 0;
+ return -1;
}
/* }}} */
diff --git a/ext/phar/dirstream.h b/ext/phar/dirstream.h
index 371c70720a..b14f877fe5 100644
--- a/ext/phar/dirstream.h
+++ b/ext/phar/dirstream.h
@@ -25,8 +25,8 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options
php_url* phar_parse_url(php_stream_wrapper *wrapper, const char *filename, const char *mode, int options);
/* directory handlers */
-static size_t phar_dir_write(php_stream *stream, const char *buf, size_t count);
-static size_t phar_dir_read( php_stream *stream, char *buf, size_t count);
+static ssize_t phar_dir_write(php_stream *stream, const char *buf, size_t count);
+static ssize_t phar_dir_read( php_stream *stream, char *buf, size_t count);
static int phar_dir_close(php_stream *stream, int close_handle);
static int phar_dir_flush(php_stream *stream);
static int phar_dir_seek( php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffset);
diff --git a/ext/phar/stream.c b/ext/phar/stream.c
index 47e37c45a2..d6384b7256 100644
--- a/ext/phar/stream.c
+++ b/ext/phar/stream.c
@@ -361,7 +361,7 @@ static int phar_stream_close(php_stream *stream, int close_handle) /* {{{ */
/**
* used for fread($fp) and company on a fopen()ed phar file handle
*/
-static size_t phar_stream_read(php_stream *stream, char *buf, size_t count) /* {{{ */
+static ssize_t phar_stream_read(php_stream *stream, char *buf, size_t count) /* {{{ */
{
phar_entry_data *data = (phar_entry_data *)stream->abstract;
size_t got;
@@ -375,7 +375,7 @@ static size_t phar_stream_read(php_stream *stream, char *buf, size_t count) /* {
if (entry->is_deleted) {
stream->eof = 1;
- return 0;
+ return -1;
}
/* use our proxy position */
@@ -436,14 +436,14 @@ static int phar_stream_seek(php_stream *stream, zend_off_t offset, int whence, z
/**
* Used for writing to a phar file
*/
-static size_t phar_stream_write(php_stream *stream, const char *buf, size_t count) /* {{{ */
+static ssize_t phar_stream_write(php_stream *stream, const char *buf, size_t count) /* {{{ */
{
phar_entry_data *data = (phar_entry_data *) stream->abstract;
php_stream_seek(data->fp, data->position, SEEK_SET);
if (count != php_stream_write(data->fp, buf, count)) {
php_stream_wrapper_log_error(stream->wrapper, stream->flags, "phar error: Could not write %d characters to \"%s\" in phar \"%s\"", (int) count, data->internal_file->filename, data->phar->fname);
- return 0;
+ return -1;
}
data->position = php_stream_tell(data->fp);
if (data->position > (zend_off_t)data->internal_file->uncompressed_filesize) {
diff --git a/ext/phar/stream.h b/ext/phar/stream.h
index 659ab66618..9746554a07 100644
--- a/ext/phar/stream.h
+++ b/ext/phar/stream.h
@@ -28,8 +28,8 @@ static int phar_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int
static int phar_wrapper_stat(php_stream_wrapper *wrapper, const char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context);
/* file/stream handlers */
-static size_t phar_stream_write(php_stream *stream, const char *buf, size_t count);
-static size_t phar_stream_read( php_stream *stream, char *buf, size_t count);
+static ssize_t phar_stream_write(php_stream *stream, const char *buf, size_t count);
+static ssize_t phar_stream_read( php_stream *stream, char *buf, size_t count);
static int phar_stream_close(php_stream *stream, int close_handle);
static int phar_stream_flush(php_stream *stream);
static int phar_stream_seek( php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffset);
diff --git a/ext/phar/tests/027.phpt b/ext/phar/tests/027.phpt
index 935f92c2d2..89b7252727 100644
--- a/ext/phar/tests/027.phpt
+++ b/ext/phar/tests/027.phpt
@@ -82,7 +82,7 @@ int(4)
int(0)
int(1)
fwrite on dir handle
-int(0)
+bool(false)
bool(false)
opendir edge cases
diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c
index f854faf15d..299fe23a82 100644
--- a/ext/soap/php_http.c
+++ b/ext/soap/php_http.c
@@ -1426,7 +1426,7 @@ static zend_string* get_http_body(php_stream *stream, int close, char *headers)
php_stream_gets(stream, headerbuf, sizeof(headerbuf));
if (sscanf(headerbuf, "%x", &buf_size) > 0 ) {
if (buf_size > 0) {
- int len_size = 0;
+ size_t len_size = 0;
if (http_buf_size + buf_size + 1 < 0) {
if (http_buf) {
@@ -1442,7 +1442,7 @@ static zend_string* get_http_body(php_stream *stream, int close, char *headers)
}
while (len_size < buf_size) {
- int len_read = php_stream_read(stream, http_buf->val + http_buf_size, buf_size - len_size);
+ ssize_t len_read = php_stream_read(stream, http_buf->val + http_buf_size, buf_size - len_size);
if (len_read <= 0) {
/* Error or EOF */
done = TRUE;
@@ -1500,7 +1500,7 @@ static zend_string* get_http_body(php_stream *stream, int close, char *headers)
}
http_buf = zend_string_alloc(header_length, 0);
while (http_buf_size < header_length) {
- int len_read = php_stream_read(stream, http_buf->val + http_buf_size, header_length - http_buf_size);
+ ssize_t len_read = php_stream_read(stream, http_buf->val + http_buf_size, header_length - http_buf_size);
if (len_read <= 0) {
break;
}
@@ -1508,7 +1508,7 @@ static zend_string* get_http_body(php_stream *stream, int close, char *headers)
}
} else if (header_close) {
do {
- int len_read;
+ ssize_t len_read;
if (http_buf) {
http_buf = zend_string_realloc(http_buf, http_buf_size + 4096, 0);
} else {
diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c
index 5ef1b3d9ca..ba308a32c5 100644
--- a/ext/spl/spl_directory.c
+++ b/ext/spl/spl_directory.c
@@ -2859,7 +2859,7 @@ SPL_METHOD(SplFileObject, fscanf)
}
/* }}} */
-/* {{{ proto mixed SplFileObject::fwrite(string str [, int length])
+/* {{{ proto int|false SplFileObject::fwrite(string str [, int length])
Binary-safe file write */
SPL_METHOD(SplFileObject, fwrite)
{
@@ -2867,6 +2867,7 @@ SPL_METHOD(SplFileObject, fwrite)
char *str;
size_t str_len;
zend_long length = 0;
+ ssize_t written;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", &str, &str_len, &length) == FAILURE) {
return;
@@ -2889,13 +2890,18 @@ SPL_METHOD(SplFileObject, fwrite)
RETURN_LONG(0);
}
- RETURN_LONG(php_stream_write(intern->u.file.stream, str, str_len));
+ written = php_stream_write(intern->u.file.stream, str, str_len);
+ if (written < 0) {
+ RETURN_FALSE;
+ }
+ RETURN_LONG(written);
} /* }}} */
SPL_METHOD(SplFileObject, fread)
{
spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(ZEND_THIS);
zend_long length = 0;
+ zend_string *str;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &length) == FAILURE) {
return;
@@ -2911,11 +2917,11 @@ SPL_METHOD(SplFileObject, fread)
RETURN_FALSE;
}
- ZVAL_NEW_STR(return_value, zend_string_alloc(length, 0));
- Z_STRLEN_P(return_value) = php_stream_read(intern->u.file.stream, Z_STRVAL_P(return_value), length);
-
- /* needed because recv/read/gzread doesn't put a null at the end*/
- Z_STRVAL_P(return_value)[Z_STRLEN_P(return_value)] = 0;
+ str = php_stream_read_to_str(intern->u.file.stream, length);
+ if (!str) {
+ RETURN_FALSE;
+ }
+ RETURN_STR(str);
}
/* {{{ proto bool SplFileObject::fstat()
diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c
index 429be63cb6..1c337ee6cb 100644
--- a/ext/sqlite3/sqlite3.c
+++ b/ext/sqlite3/sqlite3.c
@@ -1125,22 +1125,22 @@ typedef struct {
int flags;
} php_stream_sqlite3_data;
-static size_t php_sqlite3_stream_write(php_stream *stream, const char *buf, size_t count)
+static ssize_t php_sqlite3_stream_write(php_stream *stream, const char *buf, size_t count)
{
php_stream_sqlite3_data *sqlite3_stream = (php_stream_sqlite3_data *) stream->abstract;
if (sqlite3_stream->flags & SQLITE_OPEN_READONLY) {
php_error_docref(NULL, E_WARNING, "Can't write to blob stream: is open as read only");
- return 0;
+ return -1;
}
if (sqlite3_stream->position + count > sqlite3_stream->size) {
php_error_docref(NULL, E_WARNING, "It is not possible to increase the size of a BLOB");
- return 0;
+ return -1;
}
if (sqlite3_blob_write(sqlite3_stream->blob, buf, count, sqlite3_stream->position) != SQLITE_OK) {
- return 0;
+ return -1;
}
if (sqlite3_stream->position + count >= sqlite3_stream->size) {
@@ -1154,7 +1154,7 @@ static size_t php_sqlite3_stream_write(php_stream *stream, const char *buf, size
return count;
}
-static size_t php_sqlite3_stream_read(php_stream *stream, char *buf, size_t count)
+static ssize_t php_sqlite3_stream_read(php_stream *stream, char *buf, size_t count)
{
php_stream_sqlite3_data *sqlite3_stream = (php_stream_sqlite3_data *) stream->abstract;
@@ -1164,7 +1164,7 @@ static size_t php_sqlite3_stream_read(php_stream *stream, char *buf, size_t coun
}
if (count) {
if (sqlite3_blob_read(sqlite3_stream->blob, buf, count, sqlite3_stream->position) != SQLITE_OK) {
- return 0;
+ return -1;
}
sqlite3_stream->position += count;
}
diff --git a/ext/sqlite3/tests/sqlite3_30_blobopen.phpt b/ext/sqlite3/tests/sqlite3_30_blobopen.phpt
index 2e9a9f2be2..25d4a7abc2 100644
--- a/ext/sqlite3/tests/sqlite3_30_blobopen.phpt
+++ b/ext/sqlite3/tests/sqlite3_30_blobopen.phpt
@@ -60,7 +60,7 @@ string(9) "TEST TEST"
Writing to read-only stream
Warning: fwrite(): Can't write to blob stream: is open as read only in %s on line %d
-int(0)
+bool(false)
Closing Stream
bool(true)
Opening stream in write mode
@@ -72,7 +72,7 @@ string(9) "ABCD TEST"
Expanding blob size
Warning: fwrite(): It is not possible to increase the size of a BLOB in %s on line %d
-int(0)
+bool(false)
Closing Stream
bool(true)
Closing database
diff --git a/ext/standard/exec.c b/ext/standard/exec.c
index d5ab66daea..322a841c29 100644
--- a/ext/standard/exec.c
+++ b/ext/standard/exec.c
@@ -178,8 +178,9 @@ PHPAPI int php_exec(int type, char *cmd, zval *array, zval *return_value)
RETVAL_EMPTY_STRING();
}
} else {
- while((bufl = php_stream_read(stream, buf, EXEC_INPUT_BUF)) > 0) {
- PHPWRITE(buf, bufl);
+ ssize_t read;
+ while ((read = php_stream_read(stream, buf, EXEC_INPUT_BUF)) > 0) {
+ PHPWRITE(buf, read);
}
}
diff --git a/ext/standard/file.c b/ext/standard/file.c
index cf11faea91..3cd9b62ac0 100644
--- a/ext/standard/file.c
+++ b/ext/standard/file.c
@@ -586,7 +586,7 @@ PHP_FUNCTION(file_put_contents)
char *filename;
size_t filename_len;
zval *data;
- size_t numbytes = 0;
+ ssize_t numbytes = 0;
zend_long flags = 0;
zval *zcontext = NULL;
php_stream_context *context = NULL;
@@ -669,7 +669,7 @@ PHP_FUNCTION(file_put_contents)
case IS_ARRAY:
if (zend_hash_num_elements(Z_ARRVAL_P(data))) {
- size_t bytes_written;
+ ssize_t bytes_written;
zval *tmp;
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(data), tmp) {
@@ -710,7 +710,7 @@ PHP_FUNCTION(file_put_contents)
}
php_stream_close(stream);
- if (numbytes == (size_t)-1) {
+ if (numbytes < 0) {
RETURN_FALSE;
}
@@ -1135,14 +1135,14 @@ PHP_FUNCTION(fscanf)
}
/* }}} */
-/* {{{ proto int fwrite(resource fp, string str [, int length])
+/* {{{ proto int|false fwrite(resource fp, string str [, int length])
Binary-safe file write */
PHPAPI PHP_FUNCTION(fwrite)
{
zval *res;
char *input;
size_t inputlen;
- size_t ret;
+ ssize_t ret;
size_t num_bytes;
zend_long maxlen = 0;
php_stream *stream;
@@ -1169,6 +1169,9 @@ PHPAPI PHP_FUNCTION(fwrite)
PHP_STREAM_TO_ZVAL(stream, res);
ret = php_stream_write(stream, input, num_bytes);
+ if (ret < 0) {
+ RETURN_FALSE;
+ }
RETURN_LONG(ret);
}
@@ -1734,13 +1737,14 @@ safe_to_copy:
}
/* }}} */
-/* {{{ proto string fread(resource fp, int length)
+/* {{{ proto string|false fread(resource fp, int length)
Binary-safe file read */
PHPAPI PHP_FUNCTION(fread)
{
zval *res;
zend_long len;
php_stream *stream;
+ zend_string *str;
ZEND_PARSE_PARAMETERS_START(2, 2)
Z_PARAM_RESOURCE(res)
@@ -1754,15 +1758,13 @@ PHPAPI PHP_FUNCTION(fread)
RETURN_FALSE;
}
- ZVAL_NEW_STR(return_value, zend_string_alloc(len, 0));
- Z_STRLEN_P(return_value) = php_stream_read(stream, Z_STRVAL_P(return_value), len);
-
- /* needed because recv/read/gzread doesn't put a null at the end*/
- Z_STRVAL_P(return_value)[Z_STRLEN_P(return_value)] = 0;
-
- if (Z_STRLEN_P(return_value) < len / 2) {
- Z_STR_P(return_value) = zend_string_truncate(Z_STR_P(return_value), Z_STRLEN_P(return_value), 0);
+ str = php_stream_read_to_str(stream, len);
+ if (!str) {
+ zval_ptr_dtor_str(return_value);
+ RETURN_FALSE;
}
+
+ RETURN_STR(str);
}
/* }}} */
@@ -1815,7 +1817,7 @@ PHP_FUNCTION(fputcsv)
int escape_char = (unsigned char) '\\'; /* allow this to be set as parameter */
php_stream *stream;
zval *fp = NULL, *fields = NULL;
- size_t ret;
+ ssize_t ret;
char *delimiter_str = NULL, *enclosure_str = NULL, *escape_str = NULL;
size_t delimiter_str_len = 0, enclosure_str_len = 0, escape_str_len = 0;
@@ -1867,12 +1869,15 @@ PHP_FUNCTION(fputcsv)
PHP_STREAM_TO_ZVAL(stream, fp);
ret = php_fputcsv(stream, fields, delimiter, enclosure, escape_char);
+ if (ret < 0) {
+ RETURN_FALSE;
+ }
RETURN_LONG(ret);
}
/* }}} */
/* {{{ PHPAPI size_t php_fputcsv(php_stream *stream, zval *fields, char delimiter, char enclosure, int escape_char) */
-PHPAPI size_t php_fputcsv(php_stream *stream, zval *fields, char delimiter, char enclosure, int escape_char)
+PHPAPI ssize_t php_fputcsv(php_stream *stream, zval *fields, char delimiter, char enclosure, int escape_char)
{
int count, i = 0;
size_t ret;
diff --git a/ext/standard/file.h b/ext/standard/file.h
index f479989ea2..bcf4bfc51f 100644
--- a/ext/standard/file.h
+++ b/ext/standard/file.h
@@ -79,7 +79,7 @@ PHPAPI int php_mkdir(const char *dir, zend_long mode);
#define PHP_CSV_NO_ESCAPE EOF
PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, int escape_char, size_t buf_len, char *buf, zval *return_value);
-PHPAPI size_t php_fputcsv(php_stream *stream, zval *fields, char delimiter, char enclosure, int escape_char);
+PHPAPI ssize_t php_fputcsv(php_stream *stream, zval *fields, char delimiter, char enclosure, int escape_char);
#define META_DEF_BUFSIZE 8192
diff --git a/ext/standard/ftp_fopen_wrapper.c b/ext/standard/ftp_fopen_wrapper.c
index 71a511746d..3a7dec4a3b 100644
--- a/ext/standard/ftp_fopen_wrapper.c
+++ b/ext/standard/ftp_fopen_wrapper.c
@@ -613,7 +613,7 @@ errexit:
/* {{{ php_ftp_dirsteam_read
*/
-static size_t php_ftp_dirstream_read(php_stream *stream, char *buf, size_t count)
+static ssize_t php_ftp_dirstream_read(php_stream *stream, char *buf, size_t count)
{
php_stream_dirent *ent = (php_stream_dirent *)buf;
php_stream *innerstream;
@@ -623,7 +623,7 @@ static size_t php_ftp_dirstream_read(php_stream *stream, char *buf, size_t count
innerstream = ((php_ftp_dirstream_data *)stream->abstract)->datastream;
if (count != sizeof(php_stream_dirent)) {
- return 0;
+ return -1;
}
if (php_stream_eof(innerstream)) {
@@ -631,7 +631,7 @@ static size_t php_ftp_dirstream_read(php_stream *stream, char *buf, size_t count
}
if (!php_stream_get_line(innerstream, ent->d_name, sizeof(ent->d_name), &tmp_len)) {
- return 0;
+ return -1;
}
basename = php_basename(ent->d_name, tmp_len, NULL, 0);
diff --git a/ext/standard/md5.c b/ext/standard/md5.c
index d6ec2ffa66..5bf29be286 100644
--- a/ext/standard/md5.c
+++ b/ext/standard/md5.c
@@ -78,7 +78,7 @@ PHP_NAMED_FUNCTION(php_if_md5_file)
unsigned char buf[1024];
unsigned char digest[16];
PHP_MD5_CTX context;
- size_t n;
+ ssize_t n;
php_stream *stream;
ZEND_PARSE_PARAMETERS_START(1, 2)
diff --git a/ext/standard/php_fopen_wrapper.c b/ext/standard/php_fopen_wrapper.c
index 053f8417ec..aba826d7b3 100644
--- a/ext/standard/php_fopen_wrapper.c
+++ b/ext/standard/php_fopen_wrapper.c
@@ -31,17 +31,17 @@
#include "php_fopen_wrappers.h"
#include "SAPI.h"
-static size_t php_stream_output_write(php_stream *stream, const char *buf, size_t count) /* {{{ */
+static ssize_t php_stream_output_write(php_stream *stream, const char *buf, size_t count) /* {{{ */
{
PHPWRITE(buf, count);
return count;
}
/* }}} */
-static size_t php_stream_output_read(php_stream *stream, char *buf, size_t count) /* {{{ */
+static ssize_t php_stream_output_read(php_stream *stream, char *buf, size_t count) /* {{{ */
{
stream->eof = 1;
- return 0;
+ return -1;
}
/* }}} */
@@ -69,16 +69,16 @@ typedef struct php_stream_input { /* {{{ */
} php_stream_input_t;
/* }}} */
-static size_t php_stream_input_write(php_stream *stream, const char *buf, size_t count) /* {{{ */
+static ssize_t php_stream_input_write(php_stream *stream, const char *buf, size_t count) /* {{{ */
{
return -1;
}
/* }}} */
-static size_t php_stream_input_read(php_stream *stream, char *buf, size_t count) /* {{{ */
+static ssize_t php_stream_input_read(php_stream *stream, char *buf, size_t count) /* {{{ */
{
php_stream_input_t *input = stream->abstract;
- size_t read;
+ ssize_t read;
if (!SG(post_read) && SG(read_post_bytes) < (int64_t)(input->position + count)) {
/* read requested data from SAPI */
diff --git a/ext/standard/sha1.c b/ext/standard/sha1.c
index f31dd46be3..148b2dbb24 100644
--- a/ext/standard/sha1.c
+++ b/ext/standard/sha1.c
@@ -68,7 +68,7 @@ PHP_FUNCTION(sha1_file)
unsigned char buf[1024];
unsigned char digest[20];
PHP_SHA1_CTX context;
- size_t n;
+ ssize_t n;
php_stream *stream;
ZEND_PARSE_PARAMETERS_START(1, 2)
diff --git a/ext/standard/tests/file/007_variation1.phpt b/ext/standard/tests/file/007_variation1.phpt
index 6ae441f61e..c05ca6fdf0 100644
--- a/ext/standard/tests/file/007_variation1.phpt
+++ b/ext/standard/tests/file/007_variation1.phpt
@@ -32,7 +32,7 @@ var_dump($file_handle); //Check for the content of handle
var_dump( get_resource_type($file_handle) ); //Check for the type of resource
var_dump( ftell($file_handle) ); //Initial position of file pointer
var_dump( fread($file_handle, 100) ); //Check for read operation
-var_dump( fwrite($file_handle, $string) ); //Check for write operation; fails; expected: 0 bytes
+var_dump( fwrite($file_handle, $string) ); //Check for write operation; fails
var_dump( fclose($file_handle) ); //Check for close operation on the file handle
var_dump( get_resource_type($file_handle) ); //Check whether resource is lost after close operation
echo "*** Done ***\n";
@@ -48,7 +48,7 @@ int(0)
string(20) "line
line of text
li"
-int(0)
+bool(false)
bool(true)
string(7) "Unknown"
*** Done ***
diff --git a/ext/standard/tests/file/007_variation11-win32-mb.phpt b/ext/standard/tests/file/007_variation11-win32-mb.phpt
index b0d84dfe93..c2e42f68d2 100644
--- a/ext/standard/tests/file/007_variation11-win32-mb.phpt
+++ b/ext/standard/tests/file/007_variation11-win32-mb.phpt
@@ -40,7 +40,7 @@ var_dump( ftell($file_handle) ); //Initial file pointer position, expected at t
var_dump( fwrite($file_handle, $string) ); //Check for write operation; passes; expected:size of the $string
var_dump( ftell($file_handle) ); //File pointer position after write operation, expected at the end of the file
rewind($file_handle);
-var_dump( fread($file_handle, 100) ); //Check for read operation; fails; expected: empty string
+var_dump( fread($file_handle, 100) ); //Check for read operation; fails; expected: false
var_dump( ftell($file_handle) ); //File pointer position after read operation, expected at the beginning of the file
var_dump( fclose($file_handle) ); //Check for close operation on the file handle
var_dump( get_resource_type($file_handle) ); //Check whether resource is lost after close operation
@@ -68,7 +68,7 @@ string(6) "stream"
int(0)
int(37)
int(37)
-string(0) ""
+bool(false)
int(0)
bool(true)
string(7) "Unknown"
diff --git a/ext/standard/tests/file/007_variation11-win32.phpt b/ext/standard/tests/file/007_variation11-win32.phpt
index 436b22f8eb..7b6ae81465 100644
--- a/ext/standard/tests/file/007_variation11-win32.phpt
+++ b/ext/standard/tests/file/007_variation11-win32.phpt
@@ -40,7 +40,7 @@ var_dump( ftell($file_handle) ); //Initial file pointer position, expected at t
var_dump( fwrite($file_handle, $string) ); //Check for write operation; passes; expected:size of the $string
var_dump( ftell($file_handle) ); //File pointer position after write operation, expected at the end of the file
rewind($file_handle);
-var_dump( fread($file_handle, 100) ); //Check for read operation; fails; expected: empty string
+var_dump( fread($file_handle, 100) ); //Check for read operation; fails; expected: false
var_dump( ftell($file_handle) ); //File pointer position after read operation, expected at the beginning of the file
var_dump( fclose($file_handle) ); //Check for close operation on the file handle
var_dump( get_resource_type($file_handle) ); //Check whether resource is lost after close operation
@@ -66,7 +66,7 @@ string(6) "stream"
int(0)
int(37)
int(37)
-string(0) ""
+bool(false)
int(0)
bool(true)
string(7) "Unknown"
diff --git a/ext/standard/tests/file/007_variation11.phpt b/ext/standard/tests/file/007_variation11.phpt
index 9c6bff1417..3748f6f962 100644
--- a/ext/standard/tests/file/007_variation11.phpt
+++ b/ext/standard/tests/file/007_variation11.phpt
@@ -40,7 +40,7 @@ var_dump( ftell($file_handle) ); //Initial file pointer position, expected at t
var_dump( fwrite($file_handle, $string) ); //Check for write operation; passes; expected:size of the $string
var_dump( ftell($file_handle) ); //File pointer position after write operation, expected at the end of the file
rewind($file_handle);
-var_dump( fread($file_handle, 100) ); //Check for read operation; fails; expected: empty string
+var_dump( fread($file_handle, 100) ); //Check for read operation; fails; expected: false
var_dump( ftell($file_handle) ); //File pointer position after read operation, expected at the beginning of the file
var_dump( fclose($file_handle) ); //Check for close operation on the file handle
var_dump( get_resource_type($file_handle) ); //Check whether resource is lost after close operation
@@ -66,7 +66,7 @@ string(6) "stream"
int(0)
int(37)
int(37)
-string(0) ""
+bool(false)
int(0)
bool(true)
string(7) "Unknown"
diff --git a/ext/standard/tests/file/007_variation13-win32.phpt b/ext/standard/tests/file/007_variation13-win32.phpt
index 12484cfcde..72292d057f 100644
--- a/ext/standard/tests/file/007_variation13-win32.phpt
+++ b/ext/standard/tests/file/007_variation13-win32.phpt
@@ -37,7 +37,7 @@ var_dump($file_handle); //Check for the content of handle
var_dump( get_resource_type($file_handle) ); //Check for the type of resource
var_dump( fwrite($file_handle, $string) ); //Check for write operation; passes; expected:size of the $string
rewind($file_handle);
-var_dump( fread($file_handle, 100) ); //Check for read operation; fails; expected: empty string
+var_dump( fread($file_handle, 100) ); //Check for read operation; fails; expected: false
var_dump( ftell($file_handle) ); //File pointer position after read operation, expected at the end of the file
var_dump( fclose($file_handle) ); //Check for close operation on the file handle
var_dump( get_resource_type($file_handle) ); //Check whether resource is lost after close operation
@@ -56,7 +56,7 @@ unlink(__DIR__."/007_variation13.tmp");
resource(%d) of type (stream)
string(6) "stream"
int(37)
-string(0) ""
+bool(false)
int(0)
bool(true)
string(7) "Unknown"
diff --git a/ext/standard/tests/file/007_variation13.phpt b/ext/standard/tests/file/007_variation13.phpt
index 98be673d8a..a35b244c93 100644
--- a/ext/standard/tests/file/007_variation13.phpt
+++ b/ext/standard/tests/file/007_variation13.phpt
@@ -37,7 +37,7 @@ var_dump($file_handle); //Check for the content of handle
var_dump( get_resource_type($file_handle) ); //Check for the type of resource
var_dump( fwrite($file_handle, $string) ); //Check for write operation; passes; expected:size of the $string
rewind($file_handle);
-var_dump( fread($file_handle, 100) ); //Check for read operation; fails; expected: empty string
+var_dump( fread($file_handle, 100) ); //Check for read operation; fails; expected: false
var_dump( ftell($file_handle) ); //File pointer position after read operation, expected at the end of the file
var_dump( fclose($file_handle) ); //Check for close operation on the file handle
var_dump( get_resource_type($file_handle) ); //Check whether resource is lost after close operation
@@ -56,7 +56,7 @@ unlink(__DIR__."/007_variation13.tmp");
resource(%d) of type (stream)
string(6) "stream"
int(37)
-string(0) ""
+bool(false)
int(0)
bool(true)
string(7) "Unknown"
diff --git a/ext/standard/tests/file/007_variation15.phpt b/ext/standard/tests/file/007_variation15.phpt
index 39a7e506e5..41fa58f02c 100644
--- a/ext/standard/tests/file/007_variation15.phpt
+++ b/ext/standard/tests/file/007_variation15.phpt
@@ -32,7 +32,7 @@ var_dump( ftell($file_handle) ); //Initial file pointer position, expected at t
var_dump( fwrite($file_handle, $string) ); //Check for write operation; passes; expected:size of the $string
var_dump( ftell($file_handle) ); //File pointer position after write operation, expected at the end of the file
rewind($file_handle);
-var_dump( fread($file_handle, 100) ); //Check for read operation; fails; expected: empty string
+var_dump( fread($file_handle, 100) ); //Check for read operation; fails; expected: false
var_dump( ftell($file_handle) ); //File pointer position after read operation, expected at the beginning of the file
var_dump( fclose($file_handle) ); //Check for close operation on the file handle
var_dump( get_resource_type($file_handle) ); //Check whether resource is lost after close operation
@@ -49,7 +49,7 @@ string(6) "stream"
int(0)
int(37)
int(37)
-string(0) ""
+bool(false)
int(0)
bool(true)
string(7) "Unknown"
diff --git a/ext/standard/tests/file/007_variation17.phpt b/ext/standard/tests/file/007_variation17.phpt
index d468ad0452..780ea96365 100644
--- a/ext/standard/tests/file/007_variation17.phpt
+++ b/ext/standard/tests/file/007_variation17.phpt
@@ -32,7 +32,7 @@ var_dump($file_handle); //Check for the content of handle
var_dump( get_resource_type($file_handle) ); //Check for the type of resource
var_dump( ftell($file_handle) ); //Initial position of file pointer
var_dump( fread($file_handle, 100) ); //Check for read operation
-var_dump( fwrite($file_handle, $string) ); //Check for write operation; fails; expected: 0 bytes
+var_dump( fwrite($file_handle, $string) ); //Check for write operation; fails
var_dump( fclose($file_handle) ); //Check for close operation on the file handle
var_dump( get_resource_type($file_handle) ); //Check whether resource is lost after close operation
echo "*** Done ***\n";
@@ -48,7 +48,7 @@ int(0)
string(20) "line
line of text
li"
-int(0)
+bool(false)
bool(true)
string(7) "Unknown"
*** Done ***
diff --git a/ext/standard/tests/file/007_variation19.phpt b/ext/standard/tests/file/007_variation19.phpt
index d6d3a3d761..b10b4b5069 100644
--- a/ext/standard/tests/file/007_variation19.phpt
+++ b/ext/standard/tests/file/007_variation19.phpt
@@ -35,7 +35,7 @@ var_dump( ftell($file_handle) ); //Initial file pointer position, expected at t
var_dump( fwrite($file_handle, $string) ); //Check for write operation; passes; expected:size of the $string
var_dump( ftell($file_handle) ); //File pointer position after write operation, expected at the end of the file
rewind($file_handle);
-var_dump( fread($file_handle, 100) ); //Check for read operation; fails; expected: empty string
+var_dump( fread($file_handle, 100) ); //Check for read operation; fails; expected: false
var_dump( ftell($file_handle) ); //File pointer position after read operation, expected at the beginning of the file
var_dump( fclose($file_handle) ); //Check for close operation on the file handle
var_dump( get_resource_type($file_handle) ); //Check whether resource is lost after close operation
@@ -61,7 +61,7 @@ string(6) "stream"
int(0)
int(37)
int(37)
-string(0) ""
+bool(false)
int(0)
bool(true)
string(7) "Unknown"
diff --git a/ext/standard/tests/file/007_variation21.phpt b/ext/standard/tests/file/007_variation21.phpt
index 92d8f1dee7..fec0db24e4 100644
--- a/ext/standard/tests/file/007_variation21.phpt
+++ b/ext/standard/tests/file/007_variation21.phpt
@@ -32,7 +32,7 @@ var_dump($file_handle); //Check for the content of handle
var_dump( get_resource_type($file_handle) ); //Check for the type of resource
var_dump( fwrite($file_handle, $string) ); //Check for write operation; passes; expected:size of the $string
rewind($file_handle);
-var_dump( fread($file_handle, 100) ); //Check for read operation; fails; expected: empty string
+var_dump( fread($file_handle, 100) ); //Check for read operation; fails; expected: false
var_dump( ftell($file_handle) ); //File pointer position after read operation, expected at the end of the file
var_dump( fclose($file_handle) ); //Check for close operation on the file handle
var_dump( get_resource_type($file_handle) ); //Check whether resource is lost after close operation
@@ -51,7 +51,7 @@ unlink(__DIR__."/007_variation21.tmp");
resource(%d) of type (stream)
string(6) "stream"
int(37)
-string(0) ""
+bool(false)
int(0)
bool(true)
string(7) "Unknown"
diff --git a/ext/standard/tests/file/007_variation23.phpt b/ext/standard/tests/file/007_variation23.phpt
index c4b4aa86a5..81060fa1b1 100644
--- a/ext/standard/tests/file/007_variation23.phpt
+++ b/ext/standard/tests/file/007_variation23.phpt
@@ -32,7 +32,7 @@ var_dump( ftell($file_handle) ); //Initial file pointer position, expected at t
var_dump( fwrite($file_handle, $string) ); //Check for write operation; passes; expected:size of the $string
var_dump( ftell($file_handle) ); //File pointer position after write operation, expected at the end of the file
rewind($file_handle);
-var_dump( fread($file_handle, 100) ); //Check for read operation; fails; expected: empty string
+var_dump( fread($file_handle, 100) ); //Check for read operation; fails; expected: false
var_dump( ftell($file_handle) ); //File pointer position after read operation, expected at the beginning of the file
var_dump( fclose($file_handle) ); //Check for close operation on the file handle
var_dump( get_resource_type($file_handle) ); //Check whether resource is lost after close operation
@@ -49,7 +49,7 @@ string(6) "stream"
int(0)
int(37)
int(37)
-string(0) ""
+bool(false)
int(0)
bool(true)
string(7) "Unknown"
diff --git a/ext/standard/tests/file/007_variation3.phpt b/ext/standard/tests/file/007_variation3.phpt
index 344a774f87..3572ca746f 100644
--- a/ext/standard/tests/file/007_variation3.phpt
+++ b/ext/standard/tests/file/007_variation3.phpt
@@ -35,7 +35,7 @@ var_dump( ftell($file_handle) ); //Initial file pointer position, expected at t
var_dump( fwrite($file_handle, $string) ); //Check for write operation; passes; expected:size of the $string
var_dump( ftell($file_handle) ); //File pointer position after write operation, expected at the end of the file
rewind($file_handle);
-var_dump( fread($file_handle, 100) ); //Check for read operation; fails; expected: empty string
+var_dump( fread($file_handle, 100) ); //Check for read operation; fails; expected: false
var_dump( ftell($file_handle) ); //File pointer position after read operation, expected at the beginning of the file
var_dump( fclose($file_handle) ); //Check for close operation on the file handle
var_dump( get_resource_type($file_handle) ); //Check whether resource is lost after close operation
@@ -61,7 +61,7 @@ string(6) "stream"
int(0)
int(37)
int(37)
-string(0) ""
+bool(false)
int(0)
bool(true)
string(7) "Unknown"
diff --git a/ext/standard/tests/file/007_variation5.phpt b/ext/standard/tests/file/007_variation5.phpt
index 1c50e96f71..40f0794c8b 100644
--- a/ext/standard/tests/file/007_variation5.phpt
+++ b/ext/standard/tests/file/007_variation5.phpt
@@ -32,7 +32,7 @@ var_dump($file_handle); //Check for the content of handle
var_dump( get_resource_type($file_handle) ); //Check for the type of resource
var_dump( fwrite($file_handle, $string) ); //Check for write operation; passes; expected:size of the $string
rewind($file_handle);
-var_dump( fread($file_handle, 100) ); //Check for read operation; fails; expected: empty string
+var_dump( fread($file_handle, 100) ); //Check for read operation; fails; expected: false
var_dump( ftell($file_handle) ); //File pointer position after read operation, expected at the end of the file
var_dump( fclose($file_handle) ); //Check for close operation on the file handle
var_dump( get_resource_type($file_handle) ); //Check whether resource is lost after close operation
@@ -51,7 +51,7 @@ unlink(__DIR__."/007_variation5.tmp");
resource(%d) of type (stream)
string(6) "stream"
int(37)
-string(0) ""
+bool(false)
int(0)
bool(true)
string(7) "Unknown"
diff --git a/ext/standard/tests/file/007_variation7.phpt b/ext/standard/tests/file/007_variation7.phpt
index 974bfe0c8c..322e1ee44c 100644
--- a/ext/standard/tests/file/007_variation7.phpt
+++ b/ext/standard/tests/file/007_variation7.phpt
@@ -32,7 +32,7 @@ var_dump( ftell($file_handle) ); //Initial file pointer position, expected at t
var_dump( fwrite($file_handle, $string) ); //Check for write operation; passes; expected:size of the $string
var_dump( ftell($file_handle) ); //File pointer position after write operation, expected at the end of the file
rewind($file_handle);
-var_dump( fread($file_handle, 100) ); //Check for read operation; fails; expected: empty string
+var_dump( fread($file_handle, 100) ); //Check for read operation; fails; expected: false
var_dump( ftell($file_handle) ); //File pointer position after read operation, expected at the beginning of the file
var_dump( fclose($file_handle) ); //Check for close operation on the file handle
var_dump( get_resource_type($file_handle) ); //Check whether resource is lost after close operation
@@ -49,7 +49,7 @@ string(6) "stream"
int(0)
int(37)
int(37)
-string(0) ""
+bool(false)
int(0)
bool(true)
string(7) "Unknown"
diff --git a/ext/standard/tests/file/007_variation9.phpt b/ext/standard/tests/file/007_variation9.phpt
index cd0fd63c75..a730240fa3 100644
--- a/ext/standard/tests/file/007_variation9.phpt
+++ b/ext/standard/tests/file/007_variation9.phpt
@@ -32,7 +32,7 @@ var_dump($file_handle); //Check for the content of handle
var_dump( get_resource_type($file_handle) ); //Check for the type of resource
var_dump( ftell($file_handle) ); //Initial position of file pointer
var_dump( fread($file_handle, 100) ); //Check for read operation
-var_dump( fwrite($file_handle, $string) ); //Check for write operation; fails; expected: 0 bytes
+var_dump( fwrite($file_handle, $string) ); //Check for write operation; fails
var_dump( fclose($file_handle) ); //Check for close operation on the file handle
var_dump( get_resource_type($file_handle) ); //Check whether resource is lost after close operation
echo "*** Done ***\n";
@@ -48,7 +48,7 @@ int(0)
string(20) "line
line of text
li"
-int(0)
+bool(false)
bool(true)
string(7) "Unknown"
*** Done ***
diff --git a/ext/standard/tests/file/fputcsv_variation14.phpt b/ext/standard/tests/file/fputcsv_variation14.phpt
index b4454906f5..abc794de34 100644
--- a/ext/standard/tests/file/fputcsv_variation14.phpt
+++ b/ext/standard/tests/file/fputcsv_variation14.phpt
@@ -89,7 +89,7 @@ echo "Done\n";
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
@@ -99,7 +99,7 @@ string(0) ""
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
@@ -109,7 +109,7 @@ string(0) ""
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
@@ -119,7 +119,7 @@ string(0) ""
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
@@ -129,7 +129,7 @@ string(0) ""
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
@@ -139,7 +139,7 @@ string(0) ""
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
@@ -149,7 +149,7 @@ string(0) ""
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
@@ -159,7 +159,7 @@ string(0) ""
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
@@ -169,7 +169,7 @@ string(0) ""
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
@@ -179,7 +179,7 @@ string(0) ""
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
@@ -189,7 +189,7 @@ string(0) ""
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
@@ -199,7 +199,7 @@ string(0) ""
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
@@ -209,7 +209,7 @@ string(0) ""
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
@@ -219,7 +219,7 @@ string(0) ""
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
@@ -229,7 +229,7 @@ string(0) ""
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
@@ -239,7 +239,7 @@ string(0) ""
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
@@ -249,7 +249,7 @@ string(0) ""
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
@@ -259,7 +259,7 @@ string(0) ""
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
@@ -269,7 +269,7 @@ string(0) ""
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
@@ -279,7 +279,7 @@ string(0) ""
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
@@ -289,7 +289,7 @@ string(0) ""
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
@@ -299,7 +299,7 @@ string(0) ""
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
@@ -309,7 +309,7 @@ string(0) ""
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
@@ -319,7 +319,7 @@ string(0) ""
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
@@ -329,7 +329,7 @@ string(0) ""
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
@@ -339,7 +339,7 @@ string(0) ""
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
@@ -349,7 +349,7 @@ string(0) ""
Notice: fputcsv(): delimiter must be a single character in %s on line %d
Notice: fputcsv(): enclosure must be a single character in %s on line %d
-int(0)
+bool(false)
int(0)
bool(false)
string(0) ""
diff --git a/ext/standard/tests/file/fwrite.phpt b/ext/standard/tests/file/fwrite.phpt
index 4cd8a2f08a..c3a475942b 100644
--- a/ext/standard/tests/file/fwrite.phpt
+++ b/ext/standard/tests/file/fwrite.phpt
@@ -26,7 +26,7 @@ echo "Done\n";
?>
--EXPECTF--
int(0)
-int(0)
+bool(false)
int(0)
int(4)
int(0)
diff --git a/ext/standard/tests/file/fwrite_variation1-win32-mb.phpt b/ext/standard/tests/file/fwrite_variation1-win32-mb.phpt
index a472dfb2a8..ec3cdd756a 100644
--- a/ext/standard/tests/file/fwrite_variation1-win32-mb.phpt
+++ b/ext/standard/tests/file/fwrite_variation1-win32-mb.phpt
@@ -84,11 +84,11 @@ echo "Done\n";
-- Testing fwrite() with file having content of type numeric --
-- Opening file in r --
int(0)
-int(0)
+bool(false)
int(0)
bool(false)
int(2)
-int(0)
+bool(false)
int(2)
bool(false)
bool(true)
@@ -96,11 +96,11 @@ int(1024)
string(32) "950b7457d1deb6332f2fc5d42f3129d6"
-- Opening file in rb --
int(0)
-int(0)
+bool(false)
int(0)
bool(false)
int(2)
-int(0)
+bool(false)
int(2)
bool(false)
bool(true)
@@ -108,11 +108,11 @@ int(1024)
string(32) "950b7457d1deb6332f2fc5d42f3129d6"
-- Opening file in rt --
int(0)
-int(0)
+bool(false)
int(0)
bool(false)
int(2)
-int(0)
+bool(false)
int(2)
bool(false)
bool(true)
@@ -122,11 +122,11 @@ string(32) "950b7457d1deb6332f2fc5d42f3129d6"
-- Testing fwrite() with file having content of type text --
-- Opening file in r --
int(0)
-int(0)
+bool(false)
int(0)
bool(false)
int(2)
-int(0)
+bool(false)
int(2)
bool(false)
bool(true)
@@ -134,11 +134,11 @@ int(1024)
string(32) "e486000c4c8452774f746a27658d87fa"
-- Opening file in rb --
int(0)
-int(0)
+bool(false)
int(0)
bool(false)
int(2)
-int(0)
+bool(false)
int(2)
bool(false)
bool(true)
@@ -146,11 +146,11 @@ int(1024)
string(32) "e486000c4c8452774f746a27658d87fa"
-- Opening file in rt --
int(0)
-int(0)
+bool(false)
int(0)
bool(false)
int(2)
-int(0)
+bool(false)
int(2)
bool(false)
bool(true)
@@ -160,11 +160,11 @@ string(32) "e486000c4c8452774f746a27658d87fa"
-- Testing fwrite() with file having content of type text_with_new_line --
-- Opening file in r --
int(0)
-int(0)
+bool(false)
int(0)
bool(false)
int(2)
-int(0)
+bool(false)
int(2)
bool(false)
bool(true)
@@ -172,11 +172,11 @@ int(1024)
string(32) "b09c8026a64a88d36d4c2f17983964bb"
-- Opening file in rb --
int(0)
-int(0)
+bool(false)
int(0)
bool(false)
int(2)
-int(0)
+bool(false)
int(2)
bool(false)
bool(true)
@@ -184,11 +184,11 @@ int(1024)
string(32) "b09c8026a64a88d36d4c2f17983964bb"
-- Opening file in rt --
int(0)
-int(0)
+bool(false)
int(0)
bool(false)
int(2)
-int(0)
+bool(false)
int(2)
bool(false)
bool(true)
@@ -198,11 +198,11 @@ string(32) "b09c8026a64a88d36d4c2f17983964bb"
-- Testing fwrite() with file having content of type alphanumeric --
-- Opening file in r --
int(0)
-int(0)
+bool(false)
int(0)
bool(false)
int(2)
-int(0)
+bool(false)
int(2)
bool(false)
bool(true)
@@ -210,11 +210,11 @@ int(1024)
string(32) "3fabd48d8eaa65c14e0d93d6880c560c"
-- Opening file in rb --
int(0)
-int(0)
+bool(false)
int(0)
bool(false)
int(2)
-int(0)
+bool(false)
int(2)
bool(false)
bool(true)
@@ -222,11 +222,11 @@ int(1024)
string(32) "3fabd48d8eaa65c14e0d93d6880c560c"
-- Opening file in rt --
int(0)
-int(0)
+bool(false)
int(0)
bool(false)
int(2)
-int(0)
+bool(false)
int(2)
bool(false)
bool(true)
diff --git a/ext/standard/tests/file/fwrite_variation1.phpt b/ext/standard/tests/file/fwrite_variation1.phpt
index 22e0f6823f..c141aa5880 100644
--- a/ext/standard/tests/file/fwrite_variation1.phpt
+++ b/ext/standard/tests/file/fwrite_variation1.phpt
@@ -76,11 +76,11 @@ echo "Done\n";
-- Testing fwrite() with file having content of type numeric --
-- Opening file in r --
int(0)
-int(0)
+bool(false)
int(0)
bool(false)
int(2)
-int(0)
+bool(false)
int(2)
bool(false)
bool(true)
@@ -88,11 +88,11 @@ int(1024)
string(32) "950b7457d1deb6332f2fc5d42f3129d6"
-- Opening file in rb --
int(0)
-int(0)
+bool(false)
int(0)
bool(false)
int(2)
-int(0)
+bool(false)
int(2)
bool(false)
bool(true)
@@ -100,11 +100,11 @@ int(1024)
string(32) "950b7457d1deb6332f2fc5d42f3129d6"
-- Opening file in rt --
int(0)
-int(0)
+bool(false)
int(0)
bool(false)
int(2)
-int(0)
+bool(false)
int(2)
bool(false)
bool(true)
@@ -114,11 +114,11 @@ string(32) "950b7457d1deb6332f2fc5d42f3129d6"
-- Testing fwrite() with file having content of type text --
-- Opening file in r --
int(0)
-int(0)
+bool(false)
int(0)
bool(false)
int(2)
-int(0)
+bool(false)
int(2)
bool(false)
bool(true)
@@ -126,11 +126,11 @@ int(1024)
string(32) "e486000c4c8452774f746a27658d87fa"
-- Opening file in rb --
int(0)
-int(0)
+bool(false)
int(0)
bool(false)
int(2)
-int(0)
+bool(false)
int(2)
bool(false)
bool(true)
@@ -138,11 +138,11 @@ int(1024)
string(32) "e486000c4c8452774f746a27658d87fa"
-- Opening file in rt --
int(0)
-int(0)
+bool(false)
int(0)
bool(false)
int(2)
-int(0)
+bool(false)
int(2)
bool(false)
bool(true)
@@ -152,11 +152,11 @@ string(32) "e486000c4c8452774f746a27658d87fa"
-- Testing fwrite() with file having content of type text_with_new_line --
-- Opening file in r --
int(0)
-int(0)
+bool(false)
int(0)
bool(false)
int(2)
-int(0)
+bool(false)
int(2)
bool(false)
bool(true)
@@ -164,11 +164,11 @@ int(1024)
string(32) "b09c8026a64a88d36d4c2f17983964bb"
-- Opening file in rb --
int(0)
-int(0)
+bool(false)
int(0)
bool(false)
int(2)
-int(0)
+bool(false)
int(2)
bool(false)
bool(true)
@@ -176,11 +176,11 @@ int(1024)
string(32) "b09c8026a64a88d36d4c2f17983964bb"
-- Opening file in rt --
int(0)
-int(0)
+bool(false)
int(0)
bool(false)
int(2)
-int(0)
+bool(false)
int(2)
bool(false)
bool(true)
@@ -190,11 +190,11 @@ string(32) "b09c8026a64a88d36d4c2f17983964bb"
-- Testing fwrite() with file having content of type alphanumeric --
-- Opening file in r --
int(0)
-int(0)
+bool(false)
int(0)
bool(false)
int(2)
-int(0)
+bool(false)
int(2)
bool(false)
bool(true)
@@ -202,11 +202,11 @@ int(1024)
string(32) "3fabd48d8eaa65c14e0d93d6880c560c"
-- Opening file in rb --
int(0)
-int(0)
+bool(false)
int(0)
bool(false)
int(2)
-int(0)
+bool(false)
int(2)
bool(false)
bool(true)
@@ -214,11 +214,11 @@ int(1024)
string(32) "3fabd48d8eaa65c14e0d93d6880c560c"
-- Opening file in rt --
int(0)
-int(0)
+bool(false)
int(0)
bool(false)
int(2)
-int(0)
+bool(false)
int(2)
bool(false)
bool(true)
diff --git a/ext/standard/tests/network/bug20134.phpt b/ext/standard/tests/network/bug20134.phpt
index 8d97f5f6e8..260878d474 100644
--- a/ext/standard/tests/network/bug20134.phpt
+++ b/ext/standard/tests/network/bug20134.phpt
@@ -21,4 +21,4 @@ else {
?>
--EXPECT--
int(1)
-string(0) ""
+bool(false)
diff --git a/ext/standard/tests/streams/bug44818.phpt b/ext/standard/tests/streams/bug44818.phpt
index 7bd9fe5168..0446dfd3be 100644
--- a/ext/standard/tests/streams/bug44818.phpt
+++ b/ext/standard/tests/streams/bug44818.phpt
@@ -17,7 +17,7 @@ test("php://temp","w");
--EXPECTF--
php://memory, r
resource(%d) of type (stream)
-int(0)
+bool(false)
int(0)
string(0) ""
php://memory, r+
@@ -27,7 +27,7 @@ int(0)
string(3) "foo"
php://temp, r
resource(%d) of type (stream)
-int(0)
+bool(false)
int(0)
string(0) ""
php://temp, w
diff --git a/ext/standard/tests/streams/eagain_is_not_an_error.phpt b/ext/standard/tests/streams/eagain_is_not_an_error.phpt
new file mode 100644
index 0000000000..7bc50dc9b7
--- /dev/null
+++ b/ext/standard/tests/streams/eagain_is_not_an_error.phpt
@@ -0,0 +1,16 @@
+--TEST--
+EAGAIN/EWOULDBLOCK on a non-blocking socket should not result in an error return value
+--SKIPIF--
+<?php
+if (substr(PHP_OS, 0, 3) == 'WIN') die('skip not for Windows');
+?>
+--FILE--
+<?php
+
+$sockets = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
+stream_set_blocking($sockets[0], false);
+var_dump(fread($sockets[0], 100));
+
+?>
+--EXPECT--
+string(0) ""
diff --git a/ext/standard/tests/streams/nonblocking_stdin.phpt b/ext/standard/tests/streams/nonblocking_stdin.phpt
new file mode 100644
index 0000000000..0e22190fb7
--- /dev/null
+++ b/ext/standard/tests/streams/nonblocking_stdin.phpt
@@ -0,0 +1,11 @@
+--TEST--
+Read from non-blocking stdio stream should not error
+--FILE--
+<?php
+
+stream_set_blocking(STDIN, false);
+var_dump(fread(STDIN, 1));
+
+?>
+--EXPECT--
+string(0) ""
diff --git a/ext/zip/zip_stream.c b/ext/zip/zip_stream.c
index f24a91ff85..bce62f5614 100644
--- a/ext/zip/zip_stream.c
+++ b/ext/zip/zip_stream.c
@@ -45,7 +45,7 @@ struct php_zip_stream_data_t {
/* {{{ php_zip_ops_read */
-static size_t php_zip_ops_read(php_stream *stream, char *buf, size_t count)
+static ssize_t php_zip_ops_read(php_stream *stream, char *buf, size_t count)
{
ssize_t n = 0;
STREAM_DATA_FROM_STREAM();
@@ -65,7 +65,7 @@ static size_t php_zip_ops_read(php_stream *stream, char *buf, size_t count)
php_error_docref(NULL, E_WARNING, "Zip stream error: %s", zip_error_strerror(err));
zip_error_fini(err);
#endif
- return 0;
+ return -1;
}
/* cast count to signed value to avoid possibly negative n
* being cast to unsigned value */
@@ -75,15 +75,15 @@ static size_t php_zip_ops_read(php_stream *stream, char *buf, size_t count)
self->cursor += n;
}
}
- return (n < 1 ? 0 : (size_t)n);
+ return n;
}
/* }}} */
/* {{{ php_zip_ops_write */
-static size_t php_zip_ops_write(php_stream *stream, const char *buf, size_t count)
+static ssize_t php_zip_ops_write(php_stream *stream, const char *buf, size_t count)
{
if (!stream) {
- return 0;
+ return -1;
}
return count;
diff --git a/ext/zlib/tests/bug71417.phpt b/ext/zlib/tests/bug71417.phpt
new file mode 100644
index 0000000000..717b2effe4
--- /dev/null
+++ b/ext/zlib/tests/bug71417.phpt
@@ -0,0 +1,82 @@
+--TEST--
+Bug #71417: fread() does not detect decoding errors from filter zlib.inflate
+--FILE--
+<?php
+
+function test($case) {
+ $plain = "The quick brown fox jumps over the lazy dog.";
+ $fn = "bug71417.gz";
+ $compressed = (string) gzencode($plain);
+
+ if ($case == 1) {
+ // 1. Set a random byte in the middle of the compressed data.
+ // $ php test-zlib-inflate.php
+ // --> read: string(0) ""
+ // --> read: string(44) "The quick brown fox jumps over the lazx8dog."
+ // $ gzip test-zlib-inflate.gz
+ // gzip: test-zlib-inflate.gz: invalid compressed data--crc error
+ $compressed[strlen($compressed) - 15] = 'X';
+ } else if ($case == 2) {
+ // 2. Truncate the compressed data.
+ // $ php test-zlib-inflate.php
+ // --> read: string(32) "The quick brown fox jumps over t"
+ // $ gzip test-zlib-inflate.gz
+ // gzip: test-zlib-inflate.gz: unexpected end of file
+ $compressed = substr($compressed, 0, strlen($compressed) - 20);
+ } else if ($case == 3) {
+ // 3. Corrupted final CRC.
+ // $ php test-zlib-inflate.php
+ // --> read: string(0) ""
+ // --> read: string(44) "The quick brown fox jumps over the lazy dog."
+ // $ gzip test-zlib-inflate.gz
+ // gzip: test-zlib-inflate.gz: invalid compressed data--crc error
+ $compressed[strlen($compressed)-5] = 'X';
+ } else if ($case == 4) {
+ // 4. Corrupted final length.
+ // $ php test-zlib-inflate.phpread: string(0) ""
+ // read: string(44) "The quick brown fox jumps over the lazy dog."
+ // $ gunzip test-zlib-inflate.gz
+ // gzip: test-zlib-inflate.gz: invalid compressed data--length error
+ $compressed[strlen($compressed)-2] = 'X';
+ }
+
+ // The gzdecode() function applied to the corrupted compressed data always
+ // detects the error:
+ // --> gzdecode(): PHP Fatal error: Uncaught ErrorException: gzdecode(): data error in ...
+ echo "gzdecode(): ", rawurldecode(gzdecode($compressed)), "\n";
+
+ file_put_contents($fn, $compressed);
+
+ $r = fopen($fn, "r");
+ stream_filter_append($r, 'zlib.inflate', STREAM_FILTER_READ, array('window' => 15+16));
+ while (!feof($r)) {
+ $s = fread($r, 100);
+ echo "read: "; var_dump($s);
+ }
+ fclose($r);
+ unlink($fn);
+}
+
+test(1);
+test(2);
+test(3);
+test(4);
+
+?>
+--EXPECTF--
+gzdecode():
+Warning: gzdecode(): data error in %s on line %d
+
+read: bool(false)
+gzdecode():
+Warning: gzdecode(): data error in %s on line %d
+
+read: string(32) "The quick brown fox jumps over t"
+gzdecode():
+Warning: gzdecode(): data error in %s on line %d
+
+read: bool(false)
+gzdecode():
+Warning: gzdecode(): data error in %s on line %d
+
+read: bool(false)
diff --git a/ext/zlib/tests/bug_52944.phpt b/ext/zlib/tests/bug_52944.phpt
index e5c6694158..782e2396a7 100644
--- a/ext/zlib/tests/bug_52944.phpt
+++ b/ext/zlib/tests/bug_52944.phpt
@@ -19,6 +19,6 @@ var_dump(fread($fp,1));
fclose($fp);
echo "Done.\n";
--EXPECT--
-string(0) ""
+bool(false)
string(0) ""
Done.
diff --git a/ext/zlib/tests/gzread_variation1.phpt b/ext/zlib/tests/gzread_variation1.phpt
index d544d6d4c2..9cf4b9c739 100644
--- a/ext/zlib/tests/gzread_variation1.phpt
+++ b/ext/zlib/tests/gzread_variation1.phpt
@@ -27,8 +27,8 @@ unlink($filename);
?>
===DONE===
--EXPECT--
-string(0) ""
-string(0) ""
-string(0) ""
+bool(false)
+bool(false)
+bool(false)
Here is the string to be written.
===DONE===
diff --git a/ext/zlib/zlib_fopen_wrapper.c b/ext/zlib/zlib_fopen_wrapper.c
index d600f09a65..514773f2b0 100644
--- a/ext/zlib/zlib_fopen_wrapper.c
+++ b/ext/zlib/zlib_fopen_wrapper.c
@@ -30,7 +30,7 @@ struct php_gz_stream_data_t {
php_stream *stream;
};
-static size_t php_gziop_read(php_stream *stream, char *buf, size_t count)
+static ssize_t php_gziop_read(php_stream *stream, char *buf, size_t count)
{
struct php_gz_stream_data_t *self = (struct php_gz_stream_data_t *) stream->abstract;
int read;
@@ -42,18 +42,15 @@ static size_t php_gziop_read(php_stream *stream, char *buf, size_t count)
stream->eof = 1;
}
- return (size_t)((read < 0) ? 0 : read);
+ return read;
}
-static size_t php_gziop_write(php_stream *stream, const char *buf, size_t count)
+static ssize_t php_gziop_write(php_stream *stream, const char *buf, size_t count)
{
struct php_gz_stream_data_t *self = (struct php_gz_stream_data_t *) stream->abstract;
- int wrote;
/* XXX this needs to be looped for the case count > UINT_MAX */
- wrote = gzwrite(self->gz_file, (char *) buf, count);
-
- return (size_t)((wrote < 0) ? 0 : wrote);
+ return gzwrite(self->gz_file, (char *) buf, count);
}
static int php_gziop_seek(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffs)
diff --git a/main/php_streams.h b/main/php_streams.h
index 7c49099bb0..11e7c2aae7 100644
--- a/main/php_streams.h
+++ b/main/php_streams.h
@@ -115,8 +115,8 @@ typedef struct _php_stream_dirent {
/* operations on streams that are file-handles */
typedef struct _php_stream_ops {
/* stdio like functions - these are mandatory! */
- size_t (*write)(php_stream *stream, const char *buf, size_t count);
- size_t (*read)(php_stream *stream, char *buf, size_t count);
+ ssize_t (*write)(php_stream *stream, const char *buf, size_t count);
+ ssize_t (*read)(php_stream *stream, char *buf, size_t count);
int (*close)(php_stream *stream, int close_handle);
int (*flush)(php_stream *stream);
@@ -305,17 +305,19 @@ PHPAPI int _php_stream_seek(php_stream *stream, zend_off_t offset, int whence);
PHPAPI zend_off_t _php_stream_tell(php_stream *stream);
#define php_stream_tell(stream) _php_stream_tell((stream))
-PHPAPI size_t _php_stream_read(php_stream *stream, char *buf, size_t count);
+PHPAPI ssize_t _php_stream_read(php_stream *stream, char *buf, size_t count);
#define php_stream_read(stream, buf, count) _php_stream_read((stream), (buf), (count))
-PHPAPI size_t _php_stream_write(php_stream *stream, const char *buf, size_t count);
+PHPAPI zend_string *php_stream_read_to_str(php_stream *stream, size_t len);
+
+PHPAPI ssize_t _php_stream_write(php_stream *stream, const char *buf, size_t count);
#define php_stream_write_string(stream, str) _php_stream_write(stream, str, strlen(str))
#define php_stream_write(stream, buf, count) _php_stream_write(stream, (buf), (count))
-PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size);
+PHPAPI int _php_stream_fill_read_buffer(php_stream *stream, size_t size);
#define php_stream_fill_read_buffer(stream, size) _php_stream_fill_read_buffer((stream), (size))
-PHPAPI size_t _php_stream_printf(php_stream *stream, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 2, 3);
+PHPAPI ssize_t _php_stream_printf(php_stream *stream, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 2, 3);
/* php_stream_printf macro & function require */
#define php_stream_printf _php_stream_printf
@@ -462,7 +464,7 @@ PHPAPI zend_string *_php_stream_copy_to_mem(php_stream *src, size_t maxlen, int
#define php_stream_copy_to_mem(src, maxlen, persistent) _php_stream_copy_to_mem((src), (maxlen), (persistent) STREAMS_CC)
/* output all data from a stream */
-PHPAPI size_t _php_stream_passthru(php_stream * src STREAMS_DC);
+PHPAPI ssize_t _php_stream_passthru(php_stream * src STREAMS_DC);
#define php_stream_passthru(stream) _php_stream_passthru((stream) STREAMS_CC)
END_EXTERN_C()
diff --git a/main/php_variables.c b/main/php_variables.c
index f5692ede4b..4b30d84f2f 100644
--- a/main/php_variables.c
+++ b/main/php_variables.c
@@ -370,9 +370,9 @@ SAPI_API SAPI_POST_HANDLER_FUNC(php_std_post_handler)
while (!php_stream_eof(s)) {
char buf[SAPI_POST_HANDLER_BUFSIZ] = {0};
- size_t len = php_stream_read(s, buf, SAPI_POST_HANDLER_BUFSIZ);
+ ssize_t len = php_stream_read(s, buf, SAPI_POST_HANDLER_BUFSIZ);
- if (len && len != (size_t) -1) {
+ if (len > 0) {
smart_str_appendl(&post_data.str, buf, len);
if (SUCCESS != add_post_vars(arr, &post_data, 0)) {
diff --git a/main/streams/glob_wrapper.c b/main/streams/glob_wrapper.c
index 0386d72255..0e72558a2a 100644
--- a/main/streams/glob_wrapper.c
+++ b/main/streams/glob_wrapper.c
@@ -127,7 +127,7 @@ static void php_glob_stream_path_split(glob_s_t *pglob, const char *path, int ge
}
/* }}} */
-static size_t php_glob_stream_read(php_stream *stream, char *buf, size_t count) /* {{{ */
+static ssize_t php_glob_stream_read(php_stream *stream, char *buf, size_t count) /* {{{ */
{
glob_s_t *pglob = (glob_s_t *)stream->abstract;
php_stream_dirent *ent = (php_stream_dirent*)buf;
@@ -147,7 +147,7 @@ static size_t php_glob_stream_read(php_stream *stream, char *buf, size_t count)
}
}
- return 0;
+ return -1;
}
/* }}} */
diff --git a/main/streams/memory.c b/main/streams/memory.c
index b63ed77255..4b92fc2ffd 100644
--- a/main/streams/memory.c
+++ b/main/streams/memory.c
@@ -44,13 +44,13 @@ typedef struct {
/* {{{ */
-static size_t php_stream_memory_write(php_stream *stream, const char *buf, size_t count)
+static ssize_t php_stream_memory_write(php_stream *stream, const char *buf, size_t count)
{
php_stream_memory_data *ms = (php_stream_memory_data*)stream->abstract;
assert(ms != NULL);
if (ms->mode & TEMP_STREAM_READONLY) {
- return 0;
+ return (ssize_t) -1;
} else if (ms->mode & TEMP_STREAM_APPEND) {
ms->fpos = ms->fsize;
}
@@ -77,7 +77,7 @@ static size_t php_stream_memory_write(php_stream *stream, const char *buf, size_
/* {{{ */
-static size_t php_stream_memory_read(php_stream *stream, char *buf, size_t count)
+static ssize_t php_stream_memory_read(php_stream *stream, char *buf, size_t count)
{
php_stream_memory_data *ms = (php_stream_memory_data*)stream->abstract;
assert(ms != NULL);
@@ -368,7 +368,7 @@ typedef struct {
/* {{{ */
-static size_t php_stream_temp_write(php_stream *stream, const char *buf, size_t count)
+static ssize_t php_stream_temp_write(php_stream *stream, const char *buf, size_t count)
{
php_stream_temp_data *ts = (php_stream_temp_data*)stream->abstract;
assert(ts != NULL);
@@ -398,7 +398,7 @@ static size_t php_stream_temp_write(php_stream *stream, const char *buf, size_t
/* {{{ */
-static size_t php_stream_temp_read(php_stream *stream, char *buf, size_t count)
+static ssize_t php_stream_temp_read(php_stream *stream, char *buf, size_t count)
{
php_stream_temp_data *ts = (php_stream_temp_data*)stream->abstract;
size_t got;
diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c
index 83681c0d88..3c6a9afb28 100644
--- a/main/streams/plain_wrapper.c
+++ b/main/streams/plain_wrapper.c
@@ -335,7 +335,7 @@ PHPAPI php_stream *_php_stream_fopen_from_pipe(FILE *file, const char *mode STRE
return stream;
}
-static size_t php_stdiop_write(php_stream *stream, const char *buf, size_t count)
+static ssize_t php_stdiop_write(php_stream *stream, const char *buf, size_t count)
{
php_stdio_stream_data *data = (php_stdio_stream_data*)stream->abstract;
@@ -343,16 +343,15 @@ static size_t php_stdiop_write(php_stream *stream, const char *buf, size_t count
if (data->fd >= 0) {
#ifdef PHP_WIN32
- int bytes_written;
+ ssize_t bytes_written;
if (ZEND_SIZE_T_UINT_OVFL(count)) {
count = UINT_MAX;
}
bytes_written = _write(data->fd, buf, (unsigned int)count);
#else
- int bytes_written = write(data->fd, buf, count);
+ ssize_t bytes_written = write(data->fd, buf, count);
#endif
- if (bytes_written < 0) return 0;
- return (size_t) bytes_written;
+ return bytes_written;
} else {
#if HAVE_FLUSHIO
@@ -362,14 +361,14 @@ static size_t php_stdiop_write(php_stream *stream, const char *buf, size_t count
data->last_op = 'w';
#endif
- return fwrite(buf, 1, count, data->file);
+ return (ssize_t) fwrite(buf, 1, count, data->file);
}
}
-static size_t php_stdiop_read(php_stream *stream, char *buf, size_t count)
+static ssize_t php_stdiop_read(php_stream *stream, char *buf, size_t count)
{
php_stdio_stream_data *data = (php_stdio_stream_data*)stream->abstract;
- size_t ret;
+ ssize_t ret;
assert(data != NULL);
@@ -411,7 +410,20 @@ static size_t php_stdiop_read(php_stream *stream, char *buf, size_t count)
ret = read(data->fd, buf, PLAIN_WRAP_BUF_SIZE(count));
}
- stream->eof = (ret == 0 || (ret == (size_t)-1 && errno != EWOULDBLOCK && errno != EINTR && errno != EBADF));
+ if (ret < 0) {
+ if (errno == EWOULDBLOCK || errno == EAGAIN) {
+ /* Not an error. */
+ ret = 0;
+ } else if (errno == EINTR) {
+ /* An error, but not EOF */
+ } else if (errno == EBADF) {
+ /* TODO: Remove this special-case? */
+ } else {
+ stream->eof = 1;
+ }
+ } else if (ret == 0) {
+ stream->eof = 1;
+ }
} else {
#if HAVE_FLUSHIO
@@ -921,7 +933,7 @@ PHPAPI php_stream_ops php_stream_stdio_ops = {
/* }}} */
/* {{{ plain files opendir/readdir implementation */
-static size_t php_plain_files_dirstream_read(php_stream *stream, char *buf, size_t count)
+static ssize_t php_plain_files_dirstream_read(php_stream *stream, char *buf, size_t count)
{
DIR *dir = (DIR*)stream->abstract;
struct dirent *result;
@@ -929,7 +941,7 @@ static size_t php_plain_files_dirstream_read(php_stream *stream, char *buf, size
/* avoid problems if someone mis-uses the stream */
if (count != sizeof(php_stream_dirent))
- return 0;
+ return -1;
result = readdir(dir);
if (result) {
diff --git a/main/streams/streams.c b/main/streams/streams.c
index 5f467c12ce..296bf9600e 100644
--- a/main/streams/streams.c
+++ b/main/streams/streams.c
@@ -525,13 +525,12 @@ fprintf(stderr, "stream_free: %s:%p[%s] preserve_handle=%d release_cast=%d remov
/* {{{ generic stream operations */
-PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size)
+PHPAPI int _php_stream_fill_read_buffer(php_stream *stream, size_t size)
{
/* allocate/fill the buffer */
if (stream->readfilters.head) {
char *chunk_buf;
- int err_flag = 0;
php_stream_bucket_brigade brig_in = { NULL, NULL }, brig_out = { NULL, NULL };
php_stream_bucket_brigade *brig_inp = &brig_in, *brig_outp = &brig_out, *brig_swap;
@@ -542,8 +541,8 @@ PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size)
/* allocate a buffer for reading chunks */
chunk_buf = emalloc(stream->chunk_size);
- while (!stream->eof && !err_flag && (stream->writepos - stream->readpos < (zend_off_t)size)) {
- size_t justread = 0;
+ while (!stream->eof && (stream->writepos - stream->readpos < (zend_off_t)size)) {
+ ssize_t justread = 0;
int flags;
php_stream_bucket *bucket;
php_stream_filter_status_t status = PSFS_ERR_FATAL;
@@ -551,7 +550,10 @@ PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size)
/* read a chunk into a bucket */
justread = stream->ops->read(stream, chunk_buf, stream->chunk_size);
- if (justread && justread != (size_t)-1) {
+ if (justread < 0 && stream->writepos == stream->readpos) {
+ efree(chunk_buf);
+ return FAILURE;
+ } else if (justread > 0) {
bucket = php_stream_bucket_new(stream, chunk_buf, justread, 0, 0);
/* after this call, bucket is owned by the brigade */
@@ -607,31 +609,28 @@ PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size)
/* when a filter needs feeding, there is no brig_out to deal with.
* we simply continue the loop; if the caller needs more data,
* we will read again, otherwise out job is done here */
- if (justread == 0) {
- /* there is no data */
- err_flag = 1;
- break;
- }
- continue;
+ break;
case PSFS_ERR_FATAL:
/* some fatal error. Theoretically, the stream is borked, so all
* further reads should fail. */
- err_flag = 1;
- break;
+ stream->eof = 1;
+ efree(chunk_buf);
+ return FAILURE;
}
- if (justread == 0 || justread == (size_t)-1) {
+ if (justread <= 0) {
break;
}
}
efree(chunk_buf);
+ return SUCCESS;
} else {
/* is there enough data in the buffer ? */
if (stream->writepos - stream->readpos < (zend_off_t)size) {
- size_t justread = 0;
+ ssize_t justread = 0;
/* reduce buffer memory consumption if possible, to avoid a realloc */
if (stream->readbuf && stream->readbuflen - stream->writepos < stream->chunk_size) {
@@ -653,17 +652,18 @@ PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size)
justread = stream->ops->read(stream, (char*)stream->readbuf + stream->writepos,
stream->readbuflen - stream->writepos
);
-
- if (justread != (size_t)-1) {
- stream->writepos += justread;
+ if (justread < 0) {
+ return FAILURE;
}
+ stream->writepos += justread;
}
+ return SUCCESS;
}
}
-PHPAPI size_t _php_stream_read(php_stream *stream, char *buf, size_t size)
+PHPAPI ssize_t _php_stream_read(php_stream *stream, char *buf, size_t size)
{
- size_t toread = 0, didread = 0;
+ ssize_t toread = 0, didread = 0;
while (size > 0) {
@@ -692,15 +692,24 @@ PHPAPI size_t _php_stream_read(php_stream *stream, char *buf, size_t size)
if (!stream->readfilters.head && (stream->flags & PHP_STREAM_FLAG_NO_BUFFER || stream->chunk_size == 1)) {
toread = stream->ops->read(stream, buf, size);
- if (toread == (size_t) -1) {
- /* e.g. underlying read(2) returned -1 */
+ if (toread < 0) {
+ /* Report an error if the read failed and we did not read any data
+ * before that. Otherwise return the data we did read. */
+ if (didread == 0) {
+ return toread;
+ }
break;
}
} else {
- php_stream_fill_read_buffer(stream, size);
+ if (php_stream_fill_read_buffer(stream, size) != SUCCESS) {
+ if (didread == 0) {
+ return -1;
+ }
+ break;
+ }
toread = stream->writepos - stream->readpos;
- if (toread > size) {
+ if ((size_t) toread > size) {
toread = size;
}
@@ -733,6 +742,26 @@ PHPAPI size_t _php_stream_read(php_stream *stream, char *buf, size_t size)
return didread;
}
+/* Like php_stream_read(), but reading into a zend_string buffer. This has some similarity
+ * to the copy_to_mem() operation, but only performs a single direct read. */
+PHPAPI zend_string *php_stream_read_to_str(php_stream *stream, size_t len)
+{
+ zend_string *str = zend_string_alloc(len, 0);
+ ssize_t read = php_stream_read(stream, ZSTR_VAL(str), len);
+ if (read < 0) {
+ zend_string_efree(str);
+ return NULL;
+ }
+
+ ZSTR_LEN(str) = read;
+ ZSTR_VAL(str)[read] = 0;
+
+ if ((size_t) read < len / 2) {
+ return zend_string_truncate(str, read, 0);
+ }
+ return str;
+}
+
PHPAPI int _php_stream_eof(php_stream *stream)
{
/* if there is data in the buffer, it's not EOF */
@@ -776,7 +805,7 @@ PHPAPI int _php_stream_puts(php_stream *stream, const char *buf)
char newline[2] = "\n"; /* is this OK for Win? */
len = strlen(buf);
- if (len > 0 && php_stream_write(stream, buf, len) && php_stream_write(stream, newline, 1)) {
+ if (len > 0 && php_stream_write(stream, buf, len) > 0 && php_stream_write(stream, newline, 1) > 0) {
return 1;
}
return 0;
@@ -1074,9 +1103,9 @@ PHPAPI zend_string *php_stream_get_record(php_stream *stream, size_t maxlen, con
}
/* Writes a buffer directly to a stream, using multiple of the chunk size */
-static size_t _php_stream_write_buffer(php_stream *stream, const char *buf, size_t count)
+static ssize_t _php_stream_write_buffer(php_stream *stream, const char *buf, size_t count)
{
- size_t didwrite = 0, towrite, justwrote;
+ ssize_t didwrite = 0, justwrote;
/* if we have a seekable stream we need to ensure that data is written at the
* current stream->position. This means invalidating the read buffer and then
@@ -1089,29 +1118,32 @@ static size_t _php_stream_write_buffer(php_stream *stream, const char *buf, size
while (count > 0) {
- towrite = count;
+ size_t towrite = count;
if (towrite > stream->chunk_size)
towrite = stream->chunk_size;
justwrote = stream->ops->write(stream, buf, towrite);
+ if (justwrote <= 0) {
+ /* If we already successfully wrote some bytes and a write error occurred
+ * later, report the successfully written bytes. */
+ if (didwrite == 0) {
+ return justwrote;
+ }
+ return didwrite;
+ }
- /* convert justwrote to an integer, since normally it is unsigned */
- if ((int)justwrote > 0) {
- buf += justwrote;
- count -= justwrote;
- didwrite += justwrote;
+ buf += justwrote;
+ count -= justwrote;
+ didwrite += justwrote;
- /* Only screw with the buffer if we can seek, otherwise we lose data
- * buffered from fifos and sockets */
- if (stream->ops->seek && (stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0) {
- stream->position += justwrote;
- }
- } else {
- break;
+ /* Only screw with the buffer if we can seek, otherwise we lose data
+ * buffered from fifos and sockets */
+ if (stream->ops->seek && (stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0) {
+ stream->position += justwrote;
}
}
- return didwrite;
+ return didwrite;
}
/* push some data through the write filter chain.
@@ -1119,7 +1151,7 @@ static size_t _php_stream_write_buffer(php_stream *stream, const char *buf, size
* This may trigger a real write to the stream.
* Returns the number of bytes consumed from buf by the first filter in the chain.
* */
-static size_t _php_stream_write_filtered(php_stream *stream, const char *buf, size_t count, int flags)
+static ssize_t _php_stream_write_filtered(php_stream *stream, const char *buf, size_t count, int flags)
{
size_t consumed = 0;
php_stream_bucket *bucket;
@@ -1157,7 +1189,10 @@ static size_t _php_stream_write_filtered(php_stream *stream, const char *buf, si
* underlying stream */
while (brig_inp->head) {
bucket = brig_inp->head;
- _php_stream_write_buffer(stream, bucket->buf, bucket->buflen);
+ if (_php_stream_write_buffer(stream, bucket->buf, bucket->buflen) < 0) {
+ consumed = (ssize_t) -1;
+ }
+
/* Potential error situation - eg: no space on device. Perhaps we should keep this brigade
* hanging around and try to write it later.
* At the moment, we just drop it on the floor
@@ -1174,7 +1209,7 @@ static size_t _php_stream_write_filtered(php_stream *stream, const char *buf, si
case PSFS_ERR_FATAL:
/* some fatal error. Theoretically, the stream is borked, so all
* further writes should fail. */
- break;
+ return (ssize_t) -1;
}
return consumed;
@@ -1197,14 +1232,18 @@ PHPAPI int _php_stream_flush(php_stream *stream, int closing)
return ret;
}
-PHPAPI size_t _php_stream_write(php_stream *stream, const char *buf, size_t count)
+PHPAPI ssize_t _php_stream_write(php_stream *stream, const char *buf, size_t count)
{
- size_t bytes;
+ ssize_t bytes;
- if (buf == NULL || count == 0 || stream->ops->write == NULL) {
+ if (count == 0) {
return 0;
}
+ if (buf == NULL || stream->ops->write == NULL) {
+ return (ssize_t) -1;
+ }
+
if (stream->writefilters.head) {
bytes = _php_stream_write_filtered(stream, buf, count, PSFS_FLAG_NORMAL);
} else {
@@ -1218,9 +1257,9 @@ PHPAPI size_t _php_stream_write(php_stream *stream, const char *buf, size_t coun
return bytes;
}
-PHPAPI size_t _php_stream_printf(php_stream *stream, const char *fmt, ...)
+PHPAPI ssize_t _php_stream_printf(php_stream *stream, const char *fmt, ...)
{
- size_t count;
+ ssize_t count;
char *buf;
va_list ap;
@@ -1229,7 +1268,7 @@ PHPAPI size_t _php_stream_printf(php_stream *stream, const char *fmt, ...)
va_end(ap);
if (!buf) {
- return 0; /* error condition */
+ return -1; /* error condition */
}
count = php_stream_write(stream, buf, count);
@@ -1306,9 +1345,9 @@ PHPAPI int _php_stream_seek(php_stream *stream, zend_off_t offset, int whence)
/* emulate forward moving seeks with reads */
if (whence == SEEK_CUR && offset >= 0) {
char tmp[1024];
- size_t didread;
- while(offset > 0) {
- if ((didread = php_stream_read(stream, tmp, MIN(offset, sizeof(tmp)))) == 0) {
+ ssize_t didread;
+ while (offset > 0) {
+ if ((didread = php_stream_read(stream, tmp, MIN(offset, sizeof(tmp)))) <= 0) {
return -1;
}
offset -= didread;
@@ -1361,11 +1400,11 @@ PHPAPI int _php_stream_truncate_set_size(php_stream *stream, size_t newsize)
return php_stream_set_option(stream, PHP_STREAM_OPTION_TRUNCATE_API, PHP_STREAM_TRUNCATE_SET_SIZE, &newsize);
}
-PHPAPI size_t _php_stream_passthru(php_stream * stream STREAMS_DC)
+PHPAPI ssize_t _php_stream_passthru(php_stream * stream STREAMS_DC)
{
size_t bcount = 0;
char buf[8192];
- size_t b;
+ ssize_t b;
if (php_stream_mmap_possible(stream)) {
char *p;
@@ -1392,13 +1431,17 @@ PHPAPI size_t _php_stream_passthru(php_stream * stream STREAMS_DC)
bcount += b;
}
+ if (b < 0 && bcount == 0) {
+ return b;
+ }
+
return bcount;
}
PHPAPI zend_string *_php_stream_copy_to_mem(php_stream *src, size_t maxlen, int persistent STREAMS_DC)
{
- size_t ret = 0;
+ ssize_t ret = 0;
char *ptr;
size_t len = 0, max_len;
int step = CHUNK_SIZE;
@@ -1419,7 +1462,8 @@ PHPAPI zend_string *_php_stream_copy_to_mem(php_stream *src, size_t maxlen, int
ptr = ZSTR_VAL(result);
while ((len < maxlen) && !php_stream_eof(src)) {
ret = php_stream_read(src, ptr, maxlen - len);
- if (!ret) {
+ if (ret <= 0) {
+ // TODO: Propagate error?
break;
}
len += ret;
@@ -1450,7 +1494,8 @@ PHPAPI zend_string *_php_stream_copy_to_mem(php_stream *src, size_t maxlen, int
result = zend_string_alloc(max_len, persistent);
ptr = ZSTR_VAL(result);
- while ((ret = php_stream_read(src, ptr, max_len - len))) {
+ // TODO: Propagate error?
+ while ((ret = php_stream_read(src, ptr, max_len - len)) > 0){
len += ret;
if (len + min_room >= max_len) {
result = zend_string_extend(result, max_len + step, persistent);
@@ -1475,9 +1520,8 @@ PHPAPI zend_string *_php_stream_copy_to_mem(php_stream *src, size_t maxlen, int
PHPAPI int _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size_t maxlen, size_t *len STREAMS_DC)
{
char buf[CHUNK_SIZE];
- size_t readchunk;
size_t haveread = 0;
- size_t didread, didwrite, towrite;
+ size_t towrite;
size_t dummy;
php_stream_statbuf ssbuf;
@@ -1512,7 +1556,11 @@ PHPAPI int _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size
p = php_stream_mmap_range(src, php_stream_tell(src), maxlen, PHP_STREAM_MAP_MODE_SHARED_READONLY, &mapped);
if (p) {
- didwrite = php_stream_write(dest, p, mapped);
+ ssize_t didwrite = php_stream_write(dest, p, mapped);
+ if (didwrite < 0) {
+ *len = 0;
+ return FAILURE;
+ }
php_stream_mmap_unmap_ex(src, mapped);
@@ -1529,7 +1577,8 @@ PHPAPI int _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size
}
while(1) {
- readchunk = sizeof(buf);
+ size_t readchunk = sizeof(buf);
+ ssize_t didread;
if (maxlen && (maxlen - haveread) < readchunk) {
readchunk = maxlen - haveread;
@@ -1537,7 +1586,7 @@ PHPAPI int _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size
didread = php_stream_read(src, buf, readchunk);
- if (didread) {
+ if (didread > 0) {
/* extra paranoid */
char *writeptr;
@@ -1545,9 +1594,9 @@ PHPAPI int _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size
writeptr = buf;
haveread += didread;
- while(towrite) {
- didwrite = php_stream_write(dest, writeptr, towrite);
- if (didwrite == 0) {
+ while (towrite) {
+ ssize_t didwrite = php_stream_write(dest, writeptr, towrite);
+ if (didwrite <= 0) {
*len = haveread - (didread - towrite);
return FAILURE;
}
diff --git a/main/streams/userspace.c b/main/streams/userspace.c
index bdd9b1b48e..de3e8591e6 100644
--- a/main/streams/userspace.c
+++ b/main/streams/userspace.c
@@ -588,14 +588,14 @@ PHP_FUNCTION(stream_wrapper_restore)
}
/* }}} */
-static size_t php_userstreamop_write(php_stream *stream, const char *buf, size_t count)
+static ssize_t php_userstreamop_write(php_stream *stream, const char *buf, size_t count)
{
zval func_name;
zval retval;
int call_result;
php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract;
zval args[1];
- size_t didwrite = 0;
+ ssize_t didwrite;
assert(us != NULL);
@@ -612,18 +612,21 @@ static size_t php_userstreamop_write(php_stream *stream, const char *buf, size_t
zval_ptr_dtor(&args[0]);
zval_ptr_dtor(&func_name);
- didwrite = 0;
-
if (EG(exception)) {
- return 0;
+ return -1;
}
if (call_result == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
- convert_to_long(&retval);
- didwrite = Z_LVAL(retval);
- } else if (call_result == FAILURE) {
+ if (Z_TYPE(retval) == IS_FALSE) {
+ didwrite = -1;
+ } else {
+ convert_to_long(&retval);
+ didwrite = Z_LVAL(retval);
+ }
+ } else {
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_WRITE " is not implemented!",
us->wrapper->classname);
+ didwrite = -1;
}
/* don't allow strange buffer overruns due to bogus return */
@@ -639,7 +642,7 @@ static size_t php_userstreamop_write(php_stream *stream, const char *buf, size_t
return didwrite;
}
-static size_t php_userstreamop_read(php_stream *stream, char *buf, size_t count)
+static ssize_t php_userstreamop_read(php_stream *stream, char *buf, size_t count)
{
zval func_name;
zval retval;
@@ -669,6 +672,10 @@ static size_t php_userstreamop_read(php_stream *stream, char *buf, size_t count)
}
if (call_result == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
+ if (Z_TYPE(retval) == IS_FALSE) {
+ return -1;
+ }
+
if (!try_convert_to_string(&retval)) {
return -1;
}
@@ -1401,7 +1408,7 @@ static int user_wrapper_stat_url(php_stream_wrapper *wrapper, const char *url, i
}
-static size_t php_userstreamop_readdir(php_stream *stream, char *buf, size_t count)
+static ssize_t php_userstreamop_readdir(php_stream *stream, char *buf, size_t count)
{
zval func_name;
zval retval;
@@ -1412,7 +1419,7 @@ static size_t php_userstreamop_readdir(php_stream *stream, char *buf, size_t cou
/* avoid problems if someone mis-uses the stream */
if (count != sizeof(php_stream_dirent))
- return 0;
+ return -1;
ZVAL_STRINGL(&func_name, USERSTREAM_DIR_READ, sizeof(USERSTREAM_DIR_READ)-1);
diff --git a/main/streams/xp_socket.c b/main/streams/xp_socket.c
index f79fa16d5f..511e1570d1 100644
--- a/main/streams/xp_socket.c
+++ b/main/streams/xp_socket.c
@@ -56,10 +56,10 @@ const php_stream_ops php_stream_unixdg_socket_ops;
static int php_tcp_sockop_set_option(php_stream *stream, int option, int value, void *ptrparam);
/* {{{ Generic socket stream operations */
-static size_t php_sockop_write(php_stream *stream, const char *buf, size_t count)
+static ssize_t php_sockop_write(php_stream *stream, const char *buf, size_t count)
{
php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract;
- int didwrite;
+ ssize_t didwrite;
struct timeval *ptimeout;
if (!sock || sock->socket == -1) {
@@ -109,10 +109,6 @@ retry:
php_stream_notify_progress_increment(PHP_STREAM_CONTEXT(stream), didwrite, 0);
}
- if (didwrite < 0) {
- didwrite = 0;
- }
-
return didwrite;
}
@@ -146,14 +142,14 @@ static void php_sock_stream_wait_for_data(php_stream *stream, php_netstream_data
}
}
-static size_t php_sockop_read(php_stream *stream, char *buf, size_t count)
+static ssize_t php_sockop_read(php_stream *stream, char *buf, size_t count)
{
php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract;
ssize_t nr_bytes = 0;
int err;
if (!sock || sock->socket == -1) {
- return 0;
+ return -1;
}
if (sock->is_blocked) {
@@ -165,16 +161,20 @@ static size_t php_sockop_read(php_stream *stream, char *buf, size_t count)
nr_bytes = recv(sock->socket, buf, XP_SOCK_BUF_SIZE(count), (sock->is_blocked && sock->timeout.tv_sec != -1) ? MSG_DONTWAIT : 0);
err = php_socket_errno();
- stream->eof = (nr_bytes == 0 || (nr_bytes == -1 && err != EWOULDBLOCK && err != EAGAIN));
+ if (nr_bytes < 0) {
+ if (err == EAGAIN || err == EWOULDBLOCK) {
+ nr_bytes = 0;
+ } else {
+ stream->eof = 1;
+ }
+ } else if (nr_bytes == 0) {
+ stream->eof = 1;
+ }
if (nr_bytes > 0) {
php_stream_notify_progress_increment(PHP_STREAM_CONTEXT(stream), nr_bytes, 0);
}
- if (nr_bytes < 0) {
- nr_bytes = 0;
- }
-
return nr_bytes;
}
diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c
index 1f4cb29a4f..17de15fa91 100644
--- a/sapi/phpdbg/phpdbg.c
+++ b/sapi/phpdbg/phpdbg.c
@@ -955,7 +955,7 @@ typedef struct {
int fd;
} php_stdio_stream_data;
-static size_t phpdbg_stdiop_write(php_stream *stream, const char *buf, size_t count) {
+static ssize_t phpdbg_stdiop_write(php_stream *stream, const char *buf, size_t count) {
php_stdio_stream_data *data = (php_stdio_stream_data*)stream->abstract;
while (data->fd >= 0) {
diff --git a/sapi/phpdbg/phpdbg.h b/sapi/phpdbg/phpdbg.h
index f22d2ce1c2..d9a66b44bd 100644
--- a/sapi/phpdbg/phpdbg.h
+++ b/sapi/phpdbg/phpdbg.h
@@ -290,7 +290,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg)
int fd;
} io[PHPDBG_IO_FDS]; /* io */
int eol; /* type of line ending to use */
- size_t (*php_stdiop_write)(php_stream *, const char *, size_t);
+ ssize_t (*php_stdiop_write)(php_stream *, const char *, size_t);
int in_script_xml; /* in <stream> output mode */
struct {
zend_bool active;