@@ -58,7 +58,7 @@ class URLHost {
5858 public:
5959 ~URLHost ();
6060
61- void ParseIPv4Host (const char * input, size_t length, bool * is_ipv4 );
61+ void ParseIPv4Host (const char * input, size_t length);
6262 void ParseIPv6Host (const char * input, size_t length);
6363 void ParseOpaqueHost (const char * input, size_t length);
6464 void ParseHost (const char * input,
@@ -402,9 +402,36 @@ int64_t ParseNumber(const char* start, const char* end) {
402402 return strtoll (start, nullptr , R);
403403}
404404
405- void URLHost::ParseIPv4Host (const char * input, size_t length, bool * is_ipv4) {
405+ // https://url.spec.whatwg.org/#ends-in-a-number-checker
406+ bool EndsInANumber (const std::string& str) {
407+ std::vector<std::string> parts = SplitString (str, ' .' , false );
408+ if (parts.size () == 0 )
409+ return false ;
410+
411+ if (parts.back () == " " ) {
412+ if (parts.size () == 1 )
413+ return false ;
414+ parts.pop_back ();
415+ }
416+
417+ const std::string& last = parts.back ();
418+
419+ if (last == " " )
420+ return false ;
421+
422+ int64_t num = ParseNumber (last.c_str (), last.c_str () + last.size ());
423+ if (num >= 0 )
424+ return true ;
425+
426+ if (last.find_first_not_of (" 0123456789" ) == std::string::npos) {
427+ return true ;
428+ }
429+
430+ return false ;
431+ }
432+
433+ void URLHost::ParseIPv4Host (const char * input, size_t length) {
406434 CHECK_EQ (type_, HostType::H_FAILED);
407- *is_ipv4 = false ;
408435 const char * pointer = input;
409436 const char * mark = input;
410437 const char * end = pointer + length;
@@ -437,7 +464,6 @@ void URLHost::ParseIPv4Host(const char* input, size_t length, bool* is_ipv4) {
437464 pointer++;
438465 }
439466 CHECK_GT (parts, 0 );
440- *is_ipv4 = true ;
441467
442468 // If any but the last item in numbers is greater than 255, return failure.
443469 // If the last item in numbers is greater than or equal to
@@ -509,11 +535,10 @@ void URLHost::ParseHost(const char* input,
509535 }
510536 }
511537
512- // Check to see if it's an IPv4 IP address
513- bool is_ipv4;
514- ParseIPv4Host (decoded.c_str (), decoded.length (), &is_ipv4);
515- if (is_ipv4)
516- return ;
538+ // If domain ends in a number, then return the result of IPv4 parsing domain
539+ if (EndsInANumber (decoded)) {
540+ return ParseIPv4Host (decoded.c_str (), decoded.length ());
541+ }
517542
518543 // If the unicode flag is set, run the result through punycode ToUnicode
519544 if (unicode && !ToUnicode (decoded, &decoded))
0 commit comments