@@ -364,7 +364,7 @@ PHPAPI void php_uri_instantiate_uri(
364
364
void * base_url = NULL ;
365
365
if (base_url_object != NULL ) {
366
366
uri_internal_t * internal_base_url = uri_internal_from_obj (base_url_object );
367
- URI_CHECK_INITIALIZATION (internal_base_url );
367
+ URI_ASSERT_INITIALIZATION (internal_base_url );
368
368
base_url = internal_base_url -> uri ;
369
369
}
370
370
@@ -522,7 +522,7 @@ PHP_METHOD(Uri_Rfc3986_Uri, getPort)
522
522
523
523
PHP_METHOD (Uri_Rfc3986_Uri , withPort )
524
524
{
525
- URI_WITHER_LONG (ZSTR_KNOWN (ZEND_STR_PORT ));
525
+ URI_WITHER_LONG_OR_NULL (ZSTR_KNOWN (ZEND_STR_PORT ));
526
526
}
527
527
528
528
PHP_METHOD (Uri_Rfc3986_Uri , getPath )
@@ -574,10 +574,10 @@ static void uri_equals(INTERNAL_FUNCTION_PARAMETERS, zend_object *that_object, z
574
574
{
575
575
zend_object * this_object = Z_OBJ_P (ZEND_THIS );
576
576
uri_internal_t * this_internal_uri = uri_internal_from_obj (this_object );
577
- URI_CHECK_INITIALIZATION (this_internal_uri );
577
+ URI_ASSERT_INITIALIZATION (this_internal_uri );
578
578
579
579
uri_internal_t * that_internal_uri = uri_internal_from_obj (that_object );
580
- URI_CHECK_INITIALIZATION (that_internal_uri );
580
+ URI_ASSERT_INITIALIZATION (that_internal_uri );
581
581
582
582
if (this_object -> ce != that_object -> ce &&
583
583
!instanceof_function (this_object -> ce , that_object -> ce ) &&
@@ -595,15 +595,16 @@ static void uri_equals(INTERNAL_FUNCTION_PARAMETERS, zend_object *that_object, z
595
595
}
596
596
597
597
zend_string * this_str = this_internal_uri -> handler -> uri_to_string (
598
- this_internal_uri -> uri , URI_RECOMPOSITION_NORMALIZED_ASCII , exclude_fragment );
598
+ this_internal_uri -> uri , URI_RECOMPOSITION_NORMALIZED_ASCII , exclude_fragment );
599
599
if (this_str == NULL ) {
600
600
zend_throw_exception_ex (NULL , 0 , "Cannot recompose %s to string" , ZSTR_VAL (this_object -> ce -> name ));
601
601
RETURN_THROWS ();
602
602
}
603
603
604
604
zend_string * that_str = that_internal_uri -> handler -> uri_to_string (
605
- that_internal_uri -> uri , URI_RECOMPOSITION_NORMALIZED_ASCII , exclude_fragment );
605
+ that_internal_uri -> uri , URI_RECOMPOSITION_NORMALIZED_ASCII , exclude_fragment );
606
606
if (that_str == NULL ) {
607
+ zend_string_release (this_str );
607
608
zend_throw_exception_ex (NULL , 0 , "Cannot recompose %s to string" , ZSTR_VAL (that_object -> ce -> name ));
608
609
RETURN_THROWS ();
609
610
}
@@ -634,7 +635,7 @@ PHP_METHOD(Uri_Rfc3986_Uri, toRawString)
634
635
635
636
zend_object * this_object = Z_OBJ_P (ZEND_THIS );
636
637
uri_internal_t * internal_uri = uri_internal_from_obj (this_object );
637
- URI_CHECK_INITIALIZATION (internal_uri );
638
+ URI_ASSERT_INITIALIZATION (internal_uri );
638
639
639
640
zend_string * uri_str = internal_uri -> handler -> uri_to_string (internal_uri -> uri , URI_RECOMPOSITION_RAW_ASCII , false);
640
641
if (uri_str == NULL ) {
@@ -651,7 +652,7 @@ PHP_METHOD(Uri_Rfc3986_Uri, toString)
651
652
652
653
zend_object * this_object = Z_OBJ_P (ZEND_THIS );
653
654
uri_internal_t * internal_uri = uri_internal_from_obj (this_object );
654
- URI_CHECK_INITIALIZATION (internal_uri );
655
+ URI_ASSERT_INITIALIZATION (internal_uri );
655
656
656
657
zend_string * uri_str = internal_uri -> handler -> uri_to_string (internal_uri -> uri , URI_RECOMPOSITION_NORMALIZED_ASCII , false);
657
658
if (uri_str == NULL ) {
@@ -672,7 +673,7 @@ PHP_METHOD(Uri_Rfc3986_Uri, resolve)
672
673
673
674
zend_object * this_object = Z_OBJ_P (ZEND_THIS );
674
675
uri_internal_t * internal_uri = uri_internal_from_obj (this_object );
675
- URI_CHECK_INITIALIZATION (internal_uri );
676
+ URI_ASSERT_INITIALIZATION (internal_uri );
676
677
677
678
php_uri_instantiate_uri (INTERNAL_FUNCTION_PARAM_PASSTHRU , internal_uri -> handler , uri_str , this_object , true, false, NULL );
678
679
}
@@ -683,71 +684,63 @@ PHP_METHOD(Uri_Rfc3986_Uri, __serialize)
683
684
684
685
zend_object * this_object = Z_OBJ_P (ZEND_THIS );
685
686
uri_internal_t * internal_uri = uri_internal_from_obj (this_object );
686
- URI_CHECK_INITIALIZATION (internal_uri );
687
-
688
- HashTable * result = zend_array_dup (this_object -> handlers -> get_properties (this_object ));
689
- if (zend_hash_str_find_ind (result , URI_SERIALIZED_PROPERTY_NAME , sizeof (URI_SERIALIZED_PROPERTY_NAME ) - 1 ) != NULL ) {
690
- zend_hash_destroy (result );
691
- zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object: $__uri property is not allowed" , ZSTR_VAL (this_object -> ce -> name ));
692
- RETURN_THROWS ();
693
- }
687
+ URI_ASSERT_INITIALIZATION (internal_uri );
694
688
689
+ /* Serialize state: "uri" key in the first array */
695
690
zend_string * uri_str = internal_uri -> handler -> uri_to_string (internal_uri -> uri , URI_RECOMPOSITION_RAW_ASCII , false);
696
691
if (uri_str == NULL ) {
697
692
zend_throw_exception_ex (NULL , 0 , "Cannot recompose %s to string" , ZSTR_VAL (this_object -> ce -> name ));
698
693
RETURN_THROWS ();
699
694
}
695
+ zval tmp ;
696
+ ZVAL_STR (& tmp , uri_str );
700
697
701
- zval uri_zv ;
702
- ZVAL_STR (& uri_zv , uri_str );
703
- zend_hash_str_add_new (result , URI_SERIALIZED_PROPERTY_NAME , sizeof (URI_SERIALIZED_PROPERTY_NAME ) - 1 , & uri_zv );
704
-
705
- ZVAL_ARR (return_value , result );
706
- }
707
-
708
- static void uri_restore_custom_properties (zend_object * object , uri_internal_t * internal_uri , HashTable * ht )
709
- {
710
- zend_string * prop_name ;
711
- zval * prop_val ;
698
+ array_init (return_value );
712
699
713
- ZEND_HASH_FOREACH_STR_KEY_VAL (ht , prop_name , prop_val ) {
714
- if (!prop_name || Z_TYPE_P (prop_val ) == IS_REFERENCE ||
715
- zend_string_equals_literal (prop_name , URI_SERIALIZED_PROPERTY_NAME )
716
- ) {
717
- continue ;
718
- }
700
+ zval arr ;
701
+ array_init (& arr );
702
+ zend_hash_str_add_new (Z_ARRVAL (arr ), URI_SERIALIZED_PROPERTY_NAME , sizeof (URI_SERIALIZED_PROPERTY_NAME ) - 1 , & tmp );
703
+ zend_hash_next_index_insert (Z_ARRVAL_P (return_value ), & arr );
719
704
720
- zend_update_property_ex (object -> ce , object , prop_name , prop_val );
721
- if (UNEXPECTED (EG (exception ) != NULL )) {
722
- break ;
723
- }
724
- } ZEND_HASH_FOREACH_END ();
705
+ /* Serialize regular properties: second array */
706
+ ZVAL_ARR (& arr , this_object -> handlers -> get_properties (this_object ));
707
+ Z_TRY_ADDREF (arr );
708
+ zend_hash_next_index_insert (Z_ARRVAL_P (return_value ), & arr );
725
709
}
726
710
727
711
static void uri_unserialize (INTERNAL_FUNCTION_PARAMETERS , const char * handler_name )
728
712
{
729
- HashTable * properties ;
713
+ HashTable * data ;
730
714
731
715
ZEND_PARSE_PARAMETERS_START (1 , 1 )
732
- Z_PARAM_ARRAY_HT (properties )
716
+ Z_PARAM_ARRAY_HT (data )
733
717
ZEND_PARSE_PARAMETERS_END ();
734
718
735
719
zend_object * object = Z_OBJ_P (ZEND_THIS );
736
- uri_internal_t * internal_uri = uri_internal_from_obj (object );
737
720
738
- zval * uri_zv = zend_hash_str_find_ind (properties , URI_SERIALIZED_PROPERTY_NAME , sizeof (URI_SERIALIZED_PROPERTY_NAME ) - 1 );
739
- if (uri_zv == NULL ) {
740
- zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object: missing \"__uri\" field" , ZSTR_VAL (object -> ce -> name ));
721
+ /* Verify the expected number of elements, this implicitly ensures that no additional elements are present. */
722
+ if (zend_hash_num_elements (data ) != 2 ) {
723
+ zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (object -> ce -> name ));
724
+ RETURN_THROWS ();
725
+ }
726
+
727
+ /* Unserialize state: "uri" key in the first array */
728
+ zval * arr = zend_hash_index_find (data , 0 );
729
+ if (arr == NULL || Z_TYPE_P (arr ) != IS_ARRAY ) {
730
+ zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (object -> ce -> name ));
741
731
RETURN_THROWS ();
742
732
}
743
- if (Z_TYPE_P (uri_zv ) != IS_STRING ) {
744
- zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object: \"__uri\" field is not a string" , ZSTR_VAL (object -> ce -> name ));
733
+
734
+ zval * uri_zv = zend_hash_str_find_ind (Z_ARRVAL_P (arr ), URI_SERIALIZED_PROPERTY_NAME , sizeof (URI_SERIALIZED_PROPERTY_NAME ) - 1 );
735
+ if (uri_zv == NULL || Z_TYPE_P (uri_zv ) != IS_STRING ) {
736
+ zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (object -> ce -> name ));
745
737
RETURN_THROWS ();
746
738
}
747
739
748
740
zval errors ;
749
741
ZVAL_UNDEF (& errors );
750
742
743
+ uri_internal_t * internal_uri = uri_internal_from_obj (object );
751
744
internal_uri -> handler = uri_handler_by_name (handler_name , strlen (handler_name ));
752
745
if (internal_uri -> uri != NULL ) {
753
746
internal_uri -> handler -> free_uri (internal_uri -> uri );
@@ -756,12 +749,22 @@ static void uri_unserialize(INTERNAL_FUNCTION_PARAMETERS, const char *handler_na
756
749
if (internal_uri -> uri == NULL ) {
757
750
throw_invalid_uri_exception (internal_uri -> handler , & errors );
758
751
zval_ptr_dtor (& errors );
759
- zval_ptr_dtor (uri_zv );
760
752
RETURN_THROWS ();
761
753
}
762
754
zval_ptr_dtor (& errors );
763
755
764
- uri_restore_custom_properties (object , internal_uri , properties );
756
+ /* Unserialize regular properties: second array */
757
+ arr = zend_hash_index_find (data , 1 );
758
+ if (arr == NULL || Z_TYPE_P (arr ) != IS_ARRAY ) {
759
+ zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (object -> ce -> name ));
760
+ RETURN_THROWS ();
761
+ }
762
+
763
+ object_properties_load (object , Z_ARRVAL_P (arr ));
764
+ if (EG (exception )) {
765
+ zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (object -> ce -> name ));
766
+ RETURN_THROWS ();
767
+ }
765
768
}
766
769
767
770
PHP_METHOD (Uri_Rfc3986_Uri , __unserialize )
@@ -822,7 +825,7 @@ PHP_METHOD(Uri_WhatWg_Url, withHost)
822
825
ZVAL_STR_COPY (& zv , value );
823
826
}
824
827
825
- URI_WITHER_COMMON (ZSTR_KNOWN (ZEND_STR_HOST ), & zv , return_value ) \
828
+ URI_WITHER_COMMON (ZSTR_KNOWN (ZEND_STR_HOST ), & zv , return_value );
826
829
}
827
830
828
831
PHP_METHOD (Uri_WhatWg_Url , equals )
@@ -845,7 +848,7 @@ PHP_METHOD(Uri_WhatWg_Url, toUnicodeString)
845
848
846
849
zend_object * this_object = Z_OBJ_P (ZEND_THIS );
847
850
uri_internal_t * internal_uri = uri_internal_from_obj (this_object );
848
- URI_CHECK_INITIALIZATION (internal_uri );
851
+ URI_ASSERT_INITIALIZATION (internal_uri );
849
852
850
853
RETURN_STR (internal_uri -> handler -> uri_to_string (internal_uri -> uri , URI_RECOMPOSITION_RAW_UNICODE , false));
851
854
}
@@ -856,7 +859,7 @@ PHP_METHOD(Uri_WhatWg_Url, toAsciiString)
856
859
857
860
zend_object * this_object = Z_OBJ_P (ZEND_THIS );
858
861
uri_internal_t * internal_uri = uri_internal_from_obj (this_object );
859
- URI_CHECK_INITIALIZATION (internal_uri );
862
+ URI_ASSERT_INITIALIZATION (internal_uri );
860
863
861
864
RETURN_STR (internal_uri -> handler -> uri_to_string (internal_uri -> uri , URI_RECOMPOSITION_RAW_ASCII , false));
862
865
}
@@ -874,7 +877,7 @@ PHP_METHOD(Uri_WhatWg_Url, resolve)
874
877
875
878
zend_object * this_object = Z_OBJ_P (ZEND_THIS );
876
879
uri_internal_t * internal_uri = uri_internal_from_obj (this_object );
877
- URI_CHECK_INITIALIZATION (internal_uri );
880
+ URI_ASSERT_INITIALIZATION (internal_uri );
878
881
879
882
php_uri_instantiate_uri (INTERNAL_FUNCTION_PARAM_PASSTHRU , internal_uri -> handler , uri_str , this_object , true, false, errors );
880
883
}
@@ -920,7 +923,7 @@ static zend_object *uri_clone_obj_handler(zend_object *object)
920
923
ZEND_ASSERT (new_object != NULL );
921
924
uri_object_t * new_uri_object = uri_object_from_obj (new_object );
922
925
923
- URI_CHECK_INITIALIZATION (internal_uri );
926
+ URI_ASSERT_INITIALIZATION (internal_uri );
924
927
925
928
new_uri_object -> internal .handler = internal_uri -> handler ;
926
929
0 commit comments