Skip to content
Browse files

net: More accurate IP address validation and IPv6 dotted notation.

Added isIP method to make use of inet_pton to cares_wrap.cc
Modified net.isIP() to make use of new c++ isIP method.
Added new tests to test-net-isip.js.
  • Loading branch information...
1 parent 109f8e2 commit 122717409fbe6321811bd496d7a5fbee7607cc57 @snoj committed Oct 8, 2012
Showing with 27 additions and 21 deletions.
  1. +2 −19 lib/net.js
  2. +15 −1 src/cares_wrap.cc
  3. +10 −1 test/simple/test-net-isip.js
View
21 lib/net.js
@@ -24,6 +24,7 @@ var Stream = require('stream');
var timers = require('timers');
var util = require('util');
var assert = require('assert');
+var cares = process.binding('cares_wrap');
var cluster;
function noop() {}
@@ -1114,26 +1115,8 @@ Server.prototype.unref = function() {
// TODO: isIP should be moved to the DNS code. Putting it here now because
// this is what the legacy system did.
-// NOTE: This does not accept IPv6 with an IPv4 dotted address at the end,
-// and it does not detect more than one double : in a string.
exports.isIP = function(input) {
- if (!input) {
- return 0;
- } else if (/^(\d?\d?\d)\.(\d?\d?\d)\.(\d?\d?\d)\.(\d?\d?\d)$/.test(input)) {
- var parts = input.split('.');
- for (var i = 0; i < parts.length; i++) {
- var part = parseInt(parts[i]);
- if (part < 0 || 255 < part) {
- return 0;
- }
- }
- return 4;
- } else if (/^::|^::1|^([a-fA-F0-9]{1,4}::?){1,7}([a-fA-F0-9]{0,4})$/.test(
- input)) {
- return 6;
- } else {
- return 0;
- }
+ return cares.isIP(input);
};
View
16 src/cares_wrap.cc
@@ -812,6 +812,19 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
delete req_wrap;
}
+static Handle<Value> isIP(const Arguments& args) {
+ HandleScope scope;
+ char address_buffer[sizeof(struct in6_addr)];
+
+ String::AsciiValue ascii(args[0]);
+ const char * ip = *ascii;
+ if (uv_inet_pton(AF_INET, ip, &address_buffer).code == UV_OK) {
+ return scope.Close(v8::Integer::New(4));
+ } else if (uv_inet_pton(AF_INET6, ip, &address_buffer).code == UV_OK) {
+ return scope.Close(v8::Integer::New(6));
+ }
+ return scope.Close(v8::Integer::New(0));
+}
static Handle<Value> GetAddrInfo(const Arguments& args) {
HandleScope scope;
@@ -886,7 +899,8 @@ static void Initialize(Handle<Object> target) {
NODE_SET_METHOD(target, "getHostByName", QueryWithFamily<GetHostByNameWrap>);
NODE_SET_METHOD(target, "getaddrinfo", GetAddrInfo);
-
+ NODE_SET_METHOD(target, "isIP", isIP);
+
target->Set(String::NewSymbol("AF_INET"), Integer::New(AF_INET));
target->Set(String::NewSymbol("AF_INET6"), Integer::New(AF_INET6));
target->Set(String::NewSymbol("AF_UNSPEC"), Integer::New(AF_UNSPEC));
View
11 test/simple/test-net-isip.js
@@ -36,6 +36,15 @@ assert.equal(net.isIP('2001:dead::'), 6);
assert.equal(net.isIP('2001:dead:beef::'), 6);
assert.equal(net.isIP('2001:dead:beef:1::'), 6);
assert.equal(net.isIP('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), 6);
+assert.equal(net.isIP(':2001:252:0:1::2008:6:'), 0);
+assert.equal(net.isIP(':2001:252:0:1::2008:6'), 0);
+assert.equal(net.isIP('2001:252:0:1::2008:6:'), 0);
+assert.equal(net.isIP('2001:252::1::2008:6'), 0);
+assert.equal(net.isIP('::2001:252:1:2008:6'), 6);
+assert.equal(net.isIP('::2001:252:1:1.1.1.1'), 6);
+assert.equal(net.isIP('::2001:252:1:255.255.255.255'), 6);
+assert.equal(net.isIP('::2001:252:1:255.255.255.255.76'), 0);
+assert.equal(net.isIP('::anything'), 0);
assert.equal(net.isIP('::1'), 6);
assert.equal(net.isIP('::'), 6);
assert.equal(net.isIP('0000:0000:0000:0000:0000:0000:12345:0000'), 0);
@@ -49,4 +58,4 @@ assert.equal(net.isIPv4('2001:252:0:1::2008:6'), false);
assert.equal(net.isIPv6('127.0.0.1'), false);
assert.equal(net.isIPv6('example.com'), false);
-assert.equal(net.isIPv6('2001:252:0:1::2008:6'), true);
+assert.equal(net.isIPv6('2001:252:0:1::2008:6'), true);

0 comments on commit 1227174

Please sign in to comment.
Something went wrong with that request. Please try again.