diff options
author | John Dennis <jdennis@redhat.com> | 2012-08-17 15:34:40 -0400 |
---|---|---|
committer | Alexander Bokovoy <abokovoy@redhat.com> | 2012-08-22 17:23:20 +0300 |
commit | 6cad0d05405d4dc3e943dec8c53a8ec67eee5c41 (patch) | |
tree | aba469ed83ddcbe8631b2f148e3bd456bb00089e /tests | |
parent | 88f358fdcfea2029a307caa3deb3ea842c6394b6 (diff) | |
download | freeipa.git-6cad0d05405d4dc3e943dec8c53a8ec67eee5c41.tar.gz freeipa.git-6cad0d05405d4dc3e943dec8c53a8ec67eee5c41.tar.xz freeipa.git-6cad0d05405d4dc3e943dec8c53a8ec67eee5c41.zip |
Ticket #3008: DN objects hash differently depending on case
Because the attrs & values in DN's, RDN's and AVA's are comparison case-
insensitive the hash value between two objects which compare as equal but
differ in case must also yield the same hash value. This is critical when
these objects are used as a dict key or in a set because dicts and sets
use the object's __hash__ value in conjunction with the objects __eq__
method to lookup the object.
The defect is the DN, RDN & AVA objects computed their hash from the case-
preserving string representation thus two otherwise equal objects
incorrectly yielded different hash values.
The problem manifests itself when one of these objects is used as a key in
a dict, for example a dn.
dn1 = DN(('cn', 'Bob'))
dn2 = DN(('cn', 'bob'))
dn1 == dn2 --> True
hash(dn1) == hash(dn2) --> False
d = {}
d[dn1] = x
d[dn2] = y
len(d) --> 2
The patch fixes the above by lower casing the string representation of
the object prior to computing it's hash.
The patch also corrects a spelling mistake and a bogus return value in
ldapupdate.py which happened to be discovered while researching this
bug.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/test_ipapython/test_dn.py | 30 |
1 files changed, 15 insertions, 15 deletions
diff --git a/tests/test_ipapython/test_dn.py b/tests/test_ipapython/test_dn.py index 441affa4..cdeab937 100644 --- a/tests/test_ipapython/test_dn.py +++ b/tests/test_ipapython/test_dn.py @@ -267,12 +267,12 @@ class TestAVA(unittest.TestCase): self.assertEqual(result, -1) def test_hashing(self): - # create AVA's that have the same value - immutable_ava1 = AVA((self.attr1, self.value1)) - immutable_ava2 = AVA((self.attr1, self.value1)) + # create AVA's that are equal but differ in case + immutable_ava1 = AVA((self.attr1.lower(), self.value1.upper())) + immutable_ava2 = AVA((self.attr1.upper(), self.value1.lower())) - mutable_ava1 = EditableAVA((self.attr1, self.value1)) - mutable_ava2 = EditableAVA((self.attr1, self.value1)) + mutable_ava1 = EditableAVA((self.attr1.lower(), self.value1.upper())) + mutable_ava2 = EditableAVA((self.attr1.upper(), self.value1.lower())) # Immutable AVA's that are equal should hash to the same value. # Mutable AVA's should not be hashable. @@ -828,12 +828,12 @@ class TestRDN(unittest.TestCase): def test_hashing(self): - # create RDN's that have the same value - immutable_rdn1 = RDN((self.attr1, self.value1)) - immutable_rdn2 = RDN((self.attr1, self.value1)) + # create RDN's that are equal but differ in case + immutable_rdn1 = RDN((self.attr1.lower(), self.value1.upper())) + immutable_rdn2 = RDN((self.attr1.upper(), self.value1.lower())) - mutable_rdn1 = EditableRDN((self.attr1, self.value1)) - mutable_rdn2 = EditableRDN((self.attr1, self.value1)) + mutable_rdn1 = EditableRDN((self.attr1.lower(), self.value1.upper())) + mutable_rdn2 = EditableRDN((self.attr1.upper(), self.value1.lower())) # Immutable RDN's that are equal should hash to the same value. # Mutable RDN's should not be hashable. @@ -1706,12 +1706,12 @@ class TestDN(unittest.TestCase): self.assertExpectedClass(DN_class, dn[i][j], 'AVA') def test_hashing(self): - # create DN's that have the same value - immutable_dn1 = DN((self.attr1, self.value1)) - immutable_dn2 = DN((self.attr1, self.value1)) + # create DN's that are equal but differ in case + immutable_dn1 = DN((self.attr1.lower(), self.value1.upper())) + immutable_dn2 = DN((self.attr1.upper(), self.value1.lower())) - mutable_dn1 = EditableDN((self.attr1, self.value1)) - mutable_dn2 = EditableDN((self.attr1, self.value1)) + mutable_dn1 = EditableDN((self.attr1.lower(), self.value1.upper())) + mutable_dn2 = EditableDN((self.attr1.upper(), self.value1.lower())) # Immutable DN's that are equal should hash to the same value. # Mutable DN's should not be hashable. |