Skip to content

Commit 20bee65

Browse files
author
leonard
committed
Factor out LDAPberval_to_object()
Also commit other berval converters which are not yet called by anything. In places where bervals are returned as objects, PyString_FromStringAndSize() was being used. In some rare cases, a NULL berval pointer (not NULL data) is returned as None (not a string). This factors that out to the berval.c compilation unit.
1 parent ce8aca9 commit 20bee65

File tree

3 files changed

+138
-0
lines changed

3 files changed

+138
-0
lines changed

Modules/berval.c

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/* See http://www.python-ldap.org/ for details.
2+
* $Id: berval.c,v 1.1 2009/08/17 01:49:47 leonard Exp $ */
3+
4+
#include "common.h"
5+
#include "berval.h"
6+
7+
/*
8+
* Converts a Python object into a data for a berval structure.
9+
*
10+
* New memory is allocated, and the content of the object is copied into it.
11+
* Then the (pre-existing) berval structure's field are filled in with pointer
12+
* and length data.
13+
*
14+
* The source object must implement the buffer interface, or be None.
15+
* If the source object is None, bv->bv_val will be set to NULL and bv_len to 0.
16+
* Otherwise, bv->bv_val will be non-NULL (even for zero-length data).
17+
* This allows the caller to distinguish a None argument as something special.
18+
*
19+
* Returns 0 on failure, leaving *bv unchanged, and setting an error.
20+
* Returns 1 on success: the berval must be freed with LDAPberval_release().
21+
*/
22+
int
23+
LDAPberval_from_object(PyObject *obj, struct berval *bv)
24+
{
25+
const void *data;
26+
char *datacp;
27+
Py_ssize_t len;
28+
29+
if (PyNone_Check(obj)) {
30+
bv->bv_len = 0;
31+
bv->bv_val = NULL;
32+
return 1;
33+
}
34+
35+
if (!PyObject_AsReadBuffer(obj, &data, &len))
36+
return 0;
37+
38+
datacp = PyMem_MALLOC(len ? len : 1);
39+
if (!datacp) {
40+
PyErr_NoMemory();
41+
return 0;
42+
}
43+
memcpy(datacp, data, len);
44+
45+
bv->bv_len = len;
46+
bv->bv_val = datacp;
47+
return 1;
48+
}
49+
50+
/*
51+
* Returns true if the object could be used to initialize a berval structure
52+
* with LDAPberval_from_object()
53+
*/
54+
int
55+
LDAPberval_from_object_check(PyObject *obj)
56+
{
57+
return PyNone_Check(obj) ||
58+
PyObject_CheckReadBuffer(obj);
59+
}
60+
61+
/*
62+
* Releases memory allocated by LDAPberval_from_object().
63+
* Has no effect if the berval pointer is NULL or the berval data is NULL.
64+
*/
65+
void
66+
LDAPberval_release(struct berval *bv) {
67+
if (bv && bv->bv_val) {
68+
PyMem_FREE(bv->bv_val);
69+
bv->bv_len = 0;
70+
bv->bv_val = NULL;
71+
}
72+
}
73+
74+
/*
75+
* Copies out the data from a berval, and returns it as a new Python object,
76+
* Returns None if the berval pointer is NULL.
77+
*
78+
* Note that this function is not the exact inverse of LDAPberval_from_object
79+
* with regards to the NULL/None conversion.
80+
*
81+
* Returns a new Python object on success, or NULL on failure.
82+
*/
83+
PyObject *
84+
LDAPberval_to_object(const struct berval *bv)
85+
{
86+
PyObject *ret = NULL;
87+
88+
if (!bv) {
89+
ret = Py_None;
90+
Py_INCREF(ret);
91+
}
92+
else {
93+
ret = PyString_FromStringAndSize(bv->bv_val, bv->bv_len);
94+
}
95+
96+
return ret;
97+
}

Modules/berval.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/* See http://www.python-ldap.org/ for details.
2+
* $Id: berval.h,v 1.1 2009/08/17 01:49:47 leonard Exp $ */
3+
4+
#ifndef __h_berval
5+
#define __h_berval
6+
7+
#include "common.h"
8+
#include "lber.h"
9+
10+
int LDAPberval_from_object(PyObject *obj, struct berval *bv);
11+
int LDAPberval_from_object_check(PyObject *obj);
12+
void LDAPberval_release(struct berval *bv);
13+
PyObject *LDAPberval_to_object(const struct berval *bv);
14+
15+
#endif /* __h_berval_ */

Tests/runtests.sh

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/bin/sh
2+
#
3+
# This script runs all the t_*.py tests in the current directory,
4+
# preparing PYTHONPATH to use the most recent local build
5+
#
6+
# Run with -v option for verbose
7+
#
8+
9+
set -e
10+
: ${PYTHON:="python"}
11+
plat_specifier=`$PYTHON -c 'import sys,distutils.util; \
12+
print(distutils.util.get_platform()+"-"+sys.version[0:3])'`
13+
failed=
14+
for test in t_*.py; do
15+
echo "$test:"
16+
PYTHONPATH="../build/lib.$plat_specifier" $PYTHON "$test" "$@" ||
17+
failed="$failed $test"
18+
done
19+
20+
if test -n "$failed"; then
21+
echo "Tests that failed:$failed" >&2
22+
exit 1
23+
else
24+
echo "All tests passed. Yay."
25+
exit 0
26+
fi

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy