Skip to content

Commit 9925f50

Browse files
committed
Refactor user streams
1 parent 44ad2db commit 9925f50

File tree

2 files changed

+42
-45
lines changed

2 files changed

+42
-45
lines changed

ext/standard/tests/file/userstreams.phpt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,11 @@ class mystream
156156

157157
}
158158

159-
if (@stream_wrapper_register("bogus", "class_not_exist")) {
159+
try {
160+
stream_wrapper_register("bogus", "class_not_exist");
160161
die("Registered a non-existent class!!!???");
162+
} catch (\TypeError $e) {
163+
echo $e->getMessage() . \PHP_EOL;
161164
}
162165
echo "Not Registered\n";
163166

@@ -315,6 +318,7 @@ echo $data . "\n";
315318

316319
?>
317320
--EXPECT--
321+
stream_wrapper_register(): Argument #2 ($classname) must be a valid class name, class_not_exist given
318322
Not Registered
319323
Registered
320324
Registered

main/streams/userspace.c

Lines changed: 37 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ static int le_protocols;
3636

3737
struct php_user_stream_wrapper {
3838
char * protoname;
39-
char * classname;
4039
zend_class_entry *ce;
4140
php_stream_wrapper wrapper;
4241
};
@@ -71,7 +70,6 @@ static void stream_wrapper_dtor(zend_resource *rsrc)
7170
struct php_user_stream_wrapper * uwrap = (struct php_user_stream_wrapper*)rsrc->ptr;
7271

7372
efree(uwrap->protoname);
74-
efree(uwrap->classname);
7573
efree(uwrap);
7674
}
7775

@@ -375,7 +373,7 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, const char *
375373
ZVAL_COPY(&stream->wrapperdata, &us->object);
376374
} else {
377375
php_stream_wrapper_log_error(wrapper, options, "\"%s::" USERSTREAM_OPEN "\" call failed",
378-
us->wrapper->classname);
376+
ZSTR_VAL(us->wrapper->ce->name));
379377
}
380378

381379
/* destroy everything else */
@@ -444,7 +442,7 @@ static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, const char
444442
ZVAL_COPY(&stream->wrapperdata, &us->object);
445443
} else {
446444
php_stream_wrapper_log_error(wrapper, options, "\"%s::" USERSTREAM_DIR_OPEN "\" call failed",
447-
us->wrapper->classname);
445+
ZSTR_VAL(us->wrapper->ce->name));
448446
}
449447

450448
/* destroy everything else */
@@ -468,38 +466,33 @@ static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, const char
468466
/* {{{ Registers a custom URL protocol handler class */
469467
PHP_FUNCTION(stream_wrapper_register)
470468
{
471-
zend_string *protocol, *classname;
472-
struct php_user_stream_wrapper * uwrap;
469+
zend_string *protocol;
470+
struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper *)ecalloc(1, sizeof(*uwrap));;
473471
zend_resource *rsrc;
474472
zend_long flags = 0;
475473

476-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS|l", &protocol, &classname, &flags) == FAILURE) {
474+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "SC|l", &protocol, &uwrap->ce, &flags) == FAILURE) {
475+
efree(uwrap);
477476
RETURN_THROWS();
478477
}
479478

480-
uwrap = (struct php_user_stream_wrapper *)ecalloc(1, sizeof(*uwrap));
481479
uwrap->protoname = estrndup(ZSTR_VAL(protocol), ZSTR_LEN(protocol));
482-
uwrap->classname = estrndup(ZSTR_VAL(classname), ZSTR_LEN(classname));
483480
uwrap->wrapper.wops = &user_stream_wops;
484481
uwrap->wrapper.abstract = uwrap;
485482
uwrap->wrapper.is_url = ((flags & PHP_STREAM_IS_URL) != 0);
486483

487484
rsrc = zend_register_resource(uwrap, le_protocols);
488485

489-
if ((uwrap->ce = zend_lookup_class(classname)) != NULL) {
490-
if (php_register_url_stream_wrapper_volatile(protocol, &uwrap->wrapper) == SUCCESS) {
491-
RETURN_TRUE;
492-
} else {
493-
/* We failed. But why? */
494-
if (zend_hash_exists(php_stream_get_url_stream_wrappers_hash(), protocol)) {
495-
php_error_docref(NULL, E_WARNING, "Protocol %s:// is already defined.", ZSTR_VAL(protocol));
496-
} else {
497-
/* Hash doesn't exist so it must have been an invalid protocol scheme */
498-
php_error_docref(NULL, E_WARNING, "Invalid protocol scheme specified. Unable to register wrapper class %s to %s://", ZSTR_VAL(classname), ZSTR_VAL(protocol));
499-
}
500-
}
486+
if (php_register_url_stream_wrapper_volatile(protocol, &uwrap->wrapper) == SUCCESS) {
487+
RETURN_TRUE;
488+
}
489+
490+
/* We failed. But why? */
491+
if (zend_hash_exists(php_stream_get_url_stream_wrappers_hash(), protocol)) {
492+
php_error_docref(NULL, E_WARNING, "Protocol %s:// is already defined.", ZSTR_VAL(protocol));
501493
} else {
502-
php_error_docref(NULL, E_WARNING, "Class '%s' is undefined", ZSTR_VAL(classname));
494+
/* Hash doesn't exist so it must have been an invalid protocol scheme */
495+
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));
503496
}
504497

505498
zend_list_delete(rsrc);
@@ -596,14 +589,14 @@ static ssize_t php_userstreamop_write(php_stream *stream, const char *buf, size_
596589
}
597590
} else {
598591
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_WRITE " is not implemented!",
599-
us->wrapper->classname);
592+
ZSTR_VAL(us->wrapper->ce->name));
600593
didwrite = -1;
601594
}
602595

603596
/* don't allow strange buffer overruns due to bogus return */
604597
if (didwrite > 0 && didwrite > count) {
605598
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)",
606-
us->wrapper->classname,
599+
ZSTR_VAL(us->wrapper->ce->name),
607600
(zend_long)(didwrite - count), (zend_long)didwrite, (zend_long)count);
608601
didwrite = count;
609602
}
@@ -643,7 +636,7 @@ static ssize_t php_userstreamop_read(php_stream *stream, char *buf, size_t count
643636

644637
if (call_result == FAILURE) {
645638
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_READ " is not implemented!",
646-
us->wrapper->classname);
639+
ZSTR_VAL(us->wrapper->ce->name));
647640
return -1;
648641
}
649642

@@ -659,7 +652,7 @@ static ssize_t php_userstreamop_read(php_stream *stream, char *buf, size_t count
659652
if (didread > 0) {
660653
if (didread > count) {
661654
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",
662-
us->wrapper->classname, (zend_long)(didread - count), (zend_long)didread, (zend_long)count);
655+
ZSTR_VAL(us->wrapper->ce->name), (zend_long)(didread - count), (zend_long)didread, (zend_long)count);
663656
didread = count;
664657
}
665658
memcpy(buf, Z_STRVAL(retval), didread);
@@ -688,7 +681,7 @@ static ssize_t php_userstreamop_read(php_stream *stream, char *buf, size_t count
688681
} else if (call_result == FAILURE) {
689682
php_error_docref(NULL, E_WARNING,
690683
"%s::" USERSTREAM_EOF " is not implemented! Assuming EOF",
691-
us->wrapper->classname);
684+
ZSTR_VAL(us->wrapper->ce->name));
692685

693686
stream->eof = 1;
694687
}
@@ -812,7 +805,7 @@ static int php_userstreamop_seek(php_stream *stream, zend_off_t offset, int when
812805
*newoffs = Z_LVAL(retval);
813806
ret = 0;
814807
} else if (call_result == FAILURE) {
815-
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_TELL " is not implemented!", us->wrapper->classname);
808+
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_TELL " is not implemented!", ZSTR_VAL(us->wrapper->ce->name));
816809
ret = -1;
817810
} else {
818811
ret = -1;
@@ -884,7 +877,7 @@ static int php_userstreamop_stat(php_stream *stream, php_stream_statbuf *ssb)
884877
} else {
885878
if (call_result == FAILURE) {
886879
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_STAT " is not implemented!",
887-
us->wrapper->classname);
880+
ZSTR_VAL(us->wrapper->ce->name));
888881
}
889882
}
890883

@@ -913,7 +906,7 @@ static int php_userstreamop_set_option(php_stream *stream, int option, int value
913906
ret = PHP_STREAM_OPTION_RETURN_ERR;
914907
php_error_docref(NULL, E_WARNING,
915908
"%s::" USERSTREAM_EOF " is not implemented! Assuming EOF",
916-
us->wrapper->classname);
909+
ZSTR_VAL(us->wrapper->ce->name));
917910
}
918911
zval_ptr_dtor(&retval);
919912
zval_ptr_dtor(&func_name);
@@ -954,7 +947,7 @@ static int php_userstreamop_set_option(php_stream *stream, int option, int value
954947
ret = PHP_STREAM_OPTION_RETURN_OK;
955948
} else {
956949
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_LOCK " is not implemented!",
957-
us->wrapper->classname);
950+
ZSTR_VAL(us->wrapper->ce->name));
958951
ret = PHP_STREAM_OPTION_RETURN_ERR;
959952
}
960953
}
@@ -993,12 +986,12 @@ static int php_userstreamop_set_option(php_stream *stream, int option, int value
993986
} else {
994987
php_error_docref(NULL, E_WARNING,
995988
"%s::" USERSTREAM_TRUNCATE " did not return a boolean!",
996-
us->wrapper->classname);
989+
ZSTR_VAL(us->wrapper->ce->name));
997990
}
998991
} else {
999992
php_error_docref(NULL, E_WARNING,
1000993
"%s::" USERSTREAM_TRUNCATE " is not implemented!",
1001-
us->wrapper->classname);
994+
ZSTR_VAL(us->wrapper->ce->name));
1002995
}
1003996
zval_ptr_dtor(&retval);
1004997
zval_ptr_dtor(&args[0]);
@@ -1053,7 +1046,7 @@ static int php_userstreamop_set_option(php_stream *stream, int option, int value
10531046

10541047
if (call_result == FAILURE) {
10551048
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_SET_OPTION " is not implemented!",
1056-
us->wrapper->classname);
1049+
ZSTR_VAL(us->wrapper->ce->name));
10571050
ret = PHP_STREAM_OPTION_RETURN_ERR;
10581051
} else if (zend_is_true(&retval)) {
10591052
ret = PHP_STREAM_OPTION_RETURN_OK;
@@ -1104,7 +1097,7 @@ static int user_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int
11041097
if (call_result == SUCCESS && (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE)) {
11051098
ret = (Z_TYPE(zretval) == IS_TRUE);
11061099
} else if (call_result == FAILURE) {
1107-
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_UNLINK " is not implemented!", uwrap->classname);
1100+
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_UNLINK " is not implemented!", ZSTR_VAL(uwrap->ce->name));
11081101
}
11091102

11101103
/* clean up */
@@ -1148,7 +1141,7 @@ static int user_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from
11481141
if (call_result == SUCCESS && (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE)) {
11491142
ret = (Z_TYPE(zretval) == IS_TRUE);
11501143
} else if (call_result == FAILURE) {
1151-
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_RENAME " is not implemented!", uwrap->classname);
1144+
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_RENAME " is not implemented!", ZSTR_VAL(uwrap->ce->name));
11521145
}
11531146

11541147
/* clean up */
@@ -1194,7 +1187,7 @@ static int user_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url, int
11941187
if (call_result == SUCCESS && (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE)) {
11951188
ret = (Z_TYPE(zretval) == IS_TRUE);
11961189
} else if (call_result == FAILURE) {
1197-
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_MKDIR " is not implemented!", uwrap->classname);
1190+
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_MKDIR " is not implemented!", ZSTR_VAL(uwrap->ce->name));
11981191
}
11991192

12001193
/* clean up */
@@ -1240,7 +1233,7 @@ static int user_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url,
12401233
if (call_result == SUCCESS && (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE)) {
12411234
ret = (Z_TYPE(zretval) == IS_TRUE);
12421235
} else if (call_result == FAILURE) {
1243-
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_RMDIR " is not implemented!", uwrap->classname);
1236+
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_RMDIR " is not implemented!", ZSTR_VAL(uwrap->ce->name));
12441237
}
12451238

12461239
/* clean up */
@@ -1310,7 +1303,7 @@ static int user_wrapper_metadata(php_stream_wrapper *wrapper, const char *url, i
13101303
if (call_result == SUCCESS && (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE)) {
13111304
ret = Z_TYPE(zretval) == IS_TRUE;
13121305
} else if (call_result == FAILURE) {
1313-
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_METADATA " is not implemented!", uwrap->classname);
1306+
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_METADATA " is not implemented!", ZSTR_VAL(uwrap->ce->name));
13141307
}
13151308

13161309
/* clean up */
@@ -1361,7 +1354,7 @@ static int user_wrapper_stat_url(php_stream_wrapper *wrapper, const char *url, i
13611354
} else {
13621355
if (call_result == FAILURE) {
13631356
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_STATURL " is not implemented!",
1364-
uwrap->classname);
1357+
ZSTR_VAL(uwrap->ce->name));
13651358
}
13661359
}
13671360

@@ -1405,7 +1398,7 @@ static ssize_t php_userstreamop_readdir(php_stream *stream, char *buf, size_t co
14051398
didread = sizeof(php_stream_dirent);
14061399
} else if (call_result == FAILURE) {
14071400
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_DIR_READ " is not implemented!",
1408-
us->wrapper->classname);
1401+
ZSTR_VAL(us->wrapper->ce->name));
14091402
}
14101403

14111404
zval_ptr_dtor(&retval);
@@ -1491,7 +1484,7 @@ static int php_userstreamop_cast(php_stream *stream, int castas, void **retptr)
14911484
do {
14921485
if (call_result == FAILURE) {
14931486
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_CAST " is not implemented!",
1494-
us->wrapper->classname);
1487+
ZSTR_VAL(us->wrapper->ce->name));
14951488
break;
14961489
}
14971490
if (!zend_is_true(&retval)) {
@@ -1500,12 +1493,12 @@ static int php_userstreamop_cast(php_stream *stream, int castas, void **retptr)
15001493
php_stream_from_zval_no_verify(intstream, &retval);
15011494
if (!intstream) {
15021495
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_CAST " must return a stream resource",
1503-
us->wrapper->classname);
1496+
ZSTR_VAL(us->wrapper->ce->name));
15041497
break;
15051498
}
15061499
if (intstream == stream) {
15071500
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_CAST " must not return itself",
1508-
us->wrapper->classname);
1501+
ZSTR_VAL(us->wrapper->ce->name));
15091502
intstream = NULL;
15101503
break;
15111504
}

0 commit comments

Comments
 (0)