2424#include <arpa/inet.h>
2525#endif
2626
27- ZEND_TLS lxb_url_parser_t lexbor_parser ;
27+ ZEND_TLS lexbor_mraw_t lexbor_mraw = {0 };
28+ ZEND_TLS lxb_url_parser_t lexbor_parser = {0 };
29+ ZEND_TLS lxb_unicode_idna_t lexbor_idna = {0 };
2830ZEND_TLS unsigned short int parsed_urls ;
2931
3032static const unsigned short int maximum_parses_before_cleanup = 500 ;
@@ -333,17 +335,6 @@ static zend_result php_uri_parser_whatwg_password_write(struct uri_internal_t *i
333335 return SUCCESS ;
334336}
335337
336- static zend_result init_idna (void )
337- {
338- if (lexbor_parser .idna != NULL ) {
339- return SUCCESS ;
340- }
341-
342- lexbor_parser .idna = lxb_unicode_idna_create ();
343-
344- return lxb_unicode_idna_init (lexbor_parser .idna ) == LXB_STATUS_OK ? SUCCESS : FAILURE ;
345- }
346-
347338static zend_result php_uri_parser_whatwg_host_read (const struct uri_internal_t * internal_uri , uri_component_read_mode_t read_mode , zval * retval )
348339{
349340 const lxb_url_t * lexbor_uri = internal_uri -> uri ;
@@ -368,11 +359,8 @@ static zend_result php_uri_parser_whatwg_host_read(const struct uri_internal_t *
368359 switch (read_mode ) {
369360 case URI_COMPONENT_READ_NORMALIZED_UNICODE : {
370361 smart_str host_str = {0 };
371- if (init_idna () == FAILURE ) {
372- return FAILURE ;
373- }
374- lxb_url_serialize_host_unicode (lexbor_parser .idna , & lexbor_uri -> host , serialize_to_smart_str_callback , & host_str );
375- lxb_unicode_idna_clean (lexbor_parser .idna );
362+ lxb_url_serialize_host_unicode (& lexbor_idna , & lexbor_uri -> host , serialize_to_smart_str_callback , & host_str );
363+ lxb_unicode_idna_clean (& lexbor_idna );
376364
377365 ZVAL_NEW_STR (retval , smart_str_extract (& host_str ));
378366 break ;
@@ -525,29 +513,49 @@ static zend_result php_uri_parser_whatwg_fragment_write(struct uri_internal_t *i
525513
526514PHP_RINIT_FUNCTION (uri_parser_whatwg )
527515{
528- lexbor_mraw_t * mraw = lexbor_mraw_create ();
529- lxb_status_t status = lexbor_mraw_init (mraw , lexbor_mraw_byte_size );
516+ lxb_status_t status ;
517+
518+ status = lexbor_mraw_init (& lexbor_mraw , lexbor_mraw_byte_size );
530519 if (status != LXB_STATUS_OK ) {
531- lexbor_mraw_destroy (mraw , true);
532- return FAILURE ;
520+ goto fail ;
533521 }
534522
535- status = lxb_url_parser_init (& lexbor_parser , mraw );
523+ status = lxb_url_parser_init (& lexbor_parser , & lexbor_mraw );
536524 if (status != LXB_STATUS_OK ) {
537- lxb_url_parser_destroy (& lexbor_parser , false);
538- lexbor_mraw_destroy (mraw , true);
539- return FAILURE ;
525+ goto fail ;
526+ }
527+
528+ status = lxb_unicode_idna_init (& lexbor_idna );
529+ if (status != LXB_STATUS_OK ) {
530+ goto fail ;
540531 }
541532
542533 parsed_urls = 0 ;
543534
544535 return SUCCESS ;
536+
537+ fail :
538+
539+ /* Unconditionally calling the _destroy() functions is
540+ * safe on a zeroed structure. */
541+ lxb_unicode_idna_destroy (& lexbor_idna , false);
542+ memset (& lexbor_idna , 0 , sizeof (lexbor_idna ));
543+ lxb_url_parser_destroy (& lexbor_parser , false);
544+ memset (& lexbor_parser , 0 , sizeof (lexbor_parser ));
545+ lexbor_mraw_destroy (& lexbor_mraw , false);
546+ memset (& lexbor_mraw , 0 , sizeof (lexbor_mraw ));
547+
548+ return FAILURE ;
545549}
546550
547551PHP_RSHUTDOWN_FUNCTION (uri_parser_whatwg )
548552{
549- lxb_url_parser_memory_destroy (& lexbor_parser );
553+ lxb_unicode_idna_destroy (& lexbor_idna , false);
554+ memset (& lexbor_idna , 0 , sizeof (lexbor_idna ));
550555 lxb_url_parser_destroy (& lexbor_parser , false);
556+ memset (& lexbor_parser , 0 , sizeof (lexbor_parser ));
557+ lexbor_mraw_destroy (& lexbor_mraw , false);
558+ memset (& lexbor_mraw , 0 , sizeof (lexbor_mraw ));
551559
552560 parsed_urls = 0 ;
553561
@@ -600,11 +608,8 @@ static zend_string *php_uri_parser_whatwg_to_string(void *uri, uri_recomposition
600608 case URI_RECOMPOSITION_RAW_UNICODE :
601609 ZEND_FALLTHROUGH ;
602610 case URI_RECOMPOSITION_NORMALIZED_UNICODE :
603- if (init_idna () == FAILURE ) {
604- return NULL ;
605- }
606- lxb_url_serialize_idna (lexbor_parser .idna , lexbor_uri , serialize_to_smart_str_callback , & uri_str , exclude_fragment );
607- lxb_unicode_idna_clean (lexbor_parser .idna );
611+ lxb_url_serialize_idna (& lexbor_idna , lexbor_uri , serialize_to_smart_str_callback , & uri_str , exclude_fragment );
612+ lxb_unicode_idna_clean (& lexbor_idna );
608613 break ;
609614 case URI_RECOMPOSITION_RAW_ASCII :
610615 ZEND_FALLTHROUGH ;
0 commit comments