mirror of
https://github.com/php/php-src.git
synced 2024-09-21 18:07:23 +00:00
Refactor user streams to use ZPP class check
Closes GH-5876
This commit is contained in:
parent
2a72778e2d
commit
73e070a614
@ -156,8 +156,11 @@ class mystream
|
||||
|
||||
}
|
||||
|
||||
if (@stream_wrapper_register("bogus", "class_not_exist")) {
|
||||
try {
|
||||
stream_wrapper_register("bogus", "class_not_exist");
|
||||
die("Registered a non-existent class!!!???");
|
||||
} catch (\TypeError $e) {
|
||||
echo $e->getMessage() . \PHP_EOL;
|
||||
}
|
||||
echo "Not Registered\n";
|
||||
|
||||
@ -315,6 +318,7 @@ echo $data . "\n";
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
stream_wrapper_register(): Argument #2 ($classname) must be a valid class name, class_not_exist given
|
||||
Not Registered
|
||||
Registered
|
||||
Registered
|
||||
|
@ -36,7 +36,6 @@ static int le_protocols;
|
||||
|
||||
struct php_user_stream_wrapper {
|
||||
char * protoname;
|
||||
char * classname;
|
||||
zend_class_entry *ce;
|
||||
php_stream_wrapper wrapper;
|
||||
};
|
||||
@ -71,7 +70,6 @@ static void stream_wrapper_dtor(zend_resource *rsrc)
|
||||
struct php_user_stream_wrapper * uwrap = (struct php_user_stream_wrapper*)rsrc->ptr;
|
||||
|
||||
efree(uwrap->protoname);
|
||||
efree(uwrap->classname);
|
||||
efree(uwrap);
|
||||
}
|
||||
|
||||
@ -375,7 +373,7 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, const char *
|
||||
ZVAL_COPY(&stream->wrapperdata, &us->object);
|
||||
} else {
|
||||
php_stream_wrapper_log_error(wrapper, options, "\"%s::" USERSTREAM_OPEN "\" call failed",
|
||||
us->wrapper->classname);
|
||||
ZSTR_VAL(us->wrapper->ce->name));
|
||||
}
|
||||
|
||||
/* destroy everything else */
|
||||
@ -444,7 +442,7 @@ static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, const char
|
||||
ZVAL_COPY(&stream->wrapperdata, &us->object);
|
||||
} else {
|
||||
php_stream_wrapper_log_error(wrapper, options, "\"%s::" USERSTREAM_DIR_OPEN "\" call failed",
|
||||
us->wrapper->classname);
|
||||
ZSTR_VAL(us->wrapper->ce->name));
|
||||
}
|
||||
|
||||
/* destroy everything else */
|
||||
@ -468,38 +466,35 @@ static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, const char
|
||||
/* {{{ Registers a custom URL protocol handler class */
|
||||
PHP_FUNCTION(stream_wrapper_register)
|
||||
{
|
||||
zend_string *protocol, *classname;
|
||||
struct php_user_stream_wrapper * uwrap;
|
||||
zend_string *protocol;
|
||||
struct php_user_stream_wrapper *uwrap;
|
||||
zend_class_entry *ce = NULL;
|
||||
zend_resource *rsrc;
|
||||
zend_long flags = 0;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS|l", &protocol, &classname, &flags) == FAILURE) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "SC|l", &protocol, &ce, &flags) == FAILURE) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
uwrap = (struct php_user_stream_wrapper *)ecalloc(1, sizeof(*uwrap));
|
||||
uwrap->ce = ce;
|
||||
uwrap->protoname = estrndup(ZSTR_VAL(protocol), ZSTR_LEN(protocol));
|
||||
uwrap->classname = estrndup(ZSTR_VAL(classname), ZSTR_LEN(classname));
|
||||
uwrap->wrapper.wops = &user_stream_wops;
|
||||
uwrap->wrapper.abstract = uwrap;
|
||||
uwrap->wrapper.is_url = ((flags & PHP_STREAM_IS_URL) != 0);
|
||||
|
||||
rsrc = zend_register_resource(uwrap, le_protocols);
|
||||
|
||||
if ((uwrap->ce = zend_lookup_class(classname)) != NULL) {
|
||||
if (php_register_url_stream_wrapper_volatile(protocol, &uwrap->wrapper) == SUCCESS) {
|
||||
RETURN_TRUE;
|
||||
} else {
|
||||
/* We failed. But why? */
|
||||
if (zend_hash_exists(php_stream_get_url_stream_wrappers_hash(), protocol)) {
|
||||
php_error_docref(NULL, E_WARNING, "Protocol %s:// is already defined.", ZSTR_VAL(protocol));
|
||||
} else {
|
||||
/* Hash doesn't exist so it must have been an invalid protocol scheme */
|
||||
php_error_docref(NULL, E_WARNING, "Invalid protocol scheme specified. Unable to register wrapper class %s to %s://", ZSTR_VAL(classname), ZSTR_VAL(protocol));
|
||||
}
|
||||
}
|
||||
if (php_register_url_stream_wrapper_volatile(protocol, &uwrap->wrapper) == SUCCESS) {
|
||||
RETURN_TRUE;
|
||||
}
|
||||
|
||||
/* We failed. But why? */
|
||||
if (zend_hash_exists(php_stream_get_url_stream_wrappers_hash(), protocol)) {
|
||||
php_error_docref(NULL, E_WARNING, "Protocol %s:// is already defined.", ZSTR_VAL(protocol));
|
||||
} else {
|
||||
php_error_docref(NULL, E_WARNING, "Class '%s' is undefined", ZSTR_VAL(classname));
|
||||
/* Hash doesn't exist so it must have been an invalid protocol scheme */
|
||||
php_error_docref(NULL, E_WARNING, "Invalid protocol scheme specified. Unable to register wrapper class %s to %s://", ZSTR_VAL(uwrap->ce->name), ZSTR_VAL(protocol));
|
||||
}
|
||||
|
||||
zend_list_delete(rsrc);
|
||||
@ -596,14 +591,14 @@ static ssize_t php_userstreamop_write(php_stream *stream, const char *buf, size_
|
||||
}
|
||||
} else {
|
||||
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_WRITE " is not implemented!",
|
||||
us->wrapper->classname);
|
||||
ZSTR_VAL(us->wrapper->ce->name));
|
||||
didwrite = -1;
|
||||
}
|
||||
|
||||
/* don't allow strange buffer overruns due to bogus return */
|
||||
if (didwrite > 0 && didwrite > count) {
|
||||
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_WRITE " wrote " ZEND_LONG_FMT " bytes more data than requested (" ZEND_LONG_FMT " written, " ZEND_LONG_FMT " max)",
|
||||
us->wrapper->classname,
|
||||
ZSTR_VAL(us->wrapper->ce->name),
|
||||
(zend_long)(didwrite - count), (zend_long)didwrite, (zend_long)count);
|
||||
didwrite = count;
|
||||
}
|
||||
@ -643,7 +638,7 @@ static ssize_t php_userstreamop_read(php_stream *stream, char *buf, size_t count
|
||||
|
||||
if (call_result == FAILURE) {
|
||||
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_READ " is not implemented!",
|
||||
us->wrapper->classname);
|
||||
ZSTR_VAL(us->wrapper->ce->name));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -659,7 +654,7 @@ static ssize_t php_userstreamop_read(php_stream *stream, char *buf, size_t count
|
||||
if (didread > 0) {
|
||||
if (didread > count) {
|
||||
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_READ " - read " ZEND_LONG_FMT " bytes more data than requested (" ZEND_LONG_FMT " read, " ZEND_LONG_FMT " max) - excess data will be lost",
|
||||
us->wrapper->classname, (zend_long)(didread - count), (zend_long)didread, (zend_long)count);
|
||||
ZSTR_VAL(us->wrapper->ce->name), (zend_long)(didread - count), (zend_long)didread, (zend_long)count);
|
||||
didread = count;
|
||||
}
|
||||
memcpy(buf, Z_STRVAL(retval), didread);
|
||||
@ -688,7 +683,7 @@ static ssize_t php_userstreamop_read(php_stream *stream, char *buf, size_t count
|
||||
} else if (call_result == FAILURE) {
|
||||
php_error_docref(NULL, E_WARNING,
|
||||
"%s::" USERSTREAM_EOF " is not implemented! Assuming EOF",
|
||||
us->wrapper->classname);
|
||||
ZSTR_VAL(us->wrapper->ce->name));
|
||||
|
||||
stream->eof = 1;
|
||||
}
|
||||
@ -812,7 +807,7 @@ static int php_userstreamop_seek(php_stream *stream, zend_off_t offset, int when
|
||||
*newoffs = Z_LVAL(retval);
|
||||
ret = 0;
|
||||
} else if (call_result == FAILURE) {
|
||||
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_TELL " is not implemented!", us->wrapper->classname);
|
||||
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_TELL " is not implemented!", ZSTR_VAL(us->wrapper->ce->name));
|
||||
ret = -1;
|
||||
} else {
|
||||
ret = -1;
|
||||
@ -884,7 +879,7 @@ static int php_userstreamop_stat(php_stream *stream, php_stream_statbuf *ssb)
|
||||
} else {
|
||||
if (call_result == FAILURE) {
|
||||
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_STAT " is not implemented!",
|
||||
us->wrapper->classname);
|
||||
ZSTR_VAL(us->wrapper->ce->name));
|
||||
}
|
||||
}
|
||||
|
||||
@ -913,7 +908,7 @@ static int php_userstreamop_set_option(php_stream *stream, int option, int value
|
||||
ret = PHP_STREAM_OPTION_RETURN_ERR;
|
||||
php_error_docref(NULL, E_WARNING,
|
||||
"%s::" USERSTREAM_EOF " is not implemented! Assuming EOF",
|
||||
us->wrapper->classname);
|
||||
ZSTR_VAL(us->wrapper->ce->name));
|
||||
}
|
||||
zval_ptr_dtor(&retval);
|
||||
zval_ptr_dtor(&func_name);
|
||||
@ -954,7 +949,7 @@ static int php_userstreamop_set_option(php_stream *stream, int option, int value
|
||||
ret = PHP_STREAM_OPTION_RETURN_OK;
|
||||
} else {
|
||||
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_LOCK " is not implemented!",
|
||||
us->wrapper->classname);
|
||||
ZSTR_VAL(us->wrapper->ce->name));
|
||||
ret = PHP_STREAM_OPTION_RETURN_ERR;
|
||||
}
|
||||
}
|
||||
@ -993,12 +988,12 @@ static int php_userstreamop_set_option(php_stream *stream, int option, int value
|
||||
} else {
|
||||
php_error_docref(NULL, E_WARNING,
|
||||
"%s::" USERSTREAM_TRUNCATE " did not return a boolean!",
|
||||
us->wrapper->classname);
|
||||
ZSTR_VAL(us->wrapper->ce->name));
|
||||
}
|
||||
} else {
|
||||
php_error_docref(NULL, E_WARNING,
|
||||
"%s::" USERSTREAM_TRUNCATE " is not implemented!",
|
||||
us->wrapper->classname);
|
||||
ZSTR_VAL(us->wrapper->ce->name));
|
||||
}
|
||||
zval_ptr_dtor(&retval);
|
||||
zval_ptr_dtor(&args[0]);
|
||||
@ -1053,7 +1048,7 @@ static int php_userstreamop_set_option(php_stream *stream, int option, int value
|
||||
|
||||
if (call_result == FAILURE) {
|
||||
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_SET_OPTION " is not implemented!",
|
||||
us->wrapper->classname);
|
||||
ZSTR_VAL(us->wrapper->ce->name));
|
||||
ret = PHP_STREAM_OPTION_RETURN_ERR;
|
||||
} else if (zend_is_true(&retval)) {
|
||||
ret = PHP_STREAM_OPTION_RETURN_OK;
|
||||
@ -1104,7 +1099,7 @@ static int user_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int
|
||||
if (call_result == SUCCESS && (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE)) {
|
||||
ret = (Z_TYPE(zretval) == IS_TRUE);
|
||||
} else if (call_result == FAILURE) {
|
||||
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_UNLINK " is not implemented!", uwrap->classname);
|
||||
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_UNLINK " is not implemented!", ZSTR_VAL(uwrap->ce->name));
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
@ -1148,7 +1143,7 @@ static int user_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from
|
||||
if (call_result == SUCCESS && (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE)) {
|
||||
ret = (Z_TYPE(zretval) == IS_TRUE);
|
||||
} else if (call_result == FAILURE) {
|
||||
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_RENAME " is not implemented!", uwrap->classname);
|
||||
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_RENAME " is not implemented!", ZSTR_VAL(uwrap->ce->name));
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
@ -1194,7 +1189,7 @@ static int user_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url, int
|
||||
if (call_result == SUCCESS && (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE)) {
|
||||
ret = (Z_TYPE(zretval) == IS_TRUE);
|
||||
} else if (call_result == FAILURE) {
|
||||
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_MKDIR " is not implemented!", uwrap->classname);
|
||||
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_MKDIR " is not implemented!", ZSTR_VAL(uwrap->ce->name));
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
@ -1240,7 +1235,7 @@ static int user_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url,
|
||||
if (call_result == SUCCESS && (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE)) {
|
||||
ret = (Z_TYPE(zretval) == IS_TRUE);
|
||||
} else if (call_result == FAILURE) {
|
||||
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_RMDIR " is not implemented!", uwrap->classname);
|
||||
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_RMDIR " is not implemented!", ZSTR_VAL(uwrap->ce->name));
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
@ -1310,7 +1305,7 @@ static int user_wrapper_metadata(php_stream_wrapper *wrapper, const char *url, i
|
||||
if (call_result == SUCCESS && (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE)) {
|
||||
ret = Z_TYPE(zretval) == IS_TRUE;
|
||||
} else if (call_result == FAILURE) {
|
||||
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_METADATA " is not implemented!", uwrap->classname);
|
||||
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_METADATA " is not implemented!", ZSTR_VAL(uwrap->ce->name));
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
@ -1361,7 +1356,7 @@ static int user_wrapper_stat_url(php_stream_wrapper *wrapper, const char *url, i
|
||||
} else {
|
||||
if (call_result == FAILURE) {
|
||||
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_STATURL " is not implemented!",
|
||||
uwrap->classname);
|
||||
ZSTR_VAL(uwrap->ce->name));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1405,7 +1400,7 @@ static ssize_t php_userstreamop_readdir(php_stream *stream, char *buf, size_t co
|
||||
didread = sizeof(php_stream_dirent);
|
||||
} else if (call_result == FAILURE) {
|
||||
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_DIR_READ " is not implemented!",
|
||||
us->wrapper->classname);
|
||||
ZSTR_VAL(us->wrapper->ce->name));
|
||||
}
|
||||
|
||||
zval_ptr_dtor(&retval);
|
||||
@ -1491,7 +1486,7 @@ static int php_userstreamop_cast(php_stream *stream, int castas, void **retptr)
|
||||
do {
|
||||
if (call_result == FAILURE) {
|
||||
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_CAST " is not implemented!",
|
||||
us->wrapper->classname);
|
||||
ZSTR_VAL(us->wrapper->ce->name));
|
||||
break;
|
||||
}
|
||||
if (!zend_is_true(&retval)) {
|
||||
@ -1500,12 +1495,12 @@ static int php_userstreamop_cast(php_stream *stream, int castas, void **retptr)
|
||||
php_stream_from_zval_no_verify(intstream, &retval);
|
||||
if (!intstream) {
|
||||
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_CAST " must return a stream resource",
|
||||
us->wrapper->classname);
|
||||
ZSTR_VAL(us->wrapper->ce->name));
|
||||
break;
|
||||
}
|
||||
if (intstream == stream) {
|
||||
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_CAST " must not return itself",
|
||||
us->wrapper->classname);
|
||||
ZSTR_VAL(us->wrapper->ce->name));
|
||||
intstream = NULL;
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user