Skip to content

Commit 83b70c6

Browse files
committed
Reject non-IPv4 hostnames that end in numbers.
1 parent 5b6f280 commit 83b70c6

File tree

1 file changed

+31
-9
lines changed

1 file changed

+31
-9
lines changed

src/node_url.cc

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "node_errors.h"
44
#include "node_external_reference.h"
55
#include "node_i18n.h"
6+
#include "util.h"
67
#include "util-inl.h"
78

89
#include <cmath>
@@ -58,7 +59,7 @@ class URLHost {
5859
public:
5960
~URLHost();
6061

61-
void ParseIPv4Host(const char* input, size_t length, bool* is_ipv4);
62+
void ParseIPv4Host(const char* input, size_t length);
6263
void ParseIPv6Host(const char* input, size_t length);
6364
void ParseOpaqueHost(const char* input, size_t length);
6465
void ParseHost(const char* input,
@@ -401,9 +402,33 @@ int64_t ParseNumber(const char* start, const char* end) {
401402
return strtoll(start, nullptr, R);
402403
}
403404

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) {
405431
CHECK_EQ(type_, HostType::H_FAILED);
406-
*is_ipv4 = false;
407432
const char* pointer = input;
408433
const char* mark = input;
409434
const char* end = pointer + length;
@@ -436,7 +461,6 @@ void URLHost::ParseIPv4Host(const char* input, size_t length, bool* is_ipv4) {
436461
pointer++;
437462
}
438463
CHECK_GT(parts, 0);
439-
*is_ipv4 = true;
440464

441465
// If any but the last item in numbers is greater than 255, return failure.
442466
// If the last item in numbers is greater than or equal to
@@ -508,11 +532,9 @@ void URLHost::ParseHost(const char* input,
508532
}
509533
}
510534

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+
}
516538

517539
// If the unicode flag is set, run the result through punycode ToUnicode
518540
if (unicode && !ToUnicode(decoded, &decoded))

0 commit comments

Comments
 (0)