Skip to content

Commit

Permalink
Fix type conversion in page control
Browse files Browse the repository at this point in the history
The RFC 2696 function decode_page_control() had a conversion error.
`count` is an unsigned long. The correct format character for
Py_BuildValue() is 'k', not 'l'. The problem caused the function to to return
wrong value every now and then. I have seen 140728898420741 or
140728898420741 instead of 5.

In Python 3, SimplePagedResultsControl converted cookie to text although
it's an OCTET STRING. The cookie is now correctly converted to bytes.

Add tests for all four uncovered helper functions.

https://github.com/python-ldap/python-ldap/pull/10
Signed-off-by: Christian Heimes <cheimes@redhat.com>
  • Loading branch information
Christian Heimes authored and Petr Viktorin committed Nov 25, 2017
1 parent c296d61 commit 52077e8
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Lib/ldap/controls/pagedresults.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def encodeControlValue(self):
def decodeControlValue(self,encodedControlValue):
decodedValue,_ = decoder.decode(encodedControlValue,asn1Spec=PagedResultsControlValue())
self.size = int(decodedValue.getComponentByName('size'))
self.cookie = str(decodedValue.getComponentByName('cookie'))
self.cookie = bytes(decodedValue.getComponentByName('cookie'))


KNOWN_RESPONSE_CONTROLS[SimplePagedResultsControl.controlType] = SimplePagedResultsControl
4 changes: 2 additions & 2 deletions Modules/ldapcontrol.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ decode_rfc2696(PyObject *self, PyObject *args)
struct berval ldctl_value;
ber_tag_t tag;
struct berval *cookiep;
unsigned long count;
unsigned long count = 0;
Py_ssize_t ldctl_value_len;

if (!PyArg_ParseTuple(args, "s#:decode_page_control",
Expand All @@ -324,7 +324,7 @@ decode_rfc2696(PyObject *self, PyObject *args)
goto endlbl;
}

res = Py_BuildValue("(lO&)", count, LDAPberval_to_object, cookiep);
res = Py_BuildValue("(kO&)", count, LDAPberval_to_object, cookiep);
ber_bvfree(cookiep);

endlbl:
Expand Down
1 change: 1 addition & 0 deletions Tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@
from . import t_edit
from . import t_ldap_schema_subentry
from . import t_untested_mods
from . import t_ldap_controls_libldap
54 changes: 54 additions & 0 deletions Tests/t_ldap_controls_libldap.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import os
import unittest

# Switch off processing .ldaprc or ldap.conf before importing _ldap
os.environ['LDAPNOINIT'] = '1'

import ldap
from ldap.controls import pagedresults
from ldap.controls import libldap


PRC_BER = b'0\x0b\x02\x01\x05\x04\x06cookie'
SIZE = 5
COOKIE = b'cookie'


class TestLibldapControls(unittest.TestCase):
def test_pagedresults_encode(self):
pr = pagedresults.SimplePagedResultsControl(
size=SIZE, cookie=COOKIE
)
lib = libldap.SimplePagedResultsControl(
size=SIZE, cookie=COOKIE
)
self.assertEqual(pr.encodeControlValue(), lib.encodeControlValue())
self.assertEqual(pr.encodeControlValue(), PRC_BER)

def test_pagedresults_decode(self):
pr = pagedresults.SimplePagedResultsControl()
pr.decodeControlValue(PRC_BER)
self.assertEqual(pr.size, SIZE)
# LDAPString (OCTET STRING)
self.assertIsInstance(pr.cookie, bytes)
self.assertEqual(pr.cookie, COOKIE)

lib = libldap.SimplePagedResultsControl()
lib.decodeControlValue(PRC_BER)
self.assertEqual(lib.size, SIZE)
self.assertIsInstance(lib.cookie, bytes)
self.assertEqual(lib.cookie, COOKIE)

def test_matchedvalues(self):
mvc = libldap.MatchedValuesControl()
# unverified
self.assertEqual(mvc.encodeControlValue(), b'0\r\x87\x0bobjectClass')

def test_assertioncontrol(self):
ac = libldap.AssertionControl()
# unverified
self.assertEqual(ac.encodeControlValue(), b'\x87\x0bobjectClass')


if __name__ == '__main__':
unittest.main()
1 change: 0 additions & 1 deletion Tests/t_untested_mods.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import ldap.async
import ldap.controls.deref
import ldap.controls.openldap
import ldap.controls.pagedresults
import ldap.controls.ppolicy
import ldap.controls.psearch
import ldap.controls.pwdpolicy
Expand Down

0 comments on commit 52077e8

Please sign in to comment.