Skip to content

Commit 3b5f802

Browse files
authored
Merge pull request #19 from bd808/validate_netmask
Ensure that the bit string representation of a netmask is the full 32 bits before validating the left most bits are 1s.
2 parents 33954e7 + 041628d commit 3b5f802

7 files changed

Lines changed: 81 additions & 66 deletions

File tree

.gitignore

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
*.egg-info
12
*.pyc
2-
.coverage
3-
.venv
4-
build
5-
dist
6-
extras
7-
iptools.egg-info
3+
/.coverage
4+
/.tox/
5+
/.venv/
6+
/build/
7+
/dist/
8+
/extras/
89
setuptools-*.egg

.travis.yml

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
11
language: python
22
python:
3-
- "2.6"
43
- "2.7"
5-
- "3.2"
6-
- "3.3"
4+
- "3.4"
5+
- "3.5"
76
- "pypy"
7+
- "pypy3"
8+
sudo: false
9+
matrix:
10+
fast_finish: true
11+
812
install:
9-
- pip install .
10-
- pip install -r tests/requirements.txt
13+
- pip install wheel tox-travis
14+
- python setup.py install bdist_wheel
15+
- pip install ./dist/iptools-*.whl
1116
script:
12-
- flake8
13-
- nosetests
17+
- tox
18+
- tox --installpkg ./dist/iptools-*.whl
19+
1420
notifications:
1521
email:
1622
- travis-ci+python-iptools@bd808.com

iptools/__init__.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,6 @@
2222
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2323
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2424
# POSSIBILITY OF SUCH DAMAGE.
25-
__version__ = '0.7.0-dev'
26-
27-
__all__ = (
28-
'IpRange',
29-
'IpRangeList',
30-
)
31-
3225

3326
# sniff for python2.x / python3k compatibility "fixes'
3427
try:
@@ -51,10 +44,16 @@ def next(iterable):
5144
Sequence = object
5245
# end compatibility "fixes'
5346

54-
5547
from . import ipv4
5648
from . import ipv6
5749

50+
__version__ = '0.7.0-dev'
51+
52+
__all__ = (
53+
'IpRange',
54+
'IpRangeList',
55+
)
56+
5857

5958
def _address2long(address):
6059
"""

iptools/ipv4.py

Lines changed: 40 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,40 @@
2323
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2424
# POSSIBILITY OF SUCH DAMAGE.
2525

26+
import re
27+
28+
# sniff for python2.x / python3k compatibility "fixes'
29+
try:
30+
basestring = basestring
31+
except NameError:
32+
# 'basestring' is undefined, must be python3k
33+
basestring = str
34+
35+
try:
36+
bin = bin
37+
except NameError:
38+
# builtin bin function doesn't exist
39+
def bin(x):
40+
"""
41+
From http://code.activestate.com/recipes/219300/#c7
42+
"""
43+
if x < 0:
44+
return '-' + bin(-x)
45+
out = []
46+
if x == 0:
47+
out.append('0')
48+
while x > 0:
49+
out.append('01'[x & 1])
50+
x >>= 1
51+
pass
52+
try:
53+
return '0b' + ''.join(reversed(out))
54+
except NameError:
55+
out.reverse()
56+
return '0b' + ''.join(out)
57+
# end bin
58+
# end compatibility "fixes'
59+
2660
__all__ = (
2761
'cidr2block',
2862
'hex2ip',
@@ -60,43 +94,6 @@
6094
'TEST_NET_3',
6195
)
6296

63-
64-
import re
65-
66-
67-
# sniff for python2.x / python3k compatibility "fixes'
68-
try:
69-
basestring = basestring
70-
except NameError:
71-
# 'basestring' is undefined, must be python3k
72-
basestring = str
73-
74-
try:
75-
bin = bin
76-
except NameError:
77-
# builtin bin function doesn't exist
78-
def bin(x):
79-
"""
80-
From http://code.activestate.com/recipes/219300/#c7
81-
"""
82-
if x < 0:
83-
return '-' + bin(-x)
84-
out = []
85-
if x == 0:
86-
out.append('0')
87-
while x > 0:
88-
out.append('01'[x & 1])
89-
x >>= 1
90-
pass
91-
try:
92-
return '0b' + ''.join(reversed(out))
93-
except NameError:
94-
out.reverse()
95-
return '0b' + ''.join(out)
96-
# end bin
97-
# end compatibility "fixes'
98-
99-
10097
#: Regex for validating an IPv4 address
10198
_DOTTED_QUAD_RE = re.compile(r'^(\d{1,3}\.){0,3}\d{1,3}$')
10299

@@ -285,6 +282,10 @@ def validate_netmask(s):
285282
True
286283
>>> validate_netmask('128.0.0.1')
287284
False
285+
>>> validate_netmask('1.255.255.0')
286+
False
287+
>>> validate_netmask('0.255.255.0')
288+
False
288289
289290
290291
:param s: String to validate as a dotted-quad notation netmask.
@@ -293,7 +294,8 @@ def validate_netmask(s):
293294
:raises: TypeError
294295
"""
295296
if validate_ip(s):
296-
mask = bin(ip2network(s))[2:]
297+
# Convert to binary string, strip '0b' prefix, 0 pad to 32 bits
298+
mask = bin(ip2network(s))[2:].zfill(32)
297299
# all left most bits must be 1, all right most must be 0
298300
seen0 = False
299301
for c in mask:

iptools/ipv6.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2424
# POSSIBILITY OF SUCH DAMAGE.
2525

26+
import re
27+
from . import ipv4
28+
2629
__all__ = (
2730
'cidr2block',
2831
'ip2long',
@@ -52,11 +55,6 @@
5255
'UNSPECIFIED_ADDRESS',
5356
)
5457

55-
56-
import re
57-
from . import ipv4
58-
59-
6058
#: Regex for validating an IPv6 in hex notation
6159
_HEX_RE = re.compile(r'^([0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}$')
6260

setup.cfg

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
[nosetests]
2+
verbosity=2
23
detailed-errors=1
34
with-coverage=1
45
with-doctest=1
56
cover-package=iptools
67
cover-html=1
78
cover-html-dir=docs/_build/cover
9+
cover-branches=1
810

911
[flake8]
10-
ignore=F821,E402
1112
count=1
1213
show-pep8=1
1314
show-source=1
1415
statistics=1
15-
exclude=build,dist,docs,*.egg,*.egg-info
16+
exclude=.tox,.venv,build,dist,docs,*.egg,*.egg-info
1617

1718
[wheel]
1819
universal = 1

tox.ini

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[tox]
2+
envlist = py27, py34, py35, pypy, pypy3
3+
4+
[testenv]
5+
deps = -r{toxinidir}/tests/requirements.txt
6+
commands =
7+
flake8
8+
nosetests

0 commit comments

Comments
 (0)