Skip to content

Commit 0dee55c

Browse files
committed
Refactor user streams
1 parent efce369 commit 0dee55c

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

@@ -395,7 +393,7 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, const char *
395393
ZVAL_COPY(&stream->wrapperdata, &us->object);
396394
} else {
397395
php_stream_wrapper_log_error(wrapper, options, "\"%s::" USERSTREAM_OPEN "\" call failed",
398-
us->wrapper->classname);
396+
ZSTR_VAL(us->wrapper->ce->name));
399397
}
400398

401399
/* destroy everything else */
@@ -464,7 +462,7 @@ static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, const char
464462
ZVAL_COPY(&stream->wrapperdata, &us->object);
465463
} else {
466464
php_stream_wrapper_log_error(wrapper, options, "\"%s::" USERSTREAM_DIR_OPEN "\" call failed",
467-
us->wrapper->classname);
465+
ZSTR_VAL(us->wrapper->ce->name));
468466
}
469467

470468
/* destroy everything else */
@@ -488,38 +486,33 @@ static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, const char
488486
/* {{{ Registers a custom URL protocol handler class */
489487
PHP_FUNCTION(stream_wrapper_register)
490488
{
491-
zend_string *protocol, *classname;
492-
struct php_user_stream_wrapper * uwrap;
489+
zend_string *protocol;
490+
struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper *)ecalloc(1, sizeof(*uwrap));;
493491
zend_resource *rsrc;
494492
zend_long flags = 0;
495493

496-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS|l", &protocol, &classname, &flags) == FAILURE) {
494+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "SC|l", &protocol, &uwrap->ce, &flags) == FAILURE) {
495+
efree(uwrap);
497496
RETURN_THROWS();
498497
}
499498

500-
uwrap = (struct php_user_stream_wrapper *)ecalloc(1, sizeof(*uwrap));
501499
uwrap->protoname = estrndup(ZSTR_VAL(protocol), ZSTR_LEN(protocol));
502-
uwrap->classname = estrndup(ZSTR_VAL(classname), ZSTR_LEN(classname));
503500
uwrap->wrapper.wops = &user_stream_wops;
504501
uwrap->wrapper.abstract = uwrap;
505502
uwrap->wrapper.is_url = ((flags & PHP_STREAM_IS_URL) != 0);
506503

507504
rsrc = zend_register_resource(uwrap, le_protocols);
508505

509-
if ((uwrap->ce = zend_lookup_class(classname)) != NULL) {
510-
if (php_register_url_stream_wrapper_volatile(protocol, &uwrap->wrapper) == SUCCESS) {
511-
RETURN_TRUE;
512-
} else {
513-
/* We failed. But why? */
514-
if (zend_hash_exists(php_stream_get_url_stream_wrappers_hash(), protocol)) {
515-
php_error_docref(NULL, E_WARNING, "Protocol %s:// is already defined.", ZSTR_VAL(protocol));
516-
} else {
517-
/* Hash doesn't exist so it must have been an invalid protocol scheme */
518-
php_error_docref(NULL, E_WARNING, "Invalid protocol scheme specified. Unable to register wrapper class %s to %s://", ZSTR_VAL(classname), ZSTR_VAL(protocol));
519-
}
520-
}
506+
if (php_register_url_stream_wrapper_volatile(protocol, &uwrap->wrapper) == SUCCESS) {
507+
RETURN_TRUE;
508+
}
509+
510+
/* We failed. But why? */
511+
if (zend_hash_exists(php_stream_get_url_stream_wrappers_hash(), protocol)) {
512+
php_error_docref(NULL, E_WARNING, "Protocol %s:// is already defined.", ZSTR_VAL(protocol));
521513
} else {
522-
php_error_docref(NULL, E_WARNING, "Class '%s' is undefined", ZSTR_VAL(classname));
514+
/* Hash doesn't exist so it must have been an invalid protocol scheme */
515+
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));
523516
}
524517

525518
zend_list_delete(rsrc);
@@ -616,14 +609,14 @@ static ssize_t php_userstreamop_write(php_stream *stream, const char *buf, size_
616609
}
617610
} else {
618611
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_WRITE " is not implemented!",
619-
us->wrapper->classname);
612+
ZSTR_VAL(us->wrapper->ce->name));
620613
didwrite = -1;
621614
}
622615

623616
/* don't allow strange buffer overruns due to bogus return */
624617
if (didwrite > 0 && didwrite > count) {
625618
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)",
626-
us->wrapper->classname,
619+
ZSTR_VAL(us->wrapper->ce->name),
627620
(zend_long)(didwrite - count), (zend_long)didwrite, (zend_long)count);
628621
didwrite = count;
629622
}
@@ -663,7 +656,7 @@ static ssize_t php_userstreamop_read(php_stream *stream, char *buf, size_t count
663656

664657
if (call_result == FAILURE) {
665658
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_READ " is not implemented!",
666-
us->wrapper->classname);
659+
ZSTR_VAL(us->wrapper->ce->name));
667660
return -1;
668661
}
669662

@@ -679,7 +672,7 @@ static ssize_t php_userstreamop_read(php_stream *stream, char *buf, size_t count
679672
if (didread > 0) {
680673
if (didread > count) {
681674
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",
682-
us->wrapper->classname, (zend_long)(didread - count), (zend_long)didread, (zend_long)count);
675+
ZSTR_VAL(us->wrapper->ce->name), (zend_long)(didread - count), (zend_long)didread, (zend_long)count);
683676
didread = count;
684677
}
685678
memcpy(buf, Z_STRVAL(retval), didread);
@@ -708,7 +701,7 @@ static ssize_t php_userstreamop_read(php_stream *stream, char *buf, size_t count
708701
} else if (call_result == FAILURE) {
709702
php_error_docref(NULL, E_WARNING,
710703
"%s::" USERSTREAM_EOF " is not implemented! Assuming EOF",
711-
us->wrapper->classname);
704+
ZSTR_VAL(us->wrapper->ce->name));
712705

713706
stream->eof = 1;
714707
}
@@ -832,7 +825,7 @@ static int php_userstreamop_seek(php_stream *stream, zend_off_t offset, int when
832825
*newoffs = Z_LVAL(retval);
833826
ret = 0;
834827
} else if (call_result == FAILURE) {
835-
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_TELL " is not implemented!", us->wrapper->classname);
828+
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_TELL " is not implemented!", ZSTR_VAL(us->wrapper->ce->name));
836829
ret = -1;
837830
} else {
838831
ret = -1;
@@ -904,7 +897,7 @@ static int php_userstreamop_stat(php_stream *stream, php_stream_statbuf *ssb)
904897
} else {
905898
if (call_result == FAILURE) {
906899
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_STAT " is not implemented!",
907-
us->wrapper->classname);
900+
ZSTR_VAL(us->wrapper->ce->name));
908901
}
909902
}
910903

@@ -933,7 +926,7 @@ static int php_userstreamop_set_option(php_stream *stream, int option, int value
933926
ret = PHP_STREAM_OPTION_RETURN_ERR;
934927
php_error_docref(NULL, E_WARNING,
935928
"%s::" USERSTREAM_EOF " is not implemented! Assuming EOF",
936-
us->wrapper->classname);
929+
ZSTR_VAL(us->wrapper->ce->name));
937930
}
938931
zval_ptr_dtor(&retval);
939932
zval_ptr_dtor(&func_name);
@@ -974,7 +967,7 @@ static int php_userstreamop_set_option(php_stream *stream, int option, int value
974967
ret = PHP_STREAM_OPTION_RETURN_OK;
975968
} else {
976969
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_LOCK " is not implemented!",
977-
us->wrapper->classname);
970+
ZSTR_VAL(us->wrapper->ce->name));
978971
ret = PHP_STREAM_OPTION_RETURN_ERR;
979972
}
980973
}
@@ -1013,12 +1006,12 @@ static int php_userstreamop_set_option(php_stream *stream, int option, int value
10131006
} else {
10141007
php_error_docref(NULL, E_WARNING,
10151008
"%s::" USERSTREAM_TRUNCATE " did not return a boolean!",
1016-
us->wrapper->classname);
1009+
ZSTR_VAL(us->wrapper->ce->name));
10171010
}
10181011
} else {
10191012
php_error_docref(NULL, E_WARNING,
10201013
"%s::" USERSTREAM_TRUNCATE " is not implemented!",
1021-
us->wrapper->classname);
1014+
ZSTR_VAL(us->wrapper->ce->name));
10221015
}
10231016
zval_ptr_dtor(&retval);
10241017
zval_ptr_dtor(&args[0]);
@@ -1073,7 +1066,7 @@ static int php_userstreamop_set_option(php_stream *stream, int option, int value
10731066

10741067
if (call_result == FAILURE) {
10751068
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_SET_OPTION " is not implemented!",
1076-
us->wrapper->classname);
1069+
ZSTR_VAL(us->wrapper->ce->name));
10771070
ret = PHP_STREAM_OPTION_RETURN_ERR;
10781071
} else if (zend_is_true(&retval)) {
10791072
ret = PHP_STREAM_OPTION_RETURN_OK;
@@ -1124,7 +1117,7 @@ static int user_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int
11241117
if (call_result == SUCCESS && (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE)) {
11251118
ret = (Z_TYPE(zretval) == IS_TRUE);
11261119
} else if (call_result == FAILURE) {
1127-
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_UNLINK " is not implemented!", uwrap->classname);
1120+
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_UNLINK " is not implemented!", ZSTR_VAL(uwrap->ce->name));
11281121
}
11291122

11301123
/* clean up */
@@ -1168,7 +1161,7 @@ static int user_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from
11681161
if (call_result == SUCCESS && (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE)) {
11691162
ret = (Z_TYPE(zretval) == IS_TRUE);
11701163
} else if (call_result == FAILURE) {
1171-
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_RENAME " is not implemented!", uwrap->classname);
1164+
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_RENAME " is not implemented!", ZSTR_VAL(uwrap->ce->name));
11721165
}
11731166

11741167
/* clean up */
@@ -1214,7 +1207,7 @@ static int user_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url, int
12141207
if (call_result == SUCCESS && (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE)) {
12151208
ret = (Z_TYPE(zretval) == IS_TRUE);
12161209
} else if (call_result == FAILURE) {
1217-
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_MKDIR " is not implemented!", uwrap->classname);
1210+
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_MKDIR " is not implemented!", ZSTR_VAL(uwrap->ce->name));
12181211
}
12191212

12201213
/* clean up */
@@ -1260,7 +1253,7 @@ static int user_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url,
12601253
if (call_result == SUCCESS && (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE)) {
12611254
ret = (Z_TYPE(zretval) == IS_TRUE);
12621255
} else if (call_result == FAILURE) {
1263-
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_RMDIR " is not implemented!", uwrap->classname);
1256+
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_RMDIR " is not implemented!", ZSTR_VAL(uwrap->ce->name));
12641257
}
12651258

12661259
/* clean up */
@@ -1330,7 +1323,7 @@ static int user_wrapper_metadata(php_stream_wrapper *wrapper, const char *url, i
13301323
if (call_result == SUCCESS && (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE)) {
13311324
ret = Z_TYPE(zretval) == IS_TRUE;
13321325
} else if (call_result == FAILURE) {
1333-
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_METADATA " is not implemented!", uwrap->classname);
1326+
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_METADATA " is not implemented!", ZSTR_VAL(uwrap->ce->name));
13341327
}
13351328

13361329
/* clean up */
@@ -1381,7 +1374,7 @@ static int user_wrapper_stat_url(php_stream_wrapper *wrapper, const char *url, i
13811374
} else {
13821375
if (call_result == FAILURE) {
13831376
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_STATURL " is not implemented!",
1384-
uwrap->classname);
1377+
ZSTR_VAL(uwrap->ce->name));
13851378
}
13861379
}
13871380

@@ -1425,7 +1418,7 @@ static ssize_t php_userstreamop_readdir(php_stream *stream, char *buf, size_t co
14251418
didread = sizeof(php_stream_dirent);
14261419
} else if (call_result == FAILURE) {
14271420
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_DIR_READ " is not implemented!",
1428-
us->wrapper->classname);
1421+
ZSTR_VAL(us->wrapper->ce->name));
14291422
}
14301423

14311424
zval_ptr_dtor(&retval);
@@ -1511,7 +1504,7 @@ static int php_userstreamop_cast(php_stream *stream, int castas, void **retptr)
15111504
do {
15121505
if (call_result == FAILURE) {
15131506
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_CAST " is not implemented!",
1514-
us->wrapper->classname);
1507+
ZSTR_VAL(us->wrapper->ce->name));
15151508
break;
15161509
}
15171510
if (!zend_is_true(&retval)) {
@@ -1520,12 +1513,12 @@ static int php_userstreamop_cast(php_stream *stream, int castas, void **retptr)
15201513
php_stream_from_zval_no_verify(intstream, &retval);
15211514
if (!intstream) {
15221515
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_CAST " must return a stream resource",
1523-
us->wrapper->classname);
1516+
ZSTR_VAL(us->wrapper->ce->name));
15241517
break;
15251518
}
15261519
if (intstream == stream) {
15271520
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_CAST " must not return itself",
1528-
us->wrapper->classname);
1521+
ZSTR_VAL(us->wrapper->ce->name));
15291522
intstream = NULL;
15301523
break;
15311524
}

0 commit comments

Comments
 (0)