-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
lib.net_pack stores wrong bit length #71
Comments
same as #66 |
This patch does not work, as unpacking an ip address with bits set in the host mask like |
@commonism correct. for type INET you cannot have a mask length, mask length is only valid for type CIDR. 1.1.1.1/24. unfortunately, this patch is still needed and it does work with ipaddress. although, my local definition for this function is slightly different, using .get() instead. family, bits, data = triple
is_cidr = bits and 1 or 0
bits = bits and bits or {4:32, 6:128}.get(family, 32)
return bytes((fmap[family], bits, is_cidr, len(data))) + data here's a sample program. import postgresql as pgsql
pgdb = pgsql.open('pq://xx:[email protected]/vse?[sslmode]=prefer')
pgdb.execute('DROP TABLE IF EXISTS test_table_a')
pgdb.execute('CREATE TABLE test_table_a (a INET, b CIDR)')
s = pgdb.prepare('INSERT INTO test_table_a (a,b) VALUES ($1,$2)')
s('1.1.1.1', '2.2.2.2') # CIDR default address will yield 2.2.2.2/32
try:
s('1.1.1.1/24', '2.2.2.2')
except:
print('invalid notation for type INET')
s('1.1.1.1', '2.2.0.0/16') # 2.2.2.2/16 will by default raise: DETAIL: Value has bits set to right of mask
q = pgdb.query('SELECT * FROM test_table_a')
for _ in q:
print(_)
pgdb.close() this results in the following output:
unmodified lib.py: vse=# select * from test_table_a;
a | b
---------+------------
1.1.1.1/0 | 2.2.2.2/32
1.1.1.1/0 | 2.2.0.0/16
(2 rows) with my patch: vse=# select * from test_table_a;
a | b
---------+------------
1.1.1.1 | 2.2.2.2/32
1.1.1.1 | 2.2.0.0/16
(2 rows) 1.1.1.1/0 causes problems with other software and should be in INET format which has no mask length. |
You are wrong with your assumption INET can not have a mask. http://www.postgresql.org/docs/9.4/static/datatype-net-types.html
INET allows a mask.
INET could be mapped to IPvXInterface. |
My presentation was unclear and my intent was to point out that the core module >>> ipaddress.ip_address('1.1.1.1')
IPv4Address('1.1.1.1')
>>> ipaddress.ip_address('1.1.1.1/32')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python3.4/ipaddress.py", line 54, in ip_address
address)
ValueError: '1.1.1.1/32' does not appear to be an IPv4 or IPv6 address
>>> ipaddress.ip_network('1.1.1.1/32')
IPv4Network('1.1.1.1/32')
>>> ipaddress.ip_network('1.1.1.1/24')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python3.4/ipaddress.py", line 74, in ip_network
return IPv4Network(address, strict)
File "/usr/lib64/python3.4/ipaddress.py", line 1490, in __init__
raise ValueError('%s has host bits set' % self)
ValueError: 1.1.1.1/24 has host bits set
>>> ipaddress.ip_network('1.1.1.1/24', strict=False)
IPv4Network('1.1.1.0/24') Previous to my patch, py-postgresql was storing INET addresses with a netmask indicated as /0. PostgreSQL is happy storing this data with a mask length, but querying it results in exceptions in the form of: >>> ipaddress.ip_address('1.1.1.1/0')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python3.4/ipaddress.py", line 54, in ip_address
address)
ValueError: '1.1.1.1/0' does not appear to be an IPv4 or IPv6 address It's fine if other software is capable of using pgsql type INET with netmask bits. py-postgresql's data type translator uses In the past I had a modified |
I think I remember running into this. It was a little annoying having to strip out the /0 from ''::inet::text casts. Provide some tests with the patch and I'll apply it. |
when packing an ip_address() for io, the bits value is wrongly stored as a /0 instead of /32 or /128
the following will fix this:
the original code stores "1.2.3.4" as "1.2.3.4/0" instead of "1.2.3.4/32". the above fix will store the correct bits value
The text was updated successfully, but these errors were encountered: