@@ -58,7 +58,7 @@ class URLHost {
58
58
public:
59
59
~URLHost ();
60
60
61
- void ParseIPv4Host (const char * input, size_t length, bool * is_ipv4 );
61
+ void ParseIPv4Host (const char * input, size_t length);
62
62
void ParseIPv6Host (const char * input, size_t length);
63
63
void ParseOpaqueHost (const char * input, size_t length);
64
64
void ParseHost (const char * input,
@@ -402,9 +402,36 @@ int64_t ParseNumber(const char* start, const char* end) {
402
402
return strtoll (start, nullptr , R);
403
403
}
404
404
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) {
406
434
CHECK_EQ (type_, HostType::H_FAILED);
407
- *is_ipv4 = false ;
408
435
const char * pointer = input;
409
436
const char * mark = input;
410
437
const char * end = pointer + length;
@@ -437,7 +464,6 @@ void URLHost::ParseIPv4Host(const char* input, size_t length, bool* is_ipv4) {
437
464
pointer++;
438
465
}
439
466
CHECK_GT (parts, 0 );
440
- *is_ipv4 = true ;
441
467
442
468
// If any but the last item in numbers is greater than 255, return failure.
443
469
// If the last item in numbers is greater than or equal to
@@ -509,11 +535,10 @@ void URLHost::ParseHost(const char* input,
509
535
}
510
536
}
511
537
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
+ }
517
542
518
543
// If the unicode flag is set, run the result through punycode ToUnicode
519
544
if (unicode && !ToUnicode (decoded, &decoded))
0 commit comments