@@ -549,43 +549,75 @@ bool url_aggregator::set_host_or_hostname(const std::string_view input) {
549549 // Note: the 'found_colon' value is true if and only if a colon was
550550 // encountered while not inside brackets.
551551 if (found_colon) {
552+ // If buffer is the empty string, host-missing validation error, return
553+ // failure.
554+ std::string_view host_buffer = host_view.substr (0 , location);
555+ if (host_buffer.empty ()) {
556+ return false ;
557+ }
558+
559+ // If state override is given and state override is hostname state, then
560+ // return failure.
552561 if constexpr (override_hostname) {
553562 return false ;
554563 }
555- std::string_view sub_buffer = new_host.substr (location + 1 );
556- if (!sub_buffer.empty ()) {
557- set_port (sub_buffer);
564+
565+ // Let host be the result of host parsing buffer with url is not special.
566+ bool succeeded = parse_host (host_buffer);
567+ if (!succeeded) {
568+ update_base_hostname (previous_host);
569+ update_base_port (previous_port);
570+ return false ;
558571 }
572+
573+ // Set url's host to host, buffer to the empty string, and state to port
574+ // state.
575+ std::string_view port_buffer = new_host.substr (location + 1 );
576+ if (!port_buffer.empty ()) {
577+ set_port (port_buffer);
578+ }
579+ return true ;
559580 }
560- // If url is special and host_view is the empty string, validation error,
561- // return failure. Otherwise, if state override is given, host_view is the
562- // empty string, and either url includes credentials or url's port is
563- // non-null, return.
564- else if (host_view.empty () &&
565- (is_special () || has_credentials () || has_port ())) {
566- return false ;
567- }
581+ // Otherwise, if one of the following is true:
582+ // - c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#)
583+ // - url is special and c is U+005C (\)
584+ else {
585+ // If url is special and host_view is the empty string, host-missing
586+ // validation error, return failure.
587+ if (host_view.empty () && is_special ()) {
588+ return false ;
589+ }
568590
569- // Let host be the result of host parsing host_view with url is not special.
570- if (host_view.empty () && !is_special ()) {
571- if (has_hostname ()) {
572- clear_hostname (); // easy!
591+ // Otherwise, if state override is given, host_view is the empty string,
592+ // and either url includes credentials or url's port is non-null, then
593+ // return failure.
594+ if (host_view.empty () && (has_credentials () || has_port ())) {
595+ return false ;
596+ }
597+
598+ // Let host be the result of host parsing host_view with url is not
599+ // special.
600+ if (host_view.empty () && !is_special ()) {
601+ if (has_hostname ()) {
602+ clear_hostname (); // easy!
603+ } else if (has_dash_dot ()) {
604+ add_authority_slashes_if_needed ();
605+ delete_dash_dot ();
606+ }
607+ return true ;
608+ }
609+
610+ bool succeeded = parse_host (host_view);
611+ if (!succeeded) {
612+ update_base_hostname (previous_host);
613+ update_base_port (previous_port);
614+ return false ;
573615 } else if (has_dash_dot ()) {
574- add_authority_slashes_if_needed ();
616+ // Should remove dash_dot from pathname
575617 delete_dash_dot ();
576618 }
577619 return true ;
578620 }
579-
580- bool succeeded = parse_host (host_view);
581- if (!succeeded) {
582- update_base_hostname (previous_host);
583- update_base_port (previous_port);
584- } else if (has_dash_dot ()) {
585- // Should remove dash_dot from pathname
586- delete_dash_dot ();
587- }
588- return succeeded;
589621 }
590622
591623 size_t location = new_host.find_first_of (" /\\ ?" );
0 commit comments