ext/standard: Use new php_streams fast ZPP specifier for file functions

Fix a corresponding test
This commit is contained in:
Gina Peter Banyard 2025-03-03 15:33:40 +00:00
parent 11876f92fd
commit 8787fa2a36
2 changed files with 32 additions and 83 deletions

View file

@ -102,10 +102,6 @@ php_file_globals file_globals;
/* }}} */ /* }}} */
#define PHP_STREAM_FROM_ZVAL(stream, arg) \
ZEND_ASSERT(Z_TYPE_P(arg) == IS_RESOURCE); \
php_stream_from_res(stream, Z_RES_P(arg));
/* {{{ ZTS-stuff / Globals / Prototypes */ /* {{{ ZTS-stuff / Globals / Prototypes */
/* sharing globals is *evil* */ /* sharing globals is *evil* */
@ -215,19 +211,17 @@ PHPAPI void php_flock_common(php_stream *stream, zend_long operation,
/* {{{ Portable file locking */ /* {{{ Portable file locking */
PHP_FUNCTION(flock) PHP_FUNCTION(flock)
{ {
zval *res, *wouldblock = NULL; zval *wouldblock = NULL;
php_stream *stream; php_stream *stream;
zend_long operation = 0; zend_long operation = 0;
ZEND_PARSE_PARAMETERS_START(2, 3) ZEND_PARSE_PARAMETERS_START(2, 3)
Z_PARAM_RESOURCE(res) PHP_Z_PARAM_STREAM(stream)
Z_PARAM_LONG(operation) Z_PARAM_LONG(operation)
Z_PARAM_OPTIONAL Z_PARAM_OPTIONAL
Z_PARAM_ZVAL(wouldblock) Z_PARAM_ZVAL(wouldblock)
ZEND_PARSE_PARAMETERS_END(); ZEND_PARSE_PARAMETERS_END();
PHP_STREAM_FROM_ZVAL(stream, res);
php_flock_common(stream, operation, 2, wouldblock, return_value); php_flock_common(stream, operation, 2, wouldblock, return_value);
} }
/* }}} */ /* }}} */
@ -756,15 +750,12 @@ PHP_FUNCTION(fopen)
/* {{{ Close an open file pointer */ /* {{{ Close an open file pointer */
PHPAPI PHP_FUNCTION(fclose) PHPAPI PHP_FUNCTION(fclose)
{ {
zval *res;
php_stream *stream; php_stream *stream;
ZEND_PARSE_PARAMETERS_START(1, 1) ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_RESOURCE(res) PHP_Z_PARAM_STREAM(stream)
ZEND_PARSE_PARAMETERS_END(); ZEND_PARSE_PARAMETERS_END();
PHP_STREAM_FROM_ZVAL(stream, res);
if ((stream->flags & PHP_STREAM_FLAG_NO_FCLOSE) != 0) { if ((stream->flags & PHP_STREAM_FLAG_NO_FCLOSE) != 0) {
php_error_docref(NULL, E_WARNING, ZEND_LONG_FMT " is not a valid stream resource", stream->res->handle); php_error_docref(NULL, E_WARNING, ZEND_LONG_FMT " is not a valid stream resource", stream->res->handle);
RETURN_FALSE; RETURN_FALSE;
@ -836,15 +827,12 @@ PHP_FUNCTION(popen)
/* {{{ Close a file pointer opened by popen() */ /* {{{ Close a file pointer opened by popen() */
PHP_FUNCTION(pclose) PHP_FUNCTION(pclose)
{ {
zval *res;
php_stream *stream; php_stream *stream;
ZEND_PARSE_PARAMETERS_START(1, 1) ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_RESOURCE(res) PHP_Z_PARAM_STREAM(stream)
ZEND_PARSE_PARAMETERS_END(); ZEND_PARSE_PARAMETERS_END();
PHP_STREAM_FROM_ZVAL(stream, res);
FG(pclose_wait) = 1; FG(pclose_wait) = 1;
zend_list_close(stream->res); zend_list_close(stream->res);
FG(pclose_wait) = 0; FG(pclose_wait) = 0;
@ -855,15 +843,12 @@ PHP_FUNCTION(pclose)
/* {{{ Test for end-of-file on a file pointer */ /* {{{ Test for end-of-file on a file pointer */
PHPAPI PHP_FUNCTION(feof) PHPAPI PHP_FUNCTION(feof)
{ {
zval *res;
php_stream *stream; php_stream *stream;
ZEND_PARSE_PARAMETERS_START(1, 1) ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_RESOURCE(res) PHP_Z_PARAM_STREAM(stream)
ZEND_PARSE_PARAMETERS_END(); ZEND_PARSE_PARAMETERS_END();
PHP_STREAM_FROM_ZVAL(stream, res);
if (php_stream_eof(stream)) { if (php_stream_eof(stream)) {
RETURN_TRUE; RETURN_TRUE;
} else { } else {
@ -875,7 +860,6 @@ PHPAPI PHP_FUNCTION(feof)
/* {{{ Get a line from file pointer */ /* {{{ Get a line from file pointer */
PHPAPI PHP_FUNCTION(fgets) PHPAPI PHP_FUNCTION(fgets)
{ {
zval *res;
zend_long len = 1024; zend_long len = 1024;
bool len_is_null = 1; bool len_is_null = 1;
char *buf = NULL; char *buf = NULL;
@ -884,13 +868,11 @@ PHPAPI PHP_FUNCTION(fgets)
php_stream *stream; php_stream *stream;
ZEND_PARSE_PARAMETERS_START(1, 2) ZEND_PARSE_PARAMETERS_START(1, 2)
Z_PARAM_RESOURCE(res) PHP_Z_PARAM_STREAM(stream)
Z_PARAM_OPTIONAL Z_PARAM_OPTIONAL
Z_PARAM_LONG_OR_NULL(len, len_is_null) Z_PARAM_LONG_OR_NULL(len, len_is_null)
ZEND_PARSE_PARAMETERS_END(); ZEND_PARSE_PARAMETERS_END();
PHP_STREAM_FROM_ZVAL(stream, res);
if (len_is_null) { if (len_is_null) {
/* ask streams to give us a buffer of an appropriate size */ /* ask streams to give us a buffer of an appropriate size */
buf = php_stream_get_line(stream, NULL, 0, &line_len); buf = php_stream_get_line(stream, NULL, 0, &line_len);
@ -926,15 +908,12 @@ PHPAPI PHP_FUNCTION(fgets)
/* {{{ Get a character from file pointer */ /* {{{ Get a character from file pointer */
PHPAPI PHP_FUNCTION(fgetc) PHPAPI PHP_FUNCTION(fgetc)
{ {
zval *res;
php_stream *stream; php_stream *stream;
ZEND_PARSE_PARAMETERS_START(1, 1) ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_RESOURCE(res) PHP_Z_PARAM_STREAM(stream)
ZEND_PARSE_PARAMETERS_END(); ZEND_PARSE_PARAMETERS_END();
PHP_STREAM_FROM_ZVAL(stream, res);
int result = php_stream_getc(stream); int result = php_stream_getc(stream);
if (result == EOF) { if (result == EOF) {
@ -989,7 +968,6 @@ PHP_FUNCTION(fscanf)
/* {{{ Binary-safe file write */ /* {{{ Binary-safe file write */
PHPAPI PHP_FUNCTION(fwrite) PHPAPI PHP_FUNCTION(fwrite)
{ {
zval *res;
char *input; char *input;
size_t inputlen; size_t inputlen;
ssize_t ret; ssize_t ret;
@ -999,7 +977,7 @@ PHPAPI PHP_FUNCTION(fwrite)
php_stream *stream; php_stream *stream;
ZEND_PARSE_PARAMETERS_START(2, 3) ZEND_PARSE_PARAMETERS_START(2, 3)
Z_PARAM_RESOURCE(res) PHP_Z_PARAM_STREAM(stream)
Z_PARAM_STRING(input, inputlen) Z_PARAM_STRING(input, inputlen)
Z_PARAM_OPTIONAL Z_PARAM_OPTIONAL
Z_PARAM_LONG_OR_NULL(maxlen, maxlen_is_null) Z_PARAM_LONG_OR_NULL(maxlen, maxlen_is_null)
@ -1017,8 +995,6 @@ PHPAPI PHP_FUNCTION(fwrite)
RETURN_LONG(0); RETURN_LONG(0);
} }
PHP_STREAM_FROM_ZVAL(stream, res);
ret = php_stream_write(stream, input, num_bytes); ret = php_stream_write(stream, input, num_bytes);
if (ret < 0) { if (ret < 0) {
RETURN_FALSE; RETURN_FALSE;
@ -1031,16 +1007,13 @@ PHPAPI PHP_FUNCTION(fwrite)
/* {{{ Flushes output */ /* {{{ Flushes output */
PHPAPI PHP_FUNCTION(fflush) PHPAPI PHP_FUNCTION(fflush)
{ {
zval *res;
int ret; int ret;
php_stream *stream; php_stream *stream;
ZEND_PARSE_PARAMETERS_START(1, 1) ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_RESOURCE(res) PHP_Z_PARAM_STREAM(stream)
ZEND_PARSE_PARAMETERS_END(); ZEND_PARSE_PARAMETERS_END();
PHP_STREAM_FROM_ZVAL(stream, res);
ret = php_stream_flush(stream); ret = php_stream_flush(stream);
if (ret) { if (ret) {
RETURN_FALSE; RETURN_FALSE;
@ -1052,15 +1025,12 @@ PHPAPI PHP_FUNCTION(fflush)
/* {{{ Rewind the position of a file pointer */ /* {{{ Rewind the position of a file pointer */
PHPAPI PHP_FUNCTION(rewind) PHPAPI PHP_FUNCTION(rewind)
{ {
zval *res;
php_stream *stream; php_stream *stream;
ZEND_PARSE_PARAMETERS_START(1, 1) ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_RESOURCE(res) PHP_Z_PARAM_STREAM(stream)
ZEND_PARSE_PARAMETERS_END(); ZEND_PARSE_PARAMETERS_END();
PHP_STREAM_FROM_ZVAL(stream, res);
if (-1 == php_stream_rewind(stream)) { if (-1 == php_stream_rewind(stream)) {
RETURN_FALSE; RETURN_FALSE;
} }
@ -1071,16 +1041,13 @@ PHPAPI PHP_FUNCTION(rewind)
/* {{{ Get file pointer's read/write position */ /* {{{ Get file pointer's read/write position */
PHPAPI PHP_FUNCTION(ftell) PHPAPI PHP_FUNCTION(ftell)
{ {
zval *res;
zend_long ret; zend_long ret;
php_stream *stream; php_stream *stream;
ZEND_PARSE_PARAMETERS_START(1, 1) ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_RESOURCE(res) PHP_Z_PARAM_STREAM(stream)
ZEND_PARSE_PARAMETERS_END(); ZEND_PARSE_PARAMETERS_END();
PHP_STREAM_FROM_ZVAL(stream, res);
ret = php_stream_tell(stream); ret = php_stream_tell(stream);
if (ret == -1) { if (ret == -1) {
RETURN_FALSE; RETURN_FALSE;
@ -1092,19 +1059,16 @@ PHPAPI PHP_FUNCTION(ftell)
/* {{{ Seek on a file pointer */ /* {{{ Seek on a file pointer */
PHPAPI PHP_FUNCTION(fseek) PHPAPI PHP_FUNCTION(fseek)
{ {
zval *res;
zend_long offset, whence = SEEK_SET; zend_long offset, whence = SEEK_SET;
php_stream *stream; php_stream *stream;
ZEND_PARSE_PARAMETERS_START(2, 3) ZEND_PARSE_PARAMETERS_START(2, 3)
Z_PARAM_RESOURCE(res) PHP_Z_PARAM_STREAM(stream)
Z_PARAM_LONG(offset) Z_PARAM_LONG(offset)
Z_PARAM_OPTIONAL Z_PARAM_OPTIONAL
Z_PARAM_LONG(whence) Z_PARAM_LONG(whence)
ZEND_PARSE_PARAMETERS_END(); ZEND_PARSE_PARAMETERS_END();
PHP_STREAM_FROM_ZVAL(stream, res);
RETURN_LONG(php_stream_seek(stream, offset, (int) whence)); RETURN_LONG(php_stream_seek(stream, offset, (int) whence));
} }
/* }}} */ /* }}} */
@ -1215,16 +1179,13 @@ PHP_FUNCTION(umask)
/* {{{ Output all remaining data from a file pointer */ /* {{{ Output all remaining data from a file pointer */
PHPAPI PHP_FUNCTION(fpassthru) PHPAPI PHP_FUNCTION(fpassthru)
{ {
zval *res;
size_t size; size_t size;
php_stream *stream; php_stream *stream;
ZEND_PARSE_PARAMETERS_START(1, 1) ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_RESOURCE(res) PHP_Z_PARAM_STREAM(stream)
ZEND_PARSE_PARAMETERS_END(); ZEND_PARSE_PARAMETERS_END();
PHP_STREAM_FROM_ZVAL(stream, res);
size = php_stream_passthru(stream); size = php_stream_passthru(stream);
RETURN_LONG(size); RETURN_LONG(size);
} }
@ -1303,15 +1264,12 @@ PHP_FUNCTION(unlink)
PHP_FUNCTION(fsync) PHP_FUNCTION(fsync)
{ {
zval *res;
php_stream *stream; php_stream *stream;
ZEND_PARSE_PARAMETERS_START(1, 1) ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_RESOURCE(res) PHP_Z_PARAM_STREAM(stream)
ZEND_PARSE_PARAMETERS_END(); ZEND_PARSE_PARAMETERS_END();
PHP_STREAM_FROM_ZVAL(stream, res);
if (!php_stream_sync_supported(stream)) { if (!php_stream_sync_supported(stream)) {
php_error_docref(NULL, E_WARNING, "Can't fsync this stream!"); php_error_docref(NULL, E_WARNING, "Can't fsync this stream!");
RETURN_FALSE; RETURN_FALSE;
@ -1322,15 +1280,12 @@ PHP_FUNCTION(fsync)
PHP_FUNCTION(fdatasync) PHP_FUNCTION(fdatasync)
{ {
zval *res;
php_stream *stream; php_stream *stream;
ZEND_PARSE_PARAMETERS_START(1, 1) ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_RESOURCE(res) PHP_Z_PARAM_STREAM(stream)
ZEND_PARSE_PARAMETERS_END(); ZEND_PARSE_PARAMETERS_END();
PHP_STREAM_FROM_ZVAL(stream, res);
if (!php_stream_sync_supported(stream)) { if (!php_stream_sync_supported(stream)) {
php_error_docref(NULL, E_WARNING, "Can't fsync this stream!"); php_error_docref(NULL, E_WARNING, "Can't fsync this stream!");
RETURN_FALSE; RETURN_FALSE;
@ -1342,12 +1297,11 @@ PHP_FUNCTION(fdatasync)
/* {{{ Truncate file to 'size' length */ /* {{{ Truncate file to 'size' length */
PHP_FUNCTION(ftruncate) PHP_FUNCTION(ftruncate)
{ {
zval *fp;
zend_long size; zend_long size;
php_stream *stream; php_stream *stream;
ZEND_PARSE_PARAMETERS_START(2, 2) ZEND_PARSE_PARAMETERS_START(2, 2)
Z_PARAM_RESOURCE(fp) PHP_Z_PARAM_STREAM(stream)
Z_PARAM_LONG(size) Z_PARAM_LONG(size)
ZEND_PARSE_PARAMETERS_END(); ZEND_PARSE_PARAMETERS_END();
@ -1356,8 +1310,6 @@ PHP_FUNCTION(ftruncate)
RETURN_THROWS(); RETURN_THROWS();
} }
PHP_STREAM_FROM_ZVAL(stream, fp);
if (!php_stream_truncate_supported(stream)) { if (!php_stream_truncate_supported(stream)) {
php_error_docref(NULL, E_WARNING, "Can't truncate this stream!"); php_error_docref(NULL, E_WARNING, "Can't truncate this stream!");
RETURN_FALSE; RETURN_FALSE;
@ -1441,15 +1393,12 @@ PHPAPI void php_fstat(php_stream *stream, zval *return_value)
/* {{{ Stat() on a filehandle */ /* {{{ Stat() on a filehandle */
PHP_FUNCTION(fstat) PHP_FUNCTION(fstat)
{ {
zval *fp;
php_stream *stream; php_stream *stream;
ZEND_PARSE_PARAMETERS_START(1, 1) ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_RESOURCE(fp) PHP_Z_PARAM_STREAM(stream)
ZEND_PARSE_PARAMETERS_END(); ZEND_PARSE_PARAMETERS_END();
PHP_STREAM_FROM_ZVAL(stream, fp);
php_fstat(stream, return_value); php_fstat(stream, return_value);
} }
/* }}} */ /* }}} */
@ -1588,18 +1537,15 @@ safe_to_copy:
/* {{{ Binary-safe file read */ /* {{{ Binary-safe file read */
PHPAPI PHP_FUNCTION(fread) PHPAPI PHP_FUNCTION(fread)
{ {
zval *res;
zend_long len; zend_long len;
php_stream *stream; php_stream *stream;
zend_string *str; zend_string *str;
ZEND_PARSE_PARAMETERS_START(2, 2) ZEND_PARSE_PARAMETERS_START(2, 2)
Z_PARAM_RESOURCE(res) PHP_Z_PARAM_STREAM(stream)
Z_PARAM_LONG(len) Z_PARAM_LONG(len)
ZEND_PARSE_PARAMETERS_END(); ZEND_PARSE_PARAMETERS_END();
PHP_STREAM_FROM_ZVAL(stream, res);
if (len <= 0) { if (len <= 0) {
zend_argument_value_error(2, "must be greater than 0"); zend_argument_value_error(2, "must be greater than 0");
RETURN_THROWS(); RETURN_THROWS();
@ -1683,7 +1629,7 @@ PHP_FUNCTION(fputcsv)
char delimiter = ','; /* allow this to be set as parameter */ char delimiter = ','; /* allow this to be set as parameter */
char enclosure = '"'; /* allow this to be set as parameter */ char enclosure = '"'; /* allow this to be set as parameter */
php_stream *stream; php_stream *stream;
zval *fp = NULL, *fields = NULL; zval *fields = NULL;
ssize_t ret; ssize_t ret;
char *delimiter_str = NULL, *enclosure_str = NULL; char *delimiter_str = NULL, *enclosure_str = NULL;
zend_string *escape_str = NULL; zend_string *escape_str = NULL;
@ -1691,7 +1637,7 @@ PHP_FUNCTION(fputcsv)
zend_string *eol_str = NULL; zend_string *eol_str = NULL;
ZEND_PARSE_PARAMETERS_START(2, 6) ZEND_PARSE_PARAMETERS_START(2, 6)
Z_PARAM_RESOURCE(fp) PHP_Z_PARAM_STREAM(stream)
Z_PARAM_ARRAY(fields) Z_PARAM_ARRAY(fields)
Z_PARAM_OPTIONAL Z_PARAM_OPTIONAL
Z_PARAM_STRING(delimiter_str, delimiter_str_len) Z_PARAM_STRING(delimiter_str, delimiter_str_len)
@ -1725,8 +1671,6 @@ PHP_FUNCTION(fputcsv)
RETURN_THROWS(); RETURN_THROWS();
} }
PHP_STREAM_FROM_ZVAL(stream, fp);
ret = php_fputcsv(stream, fields, delimiter, enclosure, escape_char, eol_str); ret = php_fputcsv(stream, fields, delimiter, enclosure, escape_char, eol_str);
if (ret < 0) { if (ret < 0) {
RETURN_FALSE; RETURN_FALSE;
@ -1811,7 +1755,6 @@ PHP_FUNCTION(fgetcsv)
char *buf; char *buf;
php_stream *stream; php_stream *stream;
zval *fd;
bool len_is_null = 1; bool len_is_null = 1;
char *delimiter_str = NULL; char *delimiter_str = NULL;
size_t delimiter_str_len = 0; size_t delimiter_str_len = 0;
@ -1820,7 +1763,7 @@ PHP_FUNCTION(fgetcsv)
zend_string *escape_str = NULL; zend_string *escape_str = NULL;
ZEND_PARSE_PARAMETERS_START(1, 5) ZEND_PARSE_PARAMETERS_START(1, 5)
Z_PARAM_RESOURCE(fd) PHP_Z_PARAM_STREAM(stream)
Z_PARAM_OPTIONAL Z_PARAM_OPTIONAL
Z_PARAM_LONG_OR_NULL(len, len_is_null) Z_PARAM_LONG_OR_NULL(len, len_is_null)
Z_PARAM_STRING(delimiter_str, delimiter_str_len) Z_PARAM_STRING(delimiter_str, delimiter_str_len)
@ -1861,8 +1804,6 @@ PHP_FUNCTION(fgetcsv)
RETURN_THROWS(); RETURN_THROWS();
} }
PHP_STREAM_FROM_ZVAL(stream, fd);
if (len < 0) { if (len < 0) {
if ((buf = php_stream_get_line(stream, NULL, 0, &buf_len)) == NULL) { if ((buf = php_stream_get_line(stream, NULL, 0, &buf_len)) == NULL) {
RETURN_FALSE; RETURN_FALSE;

View file

@ -17,13 +17,21 @@ var_dump(fwrite($fp, "data", -1));
var_dump(fwrite($fp, "data", 100000)); var_dump(fwrite($fp, "data", 100000));
fclose($fp); fclose($fp);
var_dump(fwrite($fp, "data", -1)); try {
var_dump(fwrite($fp, "data", -1));
} catch (Throwable $e) {
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
var_dump(file_get_contents($filename)); var_dump(file_get_contents($filename));
@unlink($filename);
echo "Done\n"; echo "Done\n";
?> ?>
--CLEAN--
<?php
$filename = __DIR__."/fwrite.dat";
@unlink($filename);
?>
--EXPECTF-- --EXPECTF--
int(0) int(0)
@ -31,6 +39,6 @@ Notice: fwrite(): Write of 4 bytes failed with errno=9 Bad file descriptor in %s
bool(false) bool(false)
int(0) int(0)
int(4) int(4)
int(0) TypeError: fwrite(): supplied resource is not a valid stream resource
string(4) "data" string(4) "data"
Done Done