Location | Tool | Test ID | Function | Issue |
---|---|---|---|---|
/builddir/build/BUILD/Python-2.7.3/Modules/_ctypes/callbacks.c:325:20 | clang-analyzer | Dereference of undefined pointer value | ||
/builddir/build/BUILD/Python-2.7.3/Modules/_ctypes/callbacks.c:325:20 | clang-analyzer | Dereference of undefined pointer value |
1 /*****************************************************************
2 This file should be kept compatible with Python 2.3, see PEP 291.
3 *****************************************************************/
4
5 #include "Python.h"
6 #include "compile.h" /* required only for 2.3, as it seems */
7 #include "frameobject.h"
8
9 #include <ffi.h>
10 #ifdef MS_WIN32
11 #include <windows.h>
12 #endif
13 #include "ctypes.h"
14
15 /**************************************************************/
16
17 static void
18 CThunkObject_dealloc(PyObject *_self)
19 {
20 CThunkObject *self = (CThunkObject *)_self;
21 PyObject_GC_UnTrack(self);
22 Py_XDECREF(self->converters);
23 Py_XDECREF(self->callable);
24 Py_XDECREF(self->restype);
25 if (self->pcl_write)
26 ffi_closure_free(self->pcl_write);
27 PyObject_GC_Del(self);
28 }
29
30 static int
31 CThunkObject_traverse(PyObject *_self, visitproc visit, void *arg)
32 {
33 CThunkObject *self = (CThunkObject *)_self;
34 Py_VISIT(self->converters);
35 Py_VISIT(self->callable);
36 Py_VISIT(self->restype);
37 return 0;
38 }
39
40 static int
41 CThunkObject_clear(PyObject *_self)
42 {
43 CThunkObject *self = (CThunkObject *)_self;
44 Py_CLEAR(self->converters);
45 Py_CLEAR(self->callable);
46 Py_CLEAR(self->restype);
47 return 0;
48 }
49
50 PyTypeObject PyCThunk_Type = {
51 PyVarObject_HEAD_INIT(NULL, 0)
52 "_ctypes.CThunkObject",
53 sizeof(CThunkObject), /* tp_basicsize */
54 sizeof(ffi_type), /* tp_itemsize */
55 CThunkObject_dealloc, /* tp_dealloc */
56 0, /* tp_print */
57 0, /* tp_getattr */
58 0, /* tp_setattr */
59 0, /* tp_compare */
60 0, /* tp_repr */
61 0, /* tp_as_number */
62 0, /* tp_as_sequence */
63 0, /* tp_as_mapping */
64 0, /* tp_hash */
65 0, /* tp_call */
66 0, /* tp_str */
67 0, /* tp_getattro */
68 0, /* tp_setattro */
69 0, /* tp_as_buffer */
70 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
71 "CThunkObject", /* tp_doc */
72 CThunkObject_traverse, /* tp_traverse */
73 CThunkObject_clear, /* tp_clear */
74 0, /* tp_richcompare */
75 0, /* tp_weaklistoffset */
76 0, /* tp_iter */
77 0, /* tp_iternext */
78 0, /* tp_methods */
79 0, /* tp_members */
80 };
81
82 /**************************************************************/
83
84 static void
85 PrintError(char *msg, ...)
86 {
87 char buf[512];
88 PyObject *f = PySys_GetObject("stderr");
89 va_list marker;
90
91 va_start(marker, msg);
92 vsnprintf(buf, sizeof(buf), msg, marker);
93 va_end(marker);
94 if (f)
95 PyFile_WriteString(buf, f);
96 PyErr_Print();
97 }
98
99 #if (PY_VERSION_HEX < 0x02070000)
100 PyCodeObject *
101 PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
102 {
103 static PyObject *emptystring = NULL;
104 static PyObject *nulltuple = NULL;
105 PyObject *filename_ob = NULL;
106 PyObject *funcname_ob = NULL;
107 PyCodeObject *result = NULL;
108 if (emptystring == NULL) {
109 emptystring = PyString_FromString("");
110 if (emptystring == NULL)
111 goto failed;
112 }
113 if (nulltuple == NULL) {
114 nulltuple = PyTuple_New(0);
115 if (nulltuple == NULL)
116 goto failed;
117 }
118 funcname_ob = PyString_FromString(funcname);
119 if (funcname_ob == NULL)
120 goto failed;
121 filename_ob = PyString_FromString(filename);
122 if (filename_ob == NULL)
123 goto failed;
124
125 result = PyCode_New(0, /* argcount */
126 0, /* nlocals */
127 0, /* stacksize */
128 0, /* flags */
129 emptystring, /* code */
130 nulltuple, /* consts */
131 nulltuple, /* names */
132 nulltuple, /* varnames */
133 nulltuple, /* freevars */
134 nulltuple, /* cellvars */
135 filename_ob, /* filename */
136 funcname_ob, /* name */
137 firstlineno, /* firstlineno */
138 emptystring /* lnotab */
139 );
140
141 failed:
142 Py_XDECREF(funcname_ob);
143 Py_XDECREF(filename_ob);
144 return result;
145 }
146 #endif
147
148
149 /* after code that pyrex generates */
150 void _ctypes_add_traceback(char *funcname, char *filename, int lineno)
151 {
152 PyObject *py_globals = 0;
153 PyCodeObject *py_code = 0;
154 PyFrameObject *py_frame = 0;
155
156 py_globals = PyDict_New();
157 if (!py_globals) goto bad;
158 py_code = PyCode_NewEmpty(filename, funcname, lineno);
159 if (!py_code) goto bad;
160 py_frame = PyFrame_New(
161 PyThreadState_Get(), /*PyThreadState *tstate,*/
162 py_code, /*PyCodeObject *code,*/
163 py_globals, /*PyObject *globals,*/
164 0 /*PyObject *locals*/
165 );
166 if (!py_frame) goto bad;
167 py_frame->f_lineno = lineno;
168 PyTraceBack_Here(py_frame);
169 bad:
170 Py_XDECREF(py_globals);
171 Py_XDECREF(py_code);
172 Py_XDECREF(py_frame);
173 }
174
175 #ifdef MS_WIN32
176 /*
177 * We must call AddRef() on non-NULL COM pointers we receive as arguments
178 * to callback functions - these functions are COM method implementations.
179 * The Python instances we create have a __del__ method which calls Release().
180 *
181 * The presence of a class attribute named '_needs_com_addref_' triggers this
182 * behaviour. It would also be possible to call the AddRef() Python method,
183 * after checking for PyObject_IsTrue(), but this would probably be somewhat
184 * slower.
185 */
186 static void
187 TryAddRef(StgDictObject *dict, CDataObject *obj)
188 {
189 IUnknown *punk;
190
191 if (NULL == PyDict_GetItemString((PyObject *)dict, "_needs_com_addref_"))
192 return;
193
194 punk = *(IUnknown **)obj->b_ptr;
195 if (punk)
196 punk->lpVtbl->AddRef(punk);
197 return;
198 }
199 #endif
200
201 /******************************************************************************
202 *
203 * Call the python object with all arguments
204 *
205 */
206 static void _CallPythonObject(void *mem,
207 ffi_type *restype,
208 SETFUNC setfunc,
209 PyObject *callable,
210 PyObject *converters,
211 int flags,
212 void **pArgs)
213 {
214 Py_ssize_t i;
215 PyObject *result;
216 PyObject *arglist = NULL;
217 Py_ssize_t nArgs;
218 PyObject *error_object = NULL;
219 int *space;
220 #ifdef WITH_THREAD
221 PyGILState_STATE state = PyGILState_Ensure();
222 #endif
223
224 nArgs = PySequence_Length(converters);
225 /* Hm. What to return in case of error?
226 For COM, 0xFFFFFFFF seems better than 0.
227 */
228 if (nArgs < 0) {
229 PrintError("BUG: PySequence_Length");
230 goto Done;
231 }
232
233 arglist = PyTuple_New(nArgs);
234 if (!arglist) {
235 PrintError("PyTuple_New()");
236 goto Done;
237 }
238 for (i = 0; i < nArgs; ++i) {
239 /* Note: new reference! */
240 PyObject *cnv = PySequence_GetItem(converters, i);
241 StgDictObject *dict;
242 if (cnv)
243 dict = PyType_stgdict(cnv);
244 else {
245 PrintError("Getting argument converter %d\n", i);
246 goto Done;
247 }
248
249 if (dict && dict->getfunc && !_ctypes_simple_instance(cnv)) {
250 PyObject *v = dict->getfunc(*pArgs, dict->size);
251 if (!v) {
252 PrintError("create argument %d:\n", i);
253 Py_DECREF(cnv);
254 goto Done;
255 }
256 PyTuple_SET_ITEM(arglist, i, v);
257 /* XXX XXX XX
258 We have the problem that c_byte or c_short have dict->size of
259 1 resp. 4, but these parameters are pushed as sizeof(int) bytes.
260 BTW, the same problem occurs when they are pushed as parameters
261 */
262 } else if (dict) {
263 /* Hm, shouldn't we use PyCData_AtAddress() or something like that instead? */
264 CDataObject *obj = (CDataObject *)PyObject_CallFunctionObjArgs(cnv, NULL);
265 if (!obj) {
266 PrintError("create argument %d:\n", i);
267 Py_DECREF(cnv);
268 goto Done;
269 }
270 if (!CDataObject_Check(obj)) {
271 Py_DECREF(obj);
272 Py_DECREF(cnv);
273 PrintError("unexpected result of create argument %d:\n", i);
274 goto Done;
275 }
276 memcpy(obj->b_ptr, *pArgs, dict->size);
277 PyTuple_SET_ITEM(arglist, i, (PyObject *)obj);
278 #ifdef MS_WIN32
279 TryAddRef(dict, obj);
280 #endif
281 } else {
282 PyErr_SetString(PyExc_TypeError,
283 "cannot build parameter");
284 PrintError("Parsing argument %d\n", i);
285 Py_DECREF(cnv);
286 goto Done;
287 }
288 Py_DECREF(cnv);
289 /* XXX error handling! */
290 pArgs++;
291 }
292
293 #define CHECK(what, x) \
294 if (x == NULL) _ctypes_add_traceback(what, "_ctypes/callbacks.c", __LINE__ - 1), PyErr_Print()
295
296 if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) {
297 error_object = _ctypes_get_errobj(&space);
298 if (error_object == NULL)
299 goto Done;
300 if (flags & FUNCFLAG_USE_ERRNO) {
301 int temp = space[0];
302 space[0] = errno;
303 errno = temp;
304 }
305 #ifdef MS_WIN32
306 if (flags & FUNCFLAG_USE_LASTERROR) {
307 int temp = space[1];
308 space[1] = GetLastError();
309 SetLastError(temp);
310 }
311 #endif
312 }
313
314 result = PyObject_CallObject(callable, arglist);
315 CHECK("'calling callback function'", result);
316
317 #ifdef MS_WIN32
318 if (flags & FUNCFLAG_USE_LASTERROR) {
319 int temp = space[1];
320 space[1] = GetLastError();
321 SetLastError(temp);
322 }
323 #endif
324 if (flags & FUNCFLAG_USE_ERRNO) {
325 int temp = space[0];
(emitted by clang-analyzer)TODO: a detailed trace is available in the data model (not yet rendered in this report)
(emitted by clang-analyzer)TODO: a detailed trace is available in the data model (not yet rendered in this report)
326 space[0] = errno;
327 errno = temp;
328 }
329 Py_XDECREF(error_object);
330
331 if ((restype != &ffi_type_void) && result) {
332 PyObject *keep;
333 assert(setfunc);
334 #ifdef WORDS_BIGENDIAN
335 /* See the corresponding code in callproc.c, around line 961 */
336 if (restype->type != FFI_TYPE_FLOAT && restype->size < sizeof(ffi_arg))
337 mem = (char *)mem + sizeof(ffi_arg) - restype->size;
338 #endif
339 keep = setfunc(mem, result, 0);
340 CHECK("'converting callback result'", keep);
341 /* keep is an object we have to keep alive so that the result
342 stays valid. If there is no such object, the setfunc will
343 have returned Py_None.
344
345 If there is such an object, we have no choice than to keep
346 it alive forever - but a refcount and/or memory leak will
347 be the result. EXCEPT when restype is py_object - Python
348 itself knows how to manage the refcount of these objects.
349 */
350 if (keep == NULL) /* Could not convert callback result. */
351 PyErr_WriteUnraisable(callable);
352 else if (keep == Py_None) /* Nothing to keep */
353 Py_DECREF(keep);
354 else if (setfunc != _ctypes_get_fielddesc("O")->setfunc) {
355 if (-1 == PyErr_Warn(PyExc_RuntimeWarning,
356 "memory leak in callback function."))
357 PyErr_WriteUnraisable(callable);
358 }
359 }
360 Py_XDECREF(result);
361 Done:
362 Py_XDECREF(arglist);
363 #ifdef WITH_THREAD
364 PyGILState_Release(state);
365 #endif
366 }
367
368 static void closure_fcn(ffi_cif *cif,
369 void *resp,
370 void **args,
371 void *userdata)
372 {
373 CThunkObject *p = (CThunkObject *)userdata;
374
375 _CallPythonObject(resp,
376 p->ffi_restype,
377 p->setfunc,
378 p->callable,
379 p->converters,
380 p->flags,
381 args);
382 }
383
384 static CThunkObject* CThunkObject_new(Py_ssize_t nArgs)
385 {
386 CThunkObject *p;
387 int i;
388
389 p = PyObject_GC_NewVar(CThunkObject, &PyCThunk_Type, nArgs);
390 if (p == NULL) {
391 PyErr_NoMemory();
392 return NULL;
393 }
394
395 p->pcl_exec = NULL;
396 p->pcl_write = NULL;
397 memset(&p->cif, 0, sizeof(p->cif));
398 p->converters = NULL;
399 p->callable = NULL;
400 p->setfunc = NULL;
401 p->ffi_restype = NULL;
402
403 for (i = 0; i < nArgs + 1; ++i)
404 p->atypes[i] = NULL;
405 PyObject_GC_Track((PyObject *)p);
406 return p;
407 }
408
409 CThunkObject *_ctypes_alloc_callback(PyObject *callable,
410 PyObject *converters,
411 PyObject *restype,
412 int flags)
413 {
414 int result;
415 CThunkObject *p;
416 Py_ssize_t nArgs, i;
417 ffi_abi cc;
418
419 nArgs = PySequence_Size(converters);
420 p = CThunkObject_new(nArgs);
421 if (p == NULL)
422 return NULL;
423
424 assert(CThunk_CheckExact(p));
425
426 p->pcl_write = ffi_closure_alloc(sizeof(ffi_closure),
427 &p->pcl_exec);
428 if (p->pcl_write == NULL) {
429 PyErr_NoMemory();
430 goto error;
431 }
432
433 p->flags = flags;
434 for (i = 0; i < nArgs; ++i) {
435 PyObject *cnv = PySequence_GetItem(converters, i);
436 if (cnv == NULL)
437 goto error;
438 p->atypes[i] = _ctypes_get_ffi_type(cnv);
439 Py_DECREF(cnv);
440 }
441 p->atypes[i] = NULL;
442
443 Py_INCREF(restype);
444 p->restype = restype;
445 if (restype == Py_None) {
446 p->setfunc = NULL;
447 p->ffi_restype = &ffi_type_void;
448 } else {
449 StgDictObject *dict = PyType_stgdict(restype);
450 if (dict == NULL || dict->setfunc == NULL) {
451 PyErr_SetString(PyExc_TypeError,
452 "invalid result type for callback function");
453 goto error;
454 }
455 p->setfunc = dict->setfunc;
456 p->ffi_restype = &dict->ffi_type_pointer;
457 }
458
459 cc = FFI_DEFAULT_ABI;
460 #if defined(MS_WIN32) && !defined(_WIN32_WCE) && !defined(MS_WIN64)
461 if ((flags & FUNCFLAG_CDECL) == 0)
462 cc = FFI_STDCALL;
463 #endif
464 result = ffi_prep_cif(&p->cif, cc,
465 Py_SAFE_DOWNCAST(nArgs, Py_ssize_t, int),
466 _ctypes_get_ffi_type(restype),
467 &p->atypes[0]);
468 if (result != FFI_OK) {
469 PyErr_Format(PyExc_RuntimeError,
470 "ffi_prep_cif failed with %d", result);
471 goto error;
472 }
473 #if defined(X86_DARWIN) || defined(POWERPC_DARWIN)
474 result = ffi_prep_closure(p->pcl_write, &p->cif, closure_fcn, p);
475 #else
476 result = ffi_prep_closure_loc(p->pcl_write, &p->cif, closure_fcn,
477 p,
478 p->pcl_exec);
479 #endif
480 if (result != FFI_OK) {
481 PyErr_Format(PyExc_RuntimeError,
482 "ffi_prep_closure failed with %d", result);
483 goto error;
484 }
485
486 Py_INCREF(converters);
487 p->converters = converters;
488 Py_INCREF(callable);
489 p->callable = callable;
490 return p;
491
492 error:
493 Py_XDECREF(p);
494 return NULL;
495 }
496
497 #ifdef MS_WIN32
498
499 static void LoadPython(void)
500 {
501 if (!Py_IsInitialized()) {
502 #ifdef WITH_THREAD
503 PyEval_InitThreads();
504 #endif
505 Py_Initialize();
506 }
507 }
508
509 /******************************************************************/
510
511 long Call_GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
512 {
513 PyObject *mod, *func, *result;
514 long retval;
515 static PyObject *context;
516
517 if (context == NULL)
518 context = PyString_InternFromString("_ctypes.DllGetClassObject");
519
520 mod = PyImport_ImportModuleNoBlock("ctypes");
521 if (!mod) {
522 PyErr_WriteUnraisable(context ? context : Py_None);
523 /* There has been a warning before about this already */
524 return E_FAIL;
525 }
526
527 func = PyObject_GetAttrString(mod, "DllGetClassObject");
528 Py_DECREF(mod);
529 if (!func) {
530 PyErr_WriteUnraisable(context ? context : Py_None);
531 return E_FAIL;
532 }
533
534 {
535 PyObject *py_rclsid = PyLong_FromVoidPtr((void *)rclsid);
536 PyObject *py_riid = PyLong_FromVoidPtr((void *)riid);
537 PyObject *py_ppv = PyLong_FromVoidPtr(ppv);
538 if (!py_rclsid || !py_riid || !py_ppv) {
539 Py_XDECREF(py_rclsid);
540 Py_XDECREF(py_riid);
541 Py_XDECREF(py_ppv);
542 Py_DECREF(func);
543 PyErr_WriteUnraisable(context ? context : Py_None);
544 return E_FAIL;
545 }
546 result = PyObject_CallFunctionObjArgs(func,
547 py_rclsid,
548 py_riid,
549 py_ppv,
550 NULL);
551 Py_DECREF(py_rclsid);
552 Py_DECREF(py_riid);
553 Py_DECREF(py_ppv);
554 }
555 Py_DECREF(func);
556 if (!result) {
557 PyErr_WriteUnraisable(context ? context : Py_None);
558 return E_FAIL;
559 }
560
561 retval = PyInt_AsLong(result);
562 if (PyErr_Occurred()) {
563 PyErr_WriteUnraisable(context ? context : Py_None);
564 retval = E_FAIL;
565 }
566 Py_DECREF(result);
567 return retval;
568 }
569
570 STDAPI DllGetClassObject(REFCLSID rclsid,
571 REFIID riid,
572 LPVOID *ppv)
573 {
574 long result;
575 #ifdef WITH_THREAD
576 PyGILState_STATE state;
577 #endif
578
579 LoadPython();
580 #ifdef WITH_THREAD
581 state = PyGILState_Ensure();
582 #endif
583 result = Call_GetClassObject(rclsid, riid, ppv);
584 #ifdef WITH_THREAD
585 PyGILState_Release(state);
586 #endif
587 return result;
588 }
589
590 long Call_CanUnloadNow(void)
591 {
592 PyObject *mod, *func, *result;
593 long retval;
594 static PyObject *context;
595
596 if (context == NULL)
597 context = PyString_InternFromString("_ctypes.DllCanUnloadNow");
598
599 mod = PyImport_ImportModuleNoBlock("ctypes");
600 if (!mod) {
601 /* OutputDebugString("Could not import ctypes"); */
602 /* We assume that this error can only occur when shutting
603 down, so we silently ignore it */
604 PyErr_Clear();
605 return E_FAIL;
606 }
607 /* Other errors cannot be raised, but are printed to stderr */
608 func = PyObject_GetAttrString(mod, "DllCanUnloadNow");
609 Py_DECREF(mod);
610 if (!func) {
611 PyErr_WriteUnraisable(context ? context : Py_None);
612 return E_FAIL;
613 }
614
615 result = PyObject_CallFunction(func, NULL);
616 Py_DECREF(func);
617 if (!result) {
618 PyErr_WriteUnraisable(context ? context : Py_None);
619 return E_FAIL;
620 }
621
622 retval = PyInt_AsLong(result);
623 if (PyErr_Occurred()) {
624 PyErr_WriteUnraisable(context ? context : Py_None);
625 retval = E_FAIL;
626 }
627 Py_DECREF(result);
628 return retval;
629 }
630
631 /*
632 DllRegisterServer and DllUnregisterServer still missing
633 */
634
635 STDAPI DllCanUnloadNow(void)
636 {
637 long result;
638 #ifdef WITH_THREAD
639 PyGILState_STATE state = PyGILState_Ensure();
640 #endif
641 result = Call_CanUnloadNow();
642 #ifdef WITH_THREAD
643 PyGILState_Release(state);
644 #endif
645 return result;
646 }
647
648 #ifndef Py_NO_ENABLE_SHARED
649 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvRes)
650 {
651 switch(fdwReason) {
652 case DLL_PROCESS_ATTACH:
653 DisableThreadLibraryCalls(hinstDLL);
654 break;
655 }
656 return TRUE;
657 }
658 #endif
659
660 #endif
661
662 /*
663 Local Variables:
664 compile-command: "cd .. && python setup.py -q build_ext"
665 End:
666 */