[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Tue Mar 3 17:50:03 MST 2015


The branch, master has been updated
       via  c05b0a3 pyldb: Add tests for type errors
       via  379b919 pyldb: Report errors converting controls list to char**
       via  229935e pyldb: Better error reporting
       via  d460bab pyldb: Type-check arguments parsed with PyArg_ParseTuple*
       via  d599dcb pyldb: Fix reference leaks
       via  359e86a pyldb: Remove use of staticforward macro
       via  f87e6df pyldb: Properly preallocate result control list
       via  92ff259 pyldb: Use the Py_TYPE macro
       via  39b08c7 pyldb: Correct reference counting when returning bools
      from  6b89848 pam: Fix CID 1034871 Resource leak

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit c05b0a35a2f911e0e16a87d6d883fa76feb362b7
Author: Petr Viktorin <pviktori at redhat.com>
Date:   Tue Mar 3 22:29:14 2015 +0100

    pyldb: Add tests for type errors
    
    Signed-off-by: Petr Viktorin <pviktori at redhat.com>
    Reviewed-by: Jelmer Vernooij <jelmer at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Wed Mar  4 01:49:02 CET 2015 on sn-devel-104

commit 379b919e4b5e0c309bd9ef65e84350760b788b03
Author: Petr Viktorin <pviktori at redhat.com>
Date:   Tue Mar 3 22:29:13 2015 +0100

    pyldb: Report errors converting controls list to char**
    
    With this change, passing an unexpected type to the CRUD methods
    will result in an informative TypeError.
    
    Signed-off-by: Petr Viktorin <pviktori at redhat.com>
    Reviewed-by: Jelmer Vernooij <jelmer at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 229935e03686ebdbd4f01cd2939e4399b68c33ec
Author: Petr Viktorin <pviktori at redhat.com>
Date:   Tue Mar 3 22:29:12 2015 +0100

    pyldb: Better error reporting
    
    Provide more useful error messages for some type errors
    
    Signed-off-by: Petr Viktorin <pviktori at redhat.com>
    Reviewed-by: Jelmer Vernooij <jelmer at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit d460bab949ef48ca4e77864d624da5834dabd057
Author: Petr Viktorin <pviktori at redhat.com>
Date:   Tue Mar 3 22:29:11 2015 +0100

    pyldb: Type-check arguments parsed with PyArg_ParseTuple*
    
    PyObject* arguments need to be type-checked before they're
    cast to subtypes.
    
    Signed-off-by: Petr Viktorin <pviktori at redhat.com>
    Reviewed-by: Jelmer Vernooij <jelmer at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit d599dcb6bcac3b7b1600694be38937db0e8719b7
Author: Petr Viktorin <pviktori at redhat.com>
Date:   Tue Mar 3 22:29:10 2015 +0100

    pyldb: Fix reference leaks
    
    The parse_ldif and MessageElement.__iter__ functions leaked references
    to intermediate lists whose iterators they return.
    
    The MessageElement repr used the undocumented macro PyObject_REPR, which
    leaks references. (It was used internally in CPython before fatal errors,
    and will be removed in Python 3.5.)
    
    Signed-off-by: Petr Viktorin <pviktori at redhat.com>
    Reviewed-by: Jelmer Vernooij <jelmer at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 359e86af28719fd84e3b15cfb709536132dc2c14
Author: Petr Viktorin <pviktori at redhat.com>
Date:   Tue Mar 3 22:29:09 2015 +0100

    pyldb: Remove use of staticforward macro
    
    Signed-off-by: Petr Viktorin <pviktori at redhat.com>
    Reviewed-by: Jelmer Vernooij <jelmer at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit f87e6df34ac05b352c6c74bf1fd1d678ee23217f
Author: Petr Viktorin <pviktori at redhat.com>
Date:   Tue Mar 3 22:29:08 2015 +0100

    pyldb: Properly preallocate result control list
    
    The list was always allocated with size 1, so
    if there is more than 1 result control, the additional
    items would not be added in the list, and would
    become leaked references.
    
    Signed-off-by: Petr Viktorin <pviktori at redhat.com>
    Reviewed-by: Jelmer Vernooij <jelmer at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 92ff259f409cfeffc24ef9d7db8ab16217367bab
Author: Petr Viktorin <pviktori at redhat.com>
Date:   Tue Mar 3 22:29:07 2015 +0100

    pyldb: Use the Py_TYPE macro
    
    The "ob_type" member of Python objects is going away
    in Python 3 for compliance with C's strict aliasing rules.
    The Py_TYPE macro should be used instead.
    
    Signed-off-by: Petr Viktorin <pviktori at redhat.com>
    Reviewed-by: Jelmer Vernooij <jelmer at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 39b08c7c1ee2173e47c8e9d381b89c4d74a5e0f5
Author: Petr Viktorin <pviktori at redhat.com>
Date:   Tue Mar 3 22:29:06 2015 +0100

    pyldb: Correct reference counting when returning bools
    
    Simply returning Py_True/PyFalse doesn't increment the bool object's
    reference count.
    
    Signed-off-by: Petr Viktorin <pviktori at redhat.com>
    Reviewed-by: Jelmer Vernooij <jelmer at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 lib/ldb/pyldb.c             | 80 +++++++++++++++++++++++++++++++--------------
 lib/ldb/tests/python/api.py | 42 ++++++++++++++++++++++++
 2 files changed, 97 insertions(+), 25 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c
index 5bcff72..f18e06e 100644
--- a/lib/ldb/pyldb.c
+++ b/lib/ldb/pyldb.c
@@ -48,7 +48,7 @@ static PyTypeObject PyLdb;
 static PyTypeObject PyLdbMessageElement;
 #define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
 
-staticforward PyTypeObject PyLdbTree;
+static PyTypeObject PyLdbTree;
 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);
 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod);
 static struct ldb_message_element *PyObject_AsMessageElement(
@@ -88,7 +88,7 @@ static void py_ldb_control_dealloc(PyLdbControlObject *self)
 		talloc_free(self->mem_ctx);
 	}
 	self->data = NULL;
-	self->ob_type->tp_free(self);
+	Py_TYPE(self)->tp_free(self);
 }
 
 static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self)
@@ -121,9 +121,9 @@ static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject
 	TALLOC_CTX *mem_ctx;
 	struct ldb_context *ldb_ctx;
 
-	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!s",
 					 discard_const_p(char *, kwnames),
-					 &py_ldb, &data))
+					 &PyLdb, &py_ldb, &data))
 		return NULL;
 
 	mem_ctx = talloc_new(NULL);
@@ -269,7 +269,11 @@ static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
 	ret->msgs = list;
 
 	if (result->controls) {
-		controls = PyList_New(1);
+		i = 0;
+		while (result->controls[i]) {
+			i++;
+		}
+		controls = PyList_New(i);
 		if (controls == NULL) {
 			Py_DECREF(ret);
 			PyErr_NoMemory();
@@ -457,7 +461,7 @@ static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
 	if (!PyArg_ParseTuple(args, "s", &name))
 		return NULL;
 
-	return ldb_dn_check_special(self->dn, name)?Py_True:Py_False;
+	return PyBool_FromLong(ldb_dn_check_special(self->dn, name));
 }
 
 static int py_ldb_dn_compare(PyLdbDnObject *dn1, PyLdbDnObject *dn2)
@@ -507,7 +511,7 @@ static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
 	if (!pyldb_Object_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
 		return NULL;
 
-	return ldb_dn_add_child(dn, other)?Py_True:Py_False;
+	return PyBool_FromLong(ldb_dn_add_child(dn, other));
 }
 
 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
@@ -522,7 +526,7 @@ static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
 	if (!pyldb_Object_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
 		return NULL;
 
-	return ldb_dn_add_base(dn, other)?Py_True:Py_False;
+	return PyBool_FromLong(ldb_dn_add_base(dn, other));
 }
 
 static PyObject *py_ldb_dn_remove_base_components(PyLdbDnObject *self, PyObject *args)
@@ -534,7 +538,7 @@ static PyObject *py_ldb_dn_remove_base_components(PyLdbDnObject *self, PyObject
 
 	dn = pyldb_Dn_AsDn((PyObject *)self);
 
-	return ldb_dn_remove_base_components(dn, i)?Py_True:Py_False;
+	return PyBool_FromLong(ldb_dn_remove_base_components(dn, i));
 }
 
 static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args)
@@ -1105,6 +1109,10 @@ static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwar
 		parsed_controls = NULL;
 	} else {
 		const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
+		if (controls == NULL) {
+			talloc_free(mem_ctx);
+			return NULL;
+		}
 		parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
 		talloc_free(controls);
 	}
@@ -1209,7 +1217,7 @@ static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
 			msg_el = PyObject_AsMessageElement(msg->elements, value,
 							   mod_flags, key_str);
 			if (msg_el == NULL) {
-				PyErr_SetString(PyExc_TypeError, "unable to import element");
+				PyErr_Format(PyExc_TypeError, "unable to import element '%s'", key_str);
 				return NULL;
 			}
 			memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
@@ -1250,6 +1258,10 @@ static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
 		parsed_controls = NULL;
 	} else {
 		const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
+		if (controls == NULL) {
+			talloc_free(mem_ctx);
+			return NULL;
+		}
 		parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
 		talloc_free(controls);
 	}
@@ -1339,6 +1351,10 @@ static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwar
 		parsed_controls = NULL;
 	} else {
 		const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
+		if (controls == NULL) {
+			talloc_free(mem_ctx);
+			return NULL;
+		}
 		parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
 		talloc_free(controls);
 	}
@@ -1413,6 +1429,10 @@ static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwar
 		parsed_controls = NULL;
 	} else {
 		const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
+		if (controls == NULL) {
+			talloc_free(mem_ctx);
+			return NULL;
+		}
 		parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
 		talloc_free(controls);
 	}
@@ -1542,7 +1562,7 @@ static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
 
 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
 {
-	PyObject *list;
+	PyObject *list, *ret;
 	struct ldb_ldif *ldif;
 	const char *s;
 
@@ -1569,7 +1589,9 @@ static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
 		}
 	}
 	talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
-	return PyObject_GetIter(list);
+	ret = PyObject_GetIter(list);
+	Py_DECREF(list);
+	return ret;
 }
 
 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
@@ -1711,6 +1733,10 @@ static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwar
 		parsed_controls = NULL;
 	} else {
 		const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
+		if (controls == NULL) {
+			talloc_free(mem_ctx);
+			return NULL;
+		}
 		parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
 		talloc_free(controls);
 	}
@@ -1993,7 +2019,7 @@ static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
 static void py_ldb_dealloc(PyLdbObject *self)
 {
 	talloc_free(self->mem_ctx);
-	self->ob_type->tp_free(self);
+	Py_TYPE(self)->tp_free(self);
 }
 
 static PyTypeObject PyLdb = {
@@ -2017,7 +2043,7 @@ static void py_ldb_result_dealloc(PyLdbResultObject *self)
 	Py_DECREF(self->msgs);
 	Py_DECREF(self->referals);
 	Py_DECREF(self->controls);
-	self->ob_type->tp_free(self);
+	Py_TYPE(self)->tp_free(self);
 }
 
 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
@@ -2135,9 +2161,9 @@ static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, P
 	const char * const*attrs;
 
 	/* type "int" rather than "enum" for "scope" is intentional */
-	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiOO",
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!iOO",
 					 discard_const_p(char *, kwnames),
-					 &py_base, &scope, &py_tree, &py_attrs))
+					 &PyLdbDn, &py_base, &scope, &py_tree, &py_attrs))
 		return NULL;
 
 	mod = self->mod;
@@ -2179,7 +2205,7 @@ static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
 	int ret;
 	struct ldb_module *mod;
 
-	if (!PyArg_ParseTuple(args, "O", &py_message))
+	if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
 		return NULL;
 
 	req = talloc_zero(NULL, struct ldb_request);
@@ -2201,7 +2227,7 @@ static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
 	PyObject *py_message;
 	struct ldb_module *mod;
 
-	if (!PyArg_ParseTuple(args, "O", &py_message))
+	if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
 		return NULL;
 
 	req = talloc_zero(NULL, struct ldb_request);
@@ -2222,7 +2248,7 @@ static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
 	struct ldb_request *req;
 	PyObject *py_dn;
 
-	if (!PyArg_ParseTuple(args, "O", &py_dn))
+	if (!PyArg_ParseTuple(args, "O!", &PyLdbDn, &py_dn))
 		return NULL;
 
 	req = talloc_zero(NULL, struct ldb_request);
@@ -2242,7 +2268,7 @@ static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
 	struct ldb_request *req;
 	PyObject *py_dn1, *py_dn2;
 
-	if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
+	if (!PyArg_ParseTuple(args, "O!O!", &PyLdbDn, &py_dn1, &PyLdbDn, &py_dn2))
 		return NULL;
 
 	req = talloc_zero(NULL, struct ldb_request);
@@ -2446,7 +2472,9 @@ static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
 {
 	PyObject *el = ldb_msg_element_to_set(NULL,
 					      pyldb_MessageElement_AsMessageElement(self));
-	return PyObject_GetIter(el);
+	PyObject *ret = PyObject_GetIter(el);
+	Py_DECREF(el);
+	return ret;
 }
 
 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
@@ -2558,14 +2586,16 @@ static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
 	char *element_str = NULL;
 	Py_ssize_t i;
 	struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
-	PyObject *ret;
+	PyObject *ret, *repr;
 
 	for (i = 0; i < el->num_values; i++) {
 		PyObject *o = py_ldb_msg_element_find(self, i);
+		repr = PyObject_Repr(o);
 		if (element_str == NULL)
-			element_str = talloc_strdup(NULL, PyObject_REPR(o));
+			element_str = talloc_strdup(NULL, PyString_AsString(repr));
 		else
-			element_str = talloc_asprintf_append(element_str, ",%s", PyObject_REPR(o));
+			element_str = talloc_asprintf_append(element_str, ",%s", PyString_AsString(repr));
+		Py_DECREF(repr);
 	}
 
 	if (element_str != NULL) {
@@ -2958,7 +2988,7 @@ static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *cl
 {
 	struct ldb_message *msg = pyldb_Message_AsMessage(self);
 	if (!pyldb_Dn_Check(value)) {
-		PyErr_SetNone(PyExc_TypeError);
+		PyErr_SetString(PyExc_TypeError, "expected dn");
 		return -1;
 	}
 
diff --git a/lib/ldb/tests/python/api.py b/lib/ldb/tests/python/api.py
index 7f5c504..d101de8 100755
--- a/lib/ldb/tests/python/api.py
+++ b/lib/ldb/tests/python/api.py
@@ -776,6 +776,48 @@ class LdbResultTests(TestCase):
         self.assertTrue(found)
 
 
+class BadTypeTests(TestCase):
+    def test_control(self):
+        l = ldb.Ldb()
+        self.assertRaises(TypeError, ldb.Control, '<bad type>', 'relax:1')
+        self.assertRaises(TypeError, ldb.Control, ldb, 1234)
+
+    def test_modify(self):
+        l = ldb.Ldb()
+        dn = ldb.Dn(l, 'a=b')
+        m = ldb.Message(dn)
+        self.assertRaises(TypeError, l.modify, '<bad type>')
+        self.assertRaises(TypeError, l.modify, m, '<bad type>')
+
+    def test_add(self):
+        l = ldb.Ldb()
+        dn = ldb.Dn(l, 'a=b')
+        m = ldb.Message(dn)
+        self.assertRaises(TypeError, l.add, '<bad type>')
+        self.assertRaises(TypeError, l.add, m, '<bad type>')
+
+    def test_delete(self):
+        l = ldb.Ldb()
+        dn = ldb.Dn(l, 'a=b')
+        self.assertRaises(TypeError, l.add, '<bad type>')
+        self.assertRaises(TypeError, l.add, dn, '<bad type>')
+
+    def test_rename(self):
+        l = ldb.Ldb()
+        dn = ldb.Dn(l, 'a=b')
+        self.assertRaises(TypeError, l.add, '<bad type>', dn)
+        self.assertRaises(TypeError, l.add, dn, '<bad type>')
+        self.assertRaises(TypeError, l.add, dn, dn, '<bad type>')
+
+    def test_search(self):
+        l = ldb.Ldb()
+        self.assertRaises(TypeError, l.search, base=1234)
+        self.assertRaises(TypeError, l.search, scope='<bad type>')
+        self.assertRaises(TypeError, l.search, expression=1234)
+        self.assertRaises(TypeError, l.search, attrs='<bad type>')
+        self.assertRaises(TypeError, l.search, controls='<bad type>')
+
+
 class VersionTests(TestCase):
 
     def test_version(self):


-- 
Samba Shared Repository


More information about the samba-cvs mailing list