16
16
#include <sasl/sasl.h>
17
17
#endif
18
18
19
- static void free_attrs (char * * * , PyObject * );
19
+ static void free_attrs (char * * * );
20
20
21
21
/* constructor */
22
22
@@ -248,13 +248,10 @@ List_to_LDAPMods( PyObject *list, int no_op ) {
248
248
*/
249
249
250
250
int
251
- attrs_from_List ( PyObject * attrlist , char * * * attrsp , PyObject * * seq ) {
251
+ attrs_from_List ( PyObject * attrlist , char * * * attrsp ) {
252
252
253
253
char * * attrs = NULL ;
254
- Py_ssize_t i , len ;
255
- PyObject * item ;
256
-
257
- * seq = NULL ;
254
+ PyObject * seq = NULL ;
258
255
259
256
if (attrlist == Py_None ) {
260
257
/* None means a NULL attrlist */
@@ -268,8 +265,16 @@ attrs_from_List( PyObject *attrlist, char***attrsp, PyObject** seq) {
268
265
"expected *list* of strings, not a string" , attrlist );
269
266
goto error ;
270
267
} else {
271
- * seq = PySequence_Fast (attrlist , "expected list of strings or None" );
272
- if (* seq == NULL )
268
+ PyObject * item = NULL ;
269
+ Py_ssize_t i , len , strlen ;
270
+ #if PY_MAJOR_VERSION >= 3
271
+ const char * str ;
272
+ #else
273
+ char * str ;
274
+ #endif
275
+
276
+ seq = PySequence_Fast (attrlist , "expected list of strings or None" );
277
+ if (seq == NULL )
273
278
goto error ;
274
279
275
280
len = PySequence_Length (attrlist );
@@ -280,25 +285,36 @@ attrs_from_List( PyObject *attrlist, char***attrsp, PyObject** seq) {
280
285
281
286
for (i = 0 ; i < len ; i ++ ) {
282
287
attrs [i ] = NULL ;
283
- item = PySequence_Fast_GET_ITEM (* seq , i );
288
+ item = PySequence_Fast_GET_ITEM (seq , i );
284
289
if (item == NULL )
285
290
goto error ;
286
291
#if PY_MAJOR_VERSION == 2
287
- /* Encoded by Python to UTF-8 */
292
+ /* Encoded in Python to UTF-8 */
288
293
if (!PyBytes_Check (item )) {
289
294
LDAPerror_TypeError ("expected bytes in list" , item );
290
295
goto error ;
291
296
}
292
- attrs [i ] = PyBytes_AsString (item );
297
+ if (PyBytes_AsStringAndSize (item , & str , & strlen ) == -1 ) {
298
+ goto error ;
299
+ }
293
300
#else
294
301
if (!PyUnicode_Check (item )) {
295
302
LDAPerror_TypeError ("expected string in list" , item );
296
303
goto error ;
297
304
}
298
- attrs [ i ] = PyUnicode_AsUTF8 (item );
305
+ str = PyUnicode_AsUTF8AndSize (item , & strlen );
299
306
#endif
307
+ /* Make a copy. PyBytes_AsString* / PyUnicode_AsUTF8* return
308
+ * internal values that must be treated like const char. Python
309
+ * 3.7 actually returns a const char.
310
+ */
311
+ attrs [i ] = (char * )PyMem_NEW (char * , strlen + 1 );
312
+ if (attrs [i ] == NULL )
313
+ goto nomem ;
314
+ memcpy (attrs [i ], str , strlen + 1 );
300
315
}
301
316
attrs [len ] = NULL ;
317
+ Py_DECREF (seq );
302
318
}
303
319
304
320
* attrsp = attrs ;
@@ -307,22 +323,26 @@ attrs_from_List( PyObject *attrlist, char***attrsp, PyObject** seq) {
307
323
nomem :
308
324
PyErr_NoMemory ();
309
325
error :
310
- free_attrs (& attrs , * seq );
326
+ Py_XDECREF (seq );
327
+ free_attrs (& attrs );
311
328
return 0 ;
312
329
}
313
330
314
331
/* free memory allocated from above routine */
315
332
316
333
static void
317
- free_attrs ( char * * * attrsp , PyObject * seq ) {
334
+ free_attrs ( char * * * attrsp ) {
318
335
char * * attrs = * attrsp ;
336
+ char * * p ;
319
337
320
- if (attrs != NULL ) {
321
- PyMem_DEL (attrs );
322
- * attrsp = NULL ;
323
- }
338
+ if (attrs == NULL )
339
+ return ;
324
340
325
- Py_XDECREF (seq );
341
+ * attrsp = NULL ;
342
+ for (p = attrs ; * p != NULL ; p ++ ) {
343
+ PyMem_DEL (* p );
344
+ }
345
+ PyMem_DEL (attrs );
326
346
}
327
347
328
348
/*------------------------------------------------------------
@@ -1130,7 +1150,6 @@ l_ldap_search_ext( LDAPObject* self, PyObject* args )
1130
1150
1131
1151
PyObject * serverctrls = Py_None ;
1132
1152
PyObject * clientctrls = Py_None ;
1133
- PyObject * attrs_seq = NULL ;
1134
1153
LDAPControl * * server_ldcs = NULL ;
1135
1154
LDAPControl * * client_ldcs = NULL ;
1136
1155
@@ -1148,7 +1167,7 @@ l_ldap_search_ext( LDAPObject* self, PyObject* args )
1148
1167
& serverctrls , & clientctrls , & timeout , & sizelimit )) return NULL ;
1149
1168
if (not_valid (self )) return NULL ;
1150
1169
1151
- if (!attrs_from_List ( attrlist , & attrs , & attrs_seq ))
1170
+ if (!attrs_from_List ( attrlist , & attrs ))
1152
1171
return NULL ;
1153
1172
1154
1173
if (timeout >= 0 ) {
@@ -1160,14 +1179,14 @@ l_ldap_search_ext( LDAPObject* self, PyObject* args )
1160
1179
1161
1180
if (!PyNone_Check (serverctrls )) {
1162
1181
if (!LDAPControls_from_object (serverctrls , & server_ldcs )) {
1163
- free_attrs ( & attrs , attrs_seq );
1182
+ free_attrs ( & attrs );
1164
1183
return NULL ;
1165
1184
}
1166
1185
}
1167
1186
1168
1187
if (!PyNone_Check (clientctrls )) {
1169
1188
if (!LDAPControls_from_object (clientctrls , & client_ldcs )) {
1170
- free_attrs ( & attrs , attrs_seq );
1189
+ free_attrs ( & attrs );
1171
1190
LDAPControl_List_DEL ( server_ldcs );
1172
1191
return NULL ;
1173
1192
}
@@ -1178,7 +1197,7 @@ l_ldap_search_ext( LDAPObject* self, PyObject* args )
1178
1197
server_ldcs , client_ldcs , tvp , sizelimit , & msgid );
1179
1198
LDAP_END_ALLOW_THREADS ( self );
1180
1199
1181
- free_attrs ( & attrs , attrs_seq );
1200
+ free_attrs ( & attrs );
1182
1201
LDAPControl_List_DEL ( server_ldcs );
1183
1202
LDAPControl_List_DEL ( client_ldcs );
1184
1203
0 commit comments