diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-07-22 17:25:28 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-07-22 17:26:01 +0200 |
commit | a1e2c8870ebfdc1c2d9fa25327bc3dad5bd68c91 (patch) | |
tree | 1ba6ec4f9b3f51ef407c2903af2ad7815f8b69ca | |
parent | 7a1540fa2872a67080f2161faff226c1effebf76 (diff) | |
parent | d59aac58b3e7da7ad01a194fe9840d89725ea229 (diff) | |
download | php-git-a1e2c8870ebfdc1c2d9fa25327bc3dad5bd68c91.tar.gz |
Merge branch 'PHP-7.4'
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; |