Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions lib/internal/blocklist.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ class BlockList {
// - 2001:db8:85a3::8a2e:370:7334/64 (compressed)
// - 2001:db8:85a3::192.0.2.128/64 (mixed)
const ipv6SubnetMatch = item.match(
/Subnet: IPv6 ([0-9a-fA-F:]{1,39})\/([0-9]{1,3})/i,
/Subnet: IPv6 ([0-9a-fA-F:.]{1,45})\/([0-9]{1,3})/i,
);
if (ipv6SubnetMatch) {
const { 1: network, 2: prefix } = ipv6SubnetMatch;
Expand All @@ -212,7 +212,7 @@ class BlockList {
// - 2001:0db8:85a3:0000:0000:8a2e:0370:7334 (full)
// - 2001:db8:85a3::8a2e:370:7334 (compressed)
// - 2001:db8:85a3::192.0.2.128 (mixed)
const ipv6AddressMatch = item.match(/Address: IPv6 ([0-9a-fA-F:]{1,39})/i);
const ipv6AddressMatch = item.match(/Address: IPv6 ([0-9a-fA-F:.]{1,45})/i);
if (ipv6AddressMatch) {
const { 1: address } = ipv6AddressMatch;
this.addAddress(address, 'ipv6');
Expand All @@ -224,7 +224,7 @@ class BlockList {
// - 2001:0db8:85a3:0000:0000:8a2e:0370:7334-2001:0db8:85a3:0000:0000:8a2e:0370:7335 (full)
// - 2001:db8:85a3::8a2e:370:7334-2001:db8:85a3::8a2e:370:7335 (compressed)
// - 2001:db8:85a3::192.0.2.128-2001:db8:85a3::192.0.2.129 (mixed)
const ipv6RangeMatch = item.match(/Range: IPv6 ([0-9a-fA-F:]{1,39})-([0-9a-fA-F:]{1,39})/i);
const ipv6RangeMatch = item.match(/Range: IPv6 ([0-9a-fA-F:.]{1,45})-([0-9a-fA-F:.]{1,45})/i);
if (ipv6RangeMatch) {
const { 1: start, 2: end } = ipv6RangeMatch;
this.addRange(start, end, 'ipv6');
Expand Down
37 changes: 37 additions & 0 deletions test/parallel/test-blocklist.js
Original file line number Diff line number Diff line change
Expand Up @@ -359,3 +359,40 @@ const util = require('util');
assert.strictEqual(test5.check(i[0], i[1]), i[2]);
});
}

{
// IPv4-mapped / mixed-notation IPv6 rules must survive a toJSON/fromJSON
// round-trip. toJSON() emits these addresses in mixed dotted-quad form
// (e.g. "::ffff:192.0.2.128"), so the rule parser must accept the "." used
// in that notation.
const bl = new BlockList();
bl.addAddress('::ffff:192.0.2.128', 'ipv6');
bl.addSubnet('::ffff:10.0.0.0', 120, 'ipv6');
bl.addRange('::ffff:172.16.0.1', '::ffff:172.16.0.10', 'ipv6');

const expected = [
'Address: IPv6 ::ffff:192.0.2.128',
'Range: IPv6 ::ffff:172.16.0.1-::ffff:172.16.0.10',
'Subnet: IPv6 ::ffff:10.0.0.0/120',
];
assert.deepStrictEqual(bl.toJSON().sort(), expected);

const restored = new BlockList();
restored.fromJSON(bl.toJSON());

// The restored rules must be identical (lossless round-trip).
assert.deepStrictEqual(restored.toJSON().sort(), expected);

// And it must still match the same addresses as the original.
[
['::ffff:192.0.2.128', true], // the single address
['::ffff:192.0.2.129', false],
['::ffff:10.0.0.50', true], // inside the subnet
['::ffff:10.0.1.0', false],
['::ffff:172.16.0.5', true], // inside the range
['::ffff:172.16.0.20', false],
].forEach(([address, result]) => {
assert.strictEqual(bl.check(address, 'ipv6'), result);
assert.strictEqual(restored.check(address, 'ipv6'), result);
});
}
Loading