| 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 */