2121#include "php.h"
2222#include "Zend/zend_interfaces.h"
2323#include "Zend/zend_exceptions.h"
24+ #include "Zend/zend_enum.h"
2425#include "main/php_ini.h"
2526
2627#include "php_uri.h"
@@ -38,6 +39,7 @@ zend_class_entry *uri_exception_ce;
3839zend_class_entry * uninitialized_uri_exception_ce ;
3940zend_class_entry * uri_operation_exception_ce ;
4041zend_class_entry * invalid_uri_exception_ce ;
42+ zend_class_entry * whatwg_error_type_ce ;
4143zend_class_entry * whatwg_error_ce ;
4244
4345static zend_array uri_handlers ;
@@ -181,25 +183,23 @@ PHPAPI void php_uri_free(uri_internal_t *internal_uri)
181183 efree (internal_uri );
182184}
183185
184- PHP_METHOD (Uri_WhatWgError , __construct )
186+ PHP_METHOD (Uri_WhatWg_WhatWgError , __construct )
185187{
186- zend_string * uri , * position ;
187- zend_long error ;
188+ zend_string * context ;
189+ zval * type ;
188190
189- ZEND_PARSE_PARAMETERS_START (3 , 3 )
190- Z_PARAM_STR (uri )
191- Z_PARAM_STR (position )
192- Z_PARAM_LONG (error )
191+ ZEND_PARSE_PARAMETERS_START (2 , 2 )
192+ Z_PARAM_STR (context )
193+ Z_PARAM_OBJECT_OF_CLASS (type , whatwg_error_type_ce )
193194 ZEND_PARSE_PARAMETERS_END ();
194195
195- zend_update_property_str (whatwg_error_ce , Z_OBJ_P (ZEND_THIS ), "uri ", sizeof(" uri ") - 1, uri);
196- zend_update_property_str (whatwg_error_ce , Z_OBJ_P (ZEND_THIS ), "position" , sizeof ("position" ) - 1 , position );
197- zend_update_property_long (whatwg_error_ce , Z_OBJ_P (ZEND_THIS ), "error" , sizeof ("error" ) - 1 , error );
196+ zend_update_property_str (whatwg_error_ce , Z_OBJ_P (ZEND_THIS ), "context" , sizeof ("context" ) - 1 , context );
197+ zend_update_property (whatwg_error_ce , Z_OBJ_P (ZEND_THIS ), "type" , sizeof ("type" ) - 1 , type );
198198}
199199
200200PHPAPI void php_uri_instantiate_uri (
201201 INTERNAL_FUNCTION_PARAMETERS , const uri_handler_t * handler , const zend_string * uri_str , const zend_string * base_url_str ,
202- bool is_constructor , bool return_errors
202+ bool is_constructor , zval * errors_zv
203203) {
204204 zval errors ;
205205 ZVAL_UNDEF (& errors );
@@ -211,8 +211,16 @@ PHPAPI void php_uri_instantiate_uri(
211211 zval_ptr_dtor (& errors );
212212 RETURN_THROWS ();
213213 } else {
214- if (return_errors && Z_TYPE (errors ) == IS_ARRAY ) {
215- RETURN_ZVAL (& errors , false, false);
214+ if (errors_zv != NULL && Z_TYPE (errors ) == IS_ARRAY ) {
215+ errors_zv = zend_try_array_init (errors_zv );
216+ if (!errors_zv ) {
217+ RETURN_THROWS ();
218+ }
219+
220+ zval * error ;
221+ ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (errors_zv ), error ) {
222+ zend_hash_next_index_insert (Z_ARRVAL_P (errors_zv ), error );
223+ } ZEND_HASH_FOREACH_END ();
216224 }
217225
218226 zval_ptr_dtor (& errors );
@@ -235,11 +243,13 @@ PHPAPI void php_uri_instantiate_uri(
235243static void create_rfc3986_uri (INTERNAL_FUNCTION_PARAMETERS , bool is_constructor )
236244{
237245 zend_string * uri_str , * base_url_str = NULL ;
246+ zval * errors ;
238247
239248 ZEND_PARSE_PARAMETERS_START (1 , 2 )
240249 Z_PARAM_PATH_STR (uri_str )
241250 Z_PARAM_OPTIONAL
242251 Z_PARAM_PATH_STR_OR_NULL (base_url_str )
252+ Z_PARAM_ZVAL (errors )
243253 ZEND_PARSE_PARAMETERS_END ();
244254
245255 if (ZSTR_LEN (uri_str ) == 0 ) {
@@ -252,7 +262,7 @@ static void create_rfc3986_uri(INTERNAL_FUNCTION_PARAMETERS, bool is_constructor
252262 RETURN_THROWS ();
253263 }
254264
255- php_uri_instantiate_uri (INTERNAL_FUNCTION_PARAM_PASSTHRU , & uriparser_uri_handler , uri_str , base_url_str , is_constructor , false );
265+ php_uri_instantiate_uri (INTERNAL_FUNCTION_PARAM_PASSTHRU , & uriparser_uri_handler , uri_str , base_url_str , is_constructor , NULL );
256266}
257267
258268PHP_METHOD (Uri_Rfc3986Uri , parse )
@@ -268,11 +278,13 @@ PHP_METHOD(Uri_Rfc3986Uri, __construct)
268278static void create_whatwg_uri (INTERNAL_FUNCTION_PARAMETERS , bool is_constructor )
269279{
270280 zend_string * uri_str , * base_url_str = NULL ;
281+ zval * errors = NULL ;
271282
272- ZEND_PARSE_PARAMETERS_START (1 , 2 )
283+ ZEND_PARSE_PARAMETERS_START (1 , 3 )
273284 Z_PARAM_PATH_STR (uri_str )
274285 Z_PARAM_OPTIONAL
275286 Z_PARAM_PATH_STR_OR_NULL (base_url_str )
287+ Z_PARAM_ZVAL (errors )
276288 ZEND_PARSE_PARAMETERS_END ();
277289
278290 if (ZSTR_LEN (uri_str ) == 0 ) {
@@ -285,7 +297,7 @@ static void create_whatwg_uri(INTERNAL_FUNCTION_PARAMETERS, bool is_constructor)
285297 RETURN_THROWS ();
286298 }
287299
288- php_uri_instantiate_uri (INTERNAL_FUNCTION_PARAM_PASSTHRU , & lexbor_uri_handler , uri_str , base_url_str , is_constructor , true );
300+ php_uri_instantiate_uri (INTERNAL_FUNCTION_PARAM_PASSTHRU , & lexbor_uri_handler , uri_str , base_url_str , is_constructor , errors );
289301}
290302
291303PHP_METHOD (Uri_WhatWgUri , parse )
@@ -378,7 +390,7 @@ PHP_METHOD(Uri_Rfc3986Uri, withFragment)
378390 URI_WITHER_STR (ZSTR_KNOWN (ZEND_STR_FRAGMENT ));
379391}
380392
381- PHP_METHOD (Uri_Rfc3986Uri , equalsTo )
393+ PHP_METHOD (Uri_Rfc3986Uri , equals )
382394{
383395 zend_object * that_object ;
384396 bool exclude_fragment = true;
@@ -514,7 +526,7 @@ PHP_METHOD(Uri_Rfc3986Uri, toNormalizedString)
514526 internal_uri -> handler -> free_uri (new_uri );
515527}
516528
517- PHP_METHOD (Uri_Rfc3986Uri , __toString )
529+ PHP_METHOD (Uri_Rfc3986Uri , toString )
518530{
519531 ZEND_PARSE_PARAMETERS_NONE ();
520532
@@ -525,6 +537,23 @@ PHP_METHOD(Uri_Rfc3986Uri, __toString)
525537 RETURN_STR (internal_uri -> handler -> uri_to_string (internal_uri -> uri , false));
526538}
527539
540+ PHP_METHOD (Uri_Rfc3986Uri , resolve )
541+ {
542+ zend_string * uri_str ;
543+
544+ ZEND_PARSE_PARAMETERS_START (1 , 1 ) \
545+ Z_PARAM_PATH_STR (uri_str ) \
546+ ZEND_PARSE_PARAMETERS_END (); \
547+
548+ zend_object * this_object = Z_OBJ_P (ZEND_THIS );
549+ uri_internal_t * internal_uri = uri_internal_from_obj (this_object );
550+ URI_CHECK_INITIALIZATION_RETURN_THROWS (internal_uri , this_object );
551+
552+ zend_string * base_uri_str = internal_uri -> handler -> uri_to_string (internal_uri -> uri , false); // TODO optimize by not reparsing the base URI
553+
554+ php_uri_instantiate_uri (INTERNAL_FUNCTION_PARAM_PASSTHRU , internal_uri -> handler , uri_str , base_uri_str , true, NULL );
555+ }
556+
528557PHP_METHOD (Uri_Rfc3986Uri , __serialize )
529558{
530559 ZEND_PARSE_PARAMETERS_NONE ();
@@ -839,9 +868,7 @@ zend_result uri_handler_register(const uri_handler_t *uri_handler)
839868
840869static PHP_MINIT_FUNCTION (uri )
841870{
842- register_php_uri_symbols (module_number );
843-
844- uri_interface_ce = register_class_Uri_UriInterface (zend_ce_stringable );
871+ uri_interface_ce = register_class_Uri_Uri ();
845872
846873 rfc3986_uri_ce = register_class_Uri_Rfc3986Uri (uri_interface_ce );
847874 php_uri_implementation_set_object_handlers (rfc3986_uri_ce , & rfc3986_uri_object_handlers );
@@ -853,7 +880,8 @@ static PHP_MINIT_FUNCTION(uri)
853880 uninitialized_uri_exception_ce = register_class_Uri_UninitializedUriException (uri_exception_ce );
854881 uri_operation_exception_ce = register_class_Uri_UriOperationException (uri_exception_ce );
855882 invalid_uri_exception_ce = register_class_Uri_InvalidUriException (uri_exception_ce );
856- whatwg_error_ce = register_class_Uri_WhatWgError ();
883+ whatwg_error_ce = register_class_Uri_WhatWg_WhatWgError ();
884+ whatwg_error_type_ce = register_class_Uri_WhatWg_WhatWgErrorType ();
857885
858886 zend_hash_init (& uri_handlers , 4 , NULL , ZVAL_PTR_DTOR , true);
859887
0 commit comments