8000 BREAKING CHANGE: fix parsing of IPs with less than 4 bytes · rs/node-netmask@9f9fc38 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9f9fc38

Browse files
committed
BREAKING CHANGE: fix parsing of IPs with less than 4 bytes
Previous API was treating IPs with less than for bytes as IP with a netmask of the size of the provided bytes (1=8, 2=16, 3=24) and was interpreting the IP as if it was completed with 0s on the right side. Propre IP parsing for these is to consider missing bytes as being 0s on the left side. Mask size is no longer infered by the number of bytes provided.
1 parent ec1b5b5 commit 9f9fc38

File tree

3 files changed

+29
-24
lines changed

3 files changed

+29
-24
lines changed

README.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,9 @@ Netmask objects are created with an IP address and optionally a mask. There are
3636
'216.240.32.0', '255.255.255.0'
3737
'216.240.32.0', 0xffffff00
3838
'216.240.32.4' // A /32 block.
39-
'216.240.32' // A /24 block.
40-
'216.240' // A /16 block.
41-
'140' // A /8 block.
42-
'216.240.32/24'
43-
'216.240/16'
39+
'0330.0360.040.04' // Octal form
40+
'0xd8.0xf0.0x20.0x4' // Hex form
41+
4442

4543
API
4644
---
@@ -67,7 +65,7 @@ License
6765

6866
(The MIT License)
6967

70-
Copyright (c) 2011 Olivier Poitrey <rs@dailymotion.com>
68+
Copyright (c) 2011 Olivier Poitrey <rs@rhapsodyk.net>
7169

7270
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
7371

lib/netmask.coffee

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ ip2long = (ip) ->
2121
if isNaN(byte) then throw new Error("Invalid byte: #{byte}")
2222
if byte < 0 or byte > 255 then throw new Error("Invalid byte: #{byte}")
2323
b[i] = byte
24-
return ((b[0] or 0) << 24 | (b[1] or 0) << 16 | (b[2] or 0) << 8 | (b[3] or 0)) >>> 0
24+
while b.length < 4
25+
b.unshift(0)
26+
return (b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3]) >>> 0
2527

2628

2729
class Netmask
@@ -31,13 +33,7 @@ class Netmask
3133
# try to find the mask in the net (i.e.: 1.2.3.4/24 or 1.2.3.4/255.255.255.0)
3234
[net, mask] = net.split('/', 2)
3335
unless mask
34-
switch net.split('.').length
35-
when 1 then mask = 8
36-
when 2 then mask = 16
37-
when 3 then mask = 24
38-
when 4 then mask = 32
39-
else throw new Error("Invalid net address: #{net}")
40-
36+
mask = 32
4137
if typeof mask is 'string' and mask.indexOf('.') > -1
4238
# Compute bitmask, the netmask as a number of bits in the network portion of the address for this block (eg.: 24)
4339
try
@@ -48,7 +44,7 @@ class Netmask
4844
if @maskLong == (0xffffffff << (32 - i)) >>> 0
4945
@bitmask = i
5046
break
51-
else if mask
47+
else if mask or mask == 0
5248
# The mask was passed as bitmask, compute the mask as long from it
5349
@bitmask = parseInt(mask, 10)
5450
@maskLong = 0

test/netmasks.coffee

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ fixtures =
1010
['209.157.68.22', '255.255.224.0', '209.157.64.0', '255.255.224.0', 19]
1111
['209.157.70.33/19', null, '209.157.64.0', '255.255.224.0', 19]
1212
['209.157.70.33', null, '209.157.70.33', '255.255.255.255', 32]
13-
['140.174.82', null, '140.174.82.0', '255.255.255.0', 24]
14-
['140.174', null, '140.174.0.0', '255.255.0.0', 16]
15-
['10', null, '10.0.0.0', '255.0.0.0', 8]
16-
['10/8', null, '10.0.0.0', '255.0.0.0', 8]
17-
['209.157.64/19', null, '209.157.64.0', '255.255.224.0', 19]
13+
['140.174.82', null, '0.140.174.82', '255.255.255.255', 32]
14+
['140.174', null, '0.0.140.174', '255.255.255.255', 32]
15+
['10', null, '0.0.0.10', '255.255.255.255', 32]
16+
['10/8', null, '0.0.0.0', '255.0.0.0', 8]
17+
['209.157.64/19', null, '0.209.128.0', '255.255.224.0', 19]
1818
['216.140.48.16/32', null, '216.140.48.16', '255.255.255.255', 32]
19-
['209.157/17', null, '209.157.0.0', '255.255.128.0', 17]
19+
['209.157/17', null, '0.0.128.0', '255.255.128.0', 17]
2020
['0.0.0.0/0', null, '0.0.0.0', '0.0.0.0', 0]
2121
]
2222

@@ -45,14 +45,15 @@ vows.describe('Netmask contains IP')
4545
'does not contain IP 10.168.2.0': (block) -> assert.ok not block.contains('10.168.2.0')
4646
'does not contain IP 209.168.2.0': (block) -> assert.ok not block.contains('209.168.2.0')
4747
'contains block 192.168.1.0/24': (block) -> assert.ok block.contains('192.168.1.0/24')
48-
'contains block 192.168.1': (block) -> assert.ok block.contains('192.168.1')
49-
'contains block 192.168.1.128/25': (block) -> assert.ok block.contains('192.168.1.128/25')
48+
'contains block 192.168.1 (0.192.168.10)': (block) -> assert.ok not block.contains('192.168.1')
49+
'does not contains block 192.168.1.128/25': (block) -> assert.ok block.contains('192.168.1.128/25')
5050
'does not contain block 192.168.1.0/23': (block) -> assert.ok not block.contains('192.168.1.0/23')
5151
'does not contain block 192.168.2.0/24': (block) -> assert.ok not block.contains('192.168.2.0/24')
5252
'toString equals 192.168.1.0/24': (block) -> assert.equal block.toString(), '192.168.1.0/24'
5353
'block 192.168.0.0/24':
5454
topic: -> new Netmask('192.168.0.0/24')
55-
'does not contain block 192.168': (block) -> assert.ok not block.contains('192.168')
55+
'does not contain block 192.168 (0.0.192.168)': (block) -> assert.ok not block.contains('192.168')
56+
'does not contain block 192.168.0.0/16': (block) -> assert.ok not block.contains('192.168.0.0/16')
5657
'block 31.0.0.0/8':
5758
topic: -> new Netmask('31.0.0.0/8')
5859
'contains IP 31.5.5.5': (block) -> assert.ok block.contains('31.5.5.5')
@@ -64,6 +65,16 @@ vows.describe('Netmask contains IP')
6465
'contains IP 127.0.0.2': (block) -> assert.ok block.contains('127.0.0.2')
6566
'contains IP 0177.0.0.2 (127.0.0.2)': (block) -> assert.ok block.contains('0177.0.0.2')
6667
'contains IP 0x7f.0.0.2 (127.0.0.2)': (block) -> assert.ok block.contains('0x7f.0.0.2')
68+
'does not contains IP 127 (0.0.0.127)': (block) -> assert.ok not block.contains('127')
69+
'does not contains IP 0177 (0.0.0.127)': (block) -> assert.ok not block.contains('0177')
70+
'block 0.0.0.0/24':
71+
topic: -> new Netmask('0.0.0.0/0')
72+
'contains IP 0.0.0.0': (block) -> assert.ok block.contains('0.0.0.0')
73+
'contains IP 0': (block) -> assert.ok block.contains('0')
74+
'contains IP 10 (0.0.0.10)': (block) -> assert.ok block.contains('10')
75+
'contains IP 010 (0.0.0.8)': (block) -> assert.ok block.contains('010')
76+
'contains IP 0x10 (0.0.0.16)': (block) -> assert.ok block.contains('0x10')
77+
6778
.export(module)
6879

6980
vows.describe('Netmask forEach')

0 commit comments

Comments
 (0)
0