Skip to content

Commit

Permalink
test: add string type and toHost tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
nodech committed Jan 10, 2022
1 parent 3fdd678 commit feb53a8
Show file tree
Hide file tree
Showing 2 changed files with 313 additions and 5 deletions.
128 changes: 126 additions & 2 deletions test/data/read-write-vectors.js → test/data/other-vectors.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,92 @@
'use strict';

const binet = require('../..');

const vectors = exports;

/*
* Some extra vectors for the options and etc.
* Map/Unmap
*/

const vectors = exports;
vectors.MAP_VECTORS = [
[binet.ZERO_IPV6, binet.ZERO_IPV6],
[Buffer.alloc(16, 1), Buffer.alloc(16, 1)],
[binet.ZERO_IPV4, binet.ZERO_IPV4],
[Buffer.alloc(4, 0), binet.ZERO_IPV4],
[
Buffer.from('00000000000000000000fffffefefefe', 'hex'),
Buffer.from('00000000000000000000fffffefefefe', 'hex')
], [
Buffer.from('fefefefe', 'hex'),
Buffer.from('00000000000000000000fffffefefefe', 'hex')
], [
Buffer.from('ffffffff', 'hex'),
Buffer.from('00000000000000000000ffffffffffff', 'hex')
], [
// NOTE: Maybe it should fail if RAW is not mapped and is unmappable?
Buffer.from('ffffffffffffffffffffffffffffffff', 'hex'),
Buffer.from('ffffffffffffffffffffffffffffffff', 'hex')
]
];

// these are mapped ips
vectors.UNMAP_VECTOR = [
[Buffer.alloc(4, 0), Buffer.alloc(4, 0)],
[Buffer.alloc(4, 0xff), Buffer.alloc(4, 0xff)],
[binet.ZERO_IPV4, Buffer.alloc(4, 0)],
[
Buffer.from('00000000000000000000ffffffffffff', 'hex'),
Buffer.from('ffffffff', 'hex')
]
];

// isMappedString tests
vectors.IS_MAPPED_STRING = [
['127.0.0.1', false],
['0.0.0.0', false],
['255.255.255.255', false],
['hello', false],
['::', false],
['::1', false],
['::ffff:ffff', false],
['::f:ffff:ffff', false],
['::ff:ffff:ffff', false],
['::fff:ffff:ffff', false],
['::1:ffff:ffff:ffff', false],
['1::ffff:ffff:ffff', false],
['::ffff:ffff:ffff', true],
['::ffff:0000:0000', true]
];

// These are not mapped.
vectors.UNMAPPED_VECTOR = [
binet.ZERO_IPV6,
Buffer.from('000000000000000000000000ffffffff', 'hex'),
Buffer.from('00000000000000000000000fffffffff', 'hex'),
Buffer.from('0000000000000000000000ffffffffff', 'hex'),
Buffer.from('000000000000000000000fffffffffff', 'hex'),
Buffer.from('00000000000000000001ffffffffffff', 'hex'),
Buffer.from('10000000000000000000ffffffffffff', 'hex'),
Buffer.from('f0000000000000000000ffff00000000', 'hex'),
Buffer.from('ffffffffffffffffffffffff00000000', 'hex'),
Buffer.from('ffffffffffffffffffffffffffffffff', 'hex')
];

/*
* Small onion address set
*/
vectors.LEGACY_ONIONS = [
'0000000000000000.onion',
'aaaaaaaaaaaaaaaa.onion',
'ffffffffffffffff.onion',
'zzzzzzzzzzzzzzzz.onion',
'abcdefghijklmnop.onion',
'qrstuvwxyz234567.onion'
];

/*
* READ/WRITE Vectors
*/

// NOTE: str needs to be normalized.
vectors.READ = [
Expand Down Expand Up @@ -221,3 +303,45 @@ vectors.WRITE = [
...vectors.WRITE_6,
...vectors.WRITE_ONION
];

/*
* toHost/fromHost tests
*/

// host, port, key, returned val
vectors.TOHOST = [
['handshake', 0, null, 'handshake:0'],
['handshake', 0xffff, null, 'handshake:65535'],
['::1', 1000, null, '[::1]:1000'],
['127.0.0.1', 1000, null, '127.0.0.1:1000'],
['0.0.0.0', 1000, null, '0.0.0.0:1000'],

// do we need more strict rules in toHost?
['---', 1000, null, '---:1000'],
['handshake', 1000, Buffer.alloc(33, 0), 'handshake:1000'],
['handshake', 1000, Buffer.alloc(33, 0x11),
'ceirceirceirceirceirceirceirceirceirceirceirceirceirc@handshake:1000']
];

// host, port, key, thrown err message - null = assertion error.
vectors.TOHOST_ERR = [
// bad hostnames
['', 1000, null, 'Invalid host (zero length).'],
['a'.repeat(255 + 1 + 5 + 1), 1000, null, 'Invalid host (too large).'],
['[::]', 1000, null, 'Bad host.'],
['hsd@handshake-org', 1000, null, 'Bad host.'],
['handshake\n', 1000, null, 'Bad host.'],
['handshake\u0019', 1000, null, 'Bad host.'],
['handshake\u007f', 1000, null, 'Bad host.'],
['not-an-ipv6:addr', 1000, null, 'Unexpected colon.'],
['not-an-ipv6:1000', 1000, null, 'Unexpected colon.'],

// bad ports
['handshake', null, null, null],
['handshake', -1, null, null],
['handshake', 0xffff + 1, null, null],

// bad keys
['handshake', 100, 'not-a-key', null],
['handshake', 100, Buffer.alloc(0), null]
];
190 changes: 187 additions & 3 deletions test/ip-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const bufio = require('bufio');
const binet = require('../lib/binet');

const ipVectors = require('./data/ip-vectors');
const readWriteVectors = require('./data/read-write-vectors');
const otherVectors = require('./data/other-vectors');

const allVectors = ipVectors.ALL.reduce((p, c) => add(p, c));

Expand Down Expand Up @@ -56,7 +56,7 @@ describe('binet', function() {
});

it('should read IP from a buffer', () => {
for (const {off, size, buf, str, err} of readWriteVectors.READ) {
for (const {off, size, buf, str, err} of otherVectors.READ) {
let rerr = null;
let rres = null;

Expand All @@ -79,7 +79,7 @@ describe('binet', function() {
});

it('should write IP string to a buffer', () => {
for (const {off, size, foff, buf, str, err} of readWriteVectors.WRITE) {
for (const {off, size, foff, buf, str, err} of otherVectors.WRITE) {
let rerr = null;
let roff = null;
const dest = Buffer.alloc(buf.length);
Expand Down Expand Up @@ -369,6 +369,190 @@ describe('binet', function() {
});
}
});

describe('Mappings', function() {
it('should map 4 byte ip to IPv6', () => {
for (const vector of otherVectors.MAP_VECTORS) {
const mapped = binet.map(vector[0]);

assert.bufferEqual(mapped, vector[1]);
}
});

it('should fail mapping non-4 ip to IPv6', () => {
for (let i = 0; i < 20; i++) {
if (i === 4 || i === 16)
continue;

assert.throws(() => {
binet.map(Buffer.alloc(i));
}, {
message: 'Not an IPv4 address.'
});
}
});

it('should unmap IPv6 mapped to IPv4', () => {
for (const vector of otherVectors.UNMAP_VECTOR) {
const unmapped = binet.unmap(vector[0]);

assert.bufferEqual(unmapped, vector[1]);
}
});

it('should fail unmapping non-mapped IPs', () => {
// incorrect sizes
for (let i = 0; i < 20; i++) {
if (i === 4 || i === 16)
continue;

assert.throws(() => {
binet.unmap(Buffer.alloc(i));
}, {
message: 'Not an IPv6 address.'
});
}
});

it('should fail unmapping non-mapped IPv6s', () => {
for (const vector of otherVectors.UNMAPPED_VECTOR) {
assert.throws(() => {
binet.unmap(vector);
}, {
message: 'Not an IPv4 mapped address.'
});
}
});

it('should check mapped string', () => {
for (const vector of otherVectors.IS_MAPPED_STRING) {
assert.strictEqual(binet.isMappedString(vector[0]), vector[1]);
}
});
});

describe('String type', function() {
const {types} = binet;

const none = [
'',
'1'.repeat(255 + 1),
'1'.repeat(100)
];

const all = add(
ipVectors.IPV4,
ipVectors.IPV6,
ipVectors.ONION,
otherVectors.LEGACY_ONIONS,
none
);

it('should return none', () => {
assert.strictEqual(binet.getTypeString(''), types.NONE);
assert.strictEqual(binet.getTypeString('1'.repeat(255 + 1)), types.NONE);
assert.strictEqual(binet.getTypeString('1'.repeat(100)), types.NONE);
});

it('should return IPv4', () => {
for (const vector of ipVectors.IPV4)
assert.strictEqual(binet.getTypeString(vector), types.INET4);
});

it('should return IPv6', () => {
for (const vector of ipVectors.IPV6)
assert.strictEqual(binet.getTypeString(vector), types.INET6);
});

it('should return ONION', () => {
for (const vector of otherVectors.LEGACY_ONIONS)
assert.strictEqual(binet.getTypeString(vector), types.ONION);
});

it('should check isIPv4String', () => {
const not = sub(all, ipVectors.IPV4);

for (const vector of ipVectors.IPV4)
assert.strictEqual(binet.isIPv4String(vector), true);

for (const vector of not)
assert.strictEqual(binet.isIPv4String(vector), false);
});

it('should check isIPv6String', () => {
const not = sub(all, ipVectors.IPV6);

for (const vector of ipVectors.IPV6)
assert.strictEqual(binet.isIPv6String(vector), true);

for (const vector of not)
assert.strictEqual(binet.isIPv6String(vector), false);
});

it('should check isOnionString', () => {
const onions = add(otherVectors.LEGACY_ONIONS, ipVectors.ONION);
const not = sub(all, onions);

for (const vector of onions)
assert.strictEqual(binet.isOnionString(vector), true);

for (const vector of not)
assert.strictEqual(binet.isOnionString(vector), false);
});

it('should check isUnknownString', () => {
const not = sub(all, none);

for (const vector of none)
assert.strictEqual(binet.isUnknownString(vector), true);

for (const vector of not)
assert.strictEqual(binet.isUnknownString(vector), false);
});

it('should check isIPString', () => {
const notIPString = add(ipVectors.NONE, otherVectors.LEGACY_ONIONS);

// check inet4
for (const vector of ipVectors.IPV4)
assert.strictEqual(binet.isIPString(vector), types.INET4);

for (const vector of ipVectors.IPV6)
assert.strictEqual(binet.isIPString(vector), types.INET6);

for (const vector of notIPString)
assert.strictEqual(binet.isIPString(vector), types.NONE);
});
});

describe('Host string', function() {
it('should convert toHost string', () => {
for (const vector of otherVectors.TOHOST) {
const host = binet.toHost(vector[0], vector[1], vector[2]);

assert.strictEqual(host, vector[3]);
}
});

it('should fail toHost', () => {
for (const vector of otherVectors.TOHOST_ERR) {
let err;
try {
binet.toHost(vector[0], vector[1], vector[2]);
} catch (e) {
err = e;
}

assert(err, `Error not found: ${err}`);

if (!vector[3])
assert.strictEqual(err instanceof assert.AssertionError, true, err);

if (vector[3])
assert.strictEqual(err.message, vector[3]);
}
});
});
});

function sub(va, ...args) {
Expand Down

0 comments on commit feb53a8

Please sign in to comment.