Python-2.7.3/Modules/_ctypes/callbacks.c

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];
Dereference of undefined pointer value
(emitted by clang-analyzer)

TODO: a detailed trace is available in the data model (not yet rendered in this report)

Dereference of undefined pointer value
(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 */