|
3 | 3 | #include "node_errors.h" |
4 | 4 | #include "node_external_reference.h" |
5 | 5 | #include "node_i18n.h" |
| 6 | +#include "util.h" |
6 | 7 | #include "util-inl.h" |
7 | 8 |
|
8 | 9 | #include <cmath> |
@@ -58,7 +59,7 @@ class URLHost { |
58 | 59 | public: |
59 | 60 | ~URLHost(); |
60 | 61 |
|
61 | | - void ParseIPv4Host(const char* input, size_t length, bool* is_ipv4); |
| 62 | + void ParseIPv4Host(const char* input, size_t length); |
62 | 63 | void ParseIPv6Host(const char* input, size_t length); |
63 | 64 | void ParseOpaqueHost(const char* input, size_t length); |
64 | 65 | void ParseHost(const char* input, |
@@ -401,9 +402,33 @@ int64_t ParseNumber(const char* start, const char* end) { |
401 | 402 | return strtoll(start, nullptr, R); |
402 | 403 | } |
403 | 404 |
|
404 | | -void URLHost::ParseIPv4Host(const char* input, size_t length, bool* is_ipv4) { |
| 405 | +bool EndsInANumber(std::string& str) { |
| 406 | + std::vector<std::string> parts = SplitString(str, '.'); |
| 407 | + if (parts.size() == 0) |
| 408 | + return false; |
| 409 | + |
| 410 | + if (parts.back() == "") { |
| 411 | + if (parts.size() == 1) |
| 412 | + return false; |
| 413 | + parts.pop_back(); |
| 414 | + } |
| 415 | + |
| 416 | + const std::string& last_part = parts.back(); |
| 417 | + |
| 418 | + int64_t num = ParseNumber(last_part.c_str(), last_part.c_str() + last_part.size()); |
| 419 | + if (num >= 0) |
| 420 | + return true; |
| 421 | + |
| 422 | + if (last_part.find_first_not_of("0123456789") == std::string::npos) { |
| 423 | + return true; |
| 424 | + } |
| 425 | + |
| 426 | + return false; |
| 427 | +} |
| 428 | + |
| 429 | + |
| 430 | +void URLHost::ParseIPv4Host(const char* input, size_t length) { |
405 | 431 | CHECK_EQ(type_, HostType::H_FAILED); |
406 | | - *is_ipv4 = false; |
407 | 432 | const char* pointer = input; |
408 | 433 | const char* mark = input; |
409 | 434 | const char* end = pointer + length; |
@@ -436,7 +461,6 @@ void URLHost::ParseIPv4Host(const char* input, size_t length, bool* is_ipv4) { |
436 | 461 | pointer++; |
437 | 462 | } |
438 | 463 | CHECK_GT(parts, 0); |
439 | | - *is_ipv4 = true; |
440 | 464 |
|
441 | 465 | // If any but the last item in numbers is greater than 255, return failure. |
442 | 466 | // If the last item in numbers is greater than or equal to |
@@ -508,11 +532,9 @@ void URLHost::ParseHost(const char* input, |
508 | 532 | } |
509 | 533 | } |
510 | 534 |
|
511 | | - // Check to see if it's an IPv4 IP address |
512 | | - bool is_ipv4; |
513 | | - ParseIPv4Host(decoded.c_str(), decoded.length(), &is_ipv4); |
514 | | - if (is_ipv4) |
515 | | - return; |
| 535 | + if (EndsInANumber(decoded)) { |
| 536 | + return ParseIPv4Host(decoded.c_str(), decoded.length()); |
| 537 | + } |
516 | 538 |
|
517 | 539 | // If the unicode flag is set, run the result through punycode ToUnicode |
518 | 540 | if (unicode && !ToUnicode(decoded, &decoded)) |
|
0 commit comments