Bug Summary

File:Tk/tkImaging.c
Warning:line 371, column 13
PyObject ownership leak with reference count of 1

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name tkImaging.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -analyzer-output=html -analyzer-checker=python -analyzer-disable-checker=deadcode -analyzer-config prune-paths=true,suppress-c++-stdlib=true,suppress-null-return-paths=false,crosscheck-with-z3=true,model-path=/opt/pyrefcon/lib/pyrefcon/models/models -analyzer-config experimental-enable-naive-ctu-analysis=true,ctu-dir=/tmp/pyrefcon/Pillow/csa-scan,ctu-index-name=/tmp/pyrefcon/Pillow/csa-scan/externalDefMap.txt,ctu-invocation-list=/tmp/pyrefcon/Pillow/csa-scan/invocations.yaml,display-ctu-progress=false -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debug-info-kind=limited -dwarf-version=4 -debugger-tuning=gdb -fcoverage-compilation-dir=/tmp/pyrefcon/Pillow -resource-dir /opt/pyrefcon/lib/clang/13.0.0 -isystem /opt/pyrefcon/lib/pyrefcon/models/python3.8 -D NDEBUG -D _FORTIFY_SOURCE=2 -I /usr/include/freetype2 -I /usr/include/openjpeg-2.3 -I /tmp/pyrefcon/Pillow -I /usr/include/x86_64-linux-gnu -I /usr/include/fribidi -I /usr/include -internal-isystem /opt/pyrefcon/lib/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-result -Wsign-compare -Wall -Wformat -Werror=format-security -Wformat -Werror=format-security -Wdate-time -fdebug-compilation-dir=/tmp/pyrefcon/Pillow -ferror-limit 19 -fwrapv -pthread -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/pyrefcon/Pillow/csa-scan/reports -x c src/Tk/tkImaging.c

src/Tk/tkImaging.c

1/*
2 * The Python Imaging Library.
3 * $Id$
4 *
5 * TK interface for Python Imaging objects
6 *
7 * Copies (parts of) a named display memory to a photo image object.
8 * Also contains code to create an display memory. Under Tk, a
9 * display memory is simply an "L" or "RGB" image memory that is
10 * allocated in a single block.
11 *
12 * To use this module, import the _imagingtk module (ImageTk does
13 * this for you).
14 *
15 * If you're using Python in an embedded context, you can add the
16 * following lines to your Tcl_AppInit function (in tkappinit.c)
17 * instead. Put them after the calls to Tcl_Init and Tk_Init:
18 *
19 * {
20 * extern void TkImaging_Init(Tcl_Interp* interp);
21 * TkImaging_Init(interp);
22 * }
23 *
24 * This registers a Tcl command called "PyImagingPhoto", which is used
25 * to communicate between PIL and Tk's PhotoImage handler.
26 *
27
28 * History:
29 * 1995-09-12 fl Created
30 * 1996-04-08 fl Ready for release
31 * 1997-05-09 fl Use command instead of image type
32 * 2001-03-18 fl Initialize alpha layer pointer (struct changed in 8.3)
33 * 2003-04-23 fl Fixed building for Tk 8.4.1 and later (Jack Jansen)
34 * 2004-06-24 fl Fixed building for Tk 8.4.6 and later.
35 *
36 * Copyright (c) 1997-2004 by Secret Labs AB
37 * Copyright (c) 1995-2004 by Fredrik Lundh
38 *
39 * See the README file for information on usage and redistribution.
40 */
41
42#include "../libImaging/Imaging.h"
43#include "_tkmini.h"
44
45#include <stdlib.h>
46
47/*
48 * Global vars for Tcl / Tk functions. We load these symbols from the tkinter
49 * extension module or loaded Tcl / Tk libraries at run-time.
50 */
51static int TK_LT_85 = 0;
52static Tcl_CreateCommand_t TCL_CREATE_COMMAND;
53static Tcl_AppendResult_t TCL_APPEND_RESULT;
54static Tk_FindPhoto_t TK_FIND_PHOTO;
55static Tk_PhotoGetImage_t TK_PHOTO_GET_IMAGE;
56static Tk_PhotoPutBlock_84_t TK_PHOTO_PUT_BLOCK_84;
57static Tk_PhotoSetSize_84_t TK_PHOTO_SET_SIZE_84;
58static Tk_PhotoPutBlock_85_t TK_PHOTO_PUT_BLOCK_85;
59
60static Imaging
61ImagingFind(const char *name) {
62 Py_ssize_t id;
63
64 /* FIXME: use CObject instead? */
65#if defined(_WIN64)
66 id = _atoi64(name);
67#else
68 id = atol(name);
69#endif
70 if (!id) {
71 return NULL((void*)0);
72 }
73
74 return (Imaging)id;
75}
76
77static int
78PyImagingPhotoPut(
79 ClientData clientdata, Tcl_Interp *interp, int argc, const char **argv) {
80 Imaging im;
81 Tk_PhotoHandle photo;
82 Tk_PhotoImageBlock block;
83
84 if (argc != 3) {
85 TCL_APPEND_RESULT(
86 interp, "usage: ", argv[0], " destPhoto srcImage", (char *)NULL((void*)0));
87 return TCL_ERROR1;
88 }
89
90 /* get Tcl PhotoImage handle */
91 photo = TK_FIND_PHOTO(interp, argv[1]);
92 if (photo == NULL((void*)0)) {
93 TCL_APPEND_RESULT(interp, "destination photo must exist", (char *)NULL((void*)0));
94 return TCL_ERROR1;
95 }
96
97 /* get PIL Image handle */
98 im = ImagingFind(argv[2]);
99 if (!im) {
100 TCL_APPEND_RESULT(interp, "bad name", (char *)NULL((void*)0));
101 return TCL_ERROR1;
102 }
103 if (!im->block) {
104 TCL_APPEND_RESULT(interp, "bad display memory", (char *)NULL((void*)0));
105 return TCL_ERROR1;
106 }
107
108 /* Mode */
109
110 if (strcmp(im->mode, "1") == 0 || strcmp(im->mode, "L") == 0) {
111 block.pixelSize = 1;
112 block.offset[0] = block.offset[1] = block.offset[2] = block.offset[3] = 0;
113 } else if (strncmp(im->mode, "RGB", 3) == 0) {
114 block.pixelSize = 4;
115 block.offset[0] = 0;
116 block.offset[1] = 1;
117 block.offset[2] = 2;
118 if (strcmp(im->mode, "RGBA") == 0) {
119 block.offset[3] = 3; /* alpha (or reserved, under 8.2) */
120 } else {
121 block.offset[3] = 0; /* no alpha */
122 }
123 } else {
124 TCL_APPEND_RESULT(interp, "Bad mode", (char *)NULL((void*)0));
125 return TCL_ERROR1;
126 }
127
128 block.width = im->xsize;
129 block.height = im->ysize;
130 block.pitch = im->linesize;
131 block.pixelPtr = (unsigned char *)im->block;
132
133 if (TK_LT_85) { /* Tk 8.4 */
134 TK_PHOTO_PUT_BLOCK_84(
135 photo, &block, 0, 0, block.width, block.height, TK_PHOTO_COMPOSITE_SET1);
136 if (strcmp(im->mode, "RGBA") == 0) {
137 /* Tk workaround: we need apply ToggleComplexAlphaIfNeeded */
138 /* (fixed in Tk 8.5a3) */
139 TK_PHOTO_SET_SIZE_84(photo, block.width, block.height);
140 }
141 } else {
142 /* Tk >=8.5 */
143 TK_PHOTO_PUT_BLOCK_85(
144 interp,
145 photo,
146 &block,
147 0,
148 0,
149 block.width,
150 block.height,
151 TK_PHOTO_COMPOSITE_SET1);
152 }
153
154 return TCL_OK0;
155}
156
157static int
158PyImagingPhotoGet(
159 ClientData clientdata, Tcl_Interp *interp, int argc, const char **argv) {
160 Imaging im;
161 Tk_PhotoHandle photo;
162 Tk_PhotoImageBlock block;
163 int x, y, z;
164
165 if (argc != 3) {
166 TCL_APPEND_RESULT(
167 interp, "usage: ", argv[0], " srcPhoto destImage", (char *)NULL((void*)0));
168 return TCL_ERROR1;
169 }
170
171 /* get Tcl PhotoImage handle */
172 photo = TK_FIND_PHOTO(interp, argv[1]);
173 if (photo == NULL((void*)0)) {
174 TCL_APPEND_RESULT(interp, "source photo must exist", (char *)NULL((void*)0));
175 return TCL_ERROR1;
176 }
177
178 /* get PIL Image handle */
179 im = ImagingFind(argv[2]);
180 if (!im) {
181 TCL_APPEND_RESULT(interp, "bad name", (char *)NULL((void*)0));
182 return TCL_ERROR1;
183 }
184
185 TK_PHOTO_GET_IMAGE(photo, &block);
186
187 for (y = 0; y < block.height; y++) {
188 UINT8unsigned char *out = (UINT8unsigned char *)im->image32[y];
189 for (x = 0; x < block.pitch; x += block.pixelSize) {
190 for (z = 0; z < block.pixelSize; z++) {
191 int offset = block.offset[z];
192 out[x + offset] = block.pixelPtr[y * block.pitch + x + offset];
193 }
194 }
195 }
196
197 return TCL_OK0;
198}
199
200void
201TkImaging_Init(Tcl_Interp *interp) {
202 TCL_CREATE_COMMAND(
203 interp,
204 "PyImagingPhoto",
205 PyImagingPhotoPut,
206 (ClientData)0,
207 (Tcl_CmdDeleteProc *)NULL((void*)0));
208 TCL_CREATE_COMMAND(
209 interp,
210 "PyImagingPhotoGet",
211 PyImagingPhotoGet,
212 (ClientData)0,
213 (Tcl_CmdDeleteProc *)NULL((void*)0));
214}
215
216/*
217 * Functions to fill global Tcl / Tk function pointers by dynamic loading
218 */
219
220#define TKINTER_FINDER"PIL._tkinter_finder" "PIL._tkinter_finder"
221
222#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
223
224/*
225 * On Windows, we can't load the tkinter module to get the Tcl or Tk symbols,
226 * because Windows does not load symbols into the library name-space of
227 * importing modules. So, knowing that tkinter has already been imported by
228 * Python, we scan all modules in the running process for the Tcl and Tk
229 * function names.
230 */
231#include <windows.h>
232#define PSAPI_VERSION 1
233#include <psapi.h>
234/* Must be linked with 'psapi' library */
235
236#define TKINTER_PKG "tkinter"
237
238FARPROC
239_dfunc(HMODULE lib_handle, const char *func_name) {
240 /*
241 * Load function `func_name` from `lib_handle`.
242 * Set Python exception if we can't find `func_name` in `lib_handle`.
243 * Returns function pointer or NULL if not present.
244 */
245
246 char message[100];
247
248 FARPROC func = GetProcAddress(lib_handle, func_name);
249 if (func == NULL((void*)0)) {
250 sprintf(message, "Cannot load function %s", func_name)__builtin___sprintf_chk (message, 2 - 1, __builtin_object_size
(message, 2 > 1), "Cannot load function %s", func_name)
;
251 PyErr_SetString(PyExc_RuntimeError, message);
252 }
253 return func;
254}
255
256int
257get_tcl(HMODULE hMod) {
258 /*
259 * Try to fill Tcl global vars with function pointers. Return 0 for no
260 * functions found, 1 for all functions found, -1 for some but not all
261 * functions found.
262 */
263
264 if ((TCL_CREATE_COMMAND =
265 (Tcl_CreateCommand_t)GetProcAddress(hMod, "Tcl_CreateCommand")) == NULL((void*)0)) {
266 return 0; /* Maybe not Tcl module */
267 }
268 return ((TCL_APPEND_RESULT =
269 (Tcl_AppendResult_t)_dfunc(hMod, "Tcl_AppendResult")) == NULL((void*)0))
270 ? -1
271 : 1;
272}
273
274int
275get_tk(HMODULE hMod) {
276 /*
277 * Try to fill Tk global vars with function pointers. Return 0 for no
278 * functions found, 1 for all functions found, -1 for some but not all
279 * functions found.
280 */
281
282 FARPROC func = GetProcAddress(hMod, "Tk_PhotoPutBlock");
283 if (func == NULL((void*)0)) { /* Maybe not Tk module */
284 return 0;
285 }
286 if ((TK_PHOTO_GET_IMAGE = (Tk_PhotoGetImage_t)_dfunc(hMod, "Tk_PhotoGetImage")) ==
287 NULL((void*)0)) {
288 return -1;
289 };
290 if ((TK_FIND_PHOTO = (Tk_FindPhoto_t)_dfunc(hMod, "Tk_FindPhoto")) == NULL((void*)0)) {
291 return -1;
292 };
293 TK_LT_85 = GetProcAddress(hMod, "Tk_PhotoPutBlock_Panic") == NULL((void*)0);
294 /* Tk_PhotoPutBlock_Panic defined as of 8.5.0 */
295 if (TK_LT_85) {
296 TK_PHOTO_PUT_BLOCK_84 = (Tk_PhotoPutBlock_84_t)func;
297 return ((TK_PHOTO_SET_SIZE_84 =
298 (Tk_PhotoSetSize_84_t)_dfunc(hMod, "Tk_PhotoSetSize")) == NULL((void*)0))
299 ? -1
300 : 1;
301 }
302 TK_PHOTO_PUT_BLOCK_85 = (Tk_PhotoPutBlock_85_t)func;
303 return 1;
304}
305
306int
307load_tkinter_funcs(void) {
308 /*
309 * Load Tcl and Tk functions by searching all modules in current process.
310 * Return 0 for success, non-zero for failure.
311 */
312
313 HMODULE hMods[1024];
314 HANDLE hProcess;
315 DWORD cbNeeded;
316 unsigned int i;
317 int found_tcl = 0;
318 int found_tk = 0;
319
320 /* First load tkinter module to make sure libraries are loaded */
321 PyObject *pModule = PyImport_ImportModule(TKINTER_PKG);
322 if (pModule == NULL((void*)0)) {
323 return 1;
324 }
325 Py_DECREF(pModule)_Py_DECREF(((PyObject*)(pModule)));
326
327 /* Returns pseudo-handle that does not need to be closed */
328 hProcess = GetCurrentProcess();
329
330 /* Iterate through modules in this process looking for Tcl / Tk names */
331 if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) {
332 for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) {
333 if (!found_tcl) {
334 found_tcl = get_tcl(hMods[i]);
335 if (found_tcl == -1) {
336 return 1;
337 }
338 }
339 if (!found_tk) {
340 found_tk = get_tk(hMods[i]);
341 if (found_tk == -1) {
342 return 1;
343 }
344 }
345 if (found_tcl && found_tk) {
346 return 0;
347 }
348 }
349 }
350
351 if (found_tcl == 0) {
352 PyErr_SetString(PyExc_RuntimeError, "Could not find Tcl routines");
353 } else {
354 PyErr_SetString(PyExc_RuntimeError, "Could not find Tk routines");
355 }
356 return 1;
357}
358
359#else /* not Windows */
360
361/*
362 * On Unix, we can get the Tcl and Tk symbols from the tkinter module, because
363 * tkinter uses these symbols, and the symbols are therefore visible in the
364 * tkinter dynamic library (module).
365 */
366
367/* From module __file__ attribute to char *string for dlopen. */
368char *
369fname2char(PyObject *fname) {
370 PyObject *bytes;
371 bytes = PyUnicode_EncodeFSDefault(fname);
7
Calling 'PyUnicode_EncodeFSDefault'
9
Returning from 'PyUnicode_EncodeFSDefault'
12
PyObject ownership leak with reference count of 1
372 if (bytes == NULL((void*)0)) {
10
Assuming 'bytes' is not equal to NULL
11
Taking false branch
373 return NULL((void*)0);
374 }
375 return PyBytes_AsString(bytes);
376}
377
378#include <dlfcn.h>
379
380void *
381_dfunc(void *lib_handle, const char *func_name) {
382 /*
383 * Load function `func_name` from `lib_handle`.
384 * Set Python exception if we can't find `func_name` in `lib_handle`.
385 * Returns function pointer or NULL if not present.
386 */
387
388 void *func;
389 /* Reset errors. */
390 dlerror();
391 func = dlsym(lib_handle, func_name);
392 if (func == NULL((void*)0)) {
393 const char *error = dlerror();
394 PyErr_SetString(PyExc_RuntimeError, error);
395 }
396 return func;
397}
398
399int
400_func_loader(void *lib) {
401 /*
402 * Fill global function pointers from dynamic lib.
403 * Return 1 if any pointer is NULL, 0 otherwise.
404 */
405
406 if ((TCL_CREATE_COMMAND = (Tcl_CreateCommand_t)_dfunc(lib, "Tcl_CreateCommand")) ==
407 NULL((void*)0)) {
408 return 1;
409 }
410 if ((TCL_APPEND_RESULT = (Tcl_AppendResult_t)_dfunc(lib, "Tcl_AppendResult")) ==
411 NULL((void*)0)) {
412 return 1;
413 }
414 if ((TK_PHOTO_GET_IMAGE = (Tk_PhotoGetImage_t)_dfunc(lib, "Tk_PhotoGetImage")) ==
415 NULL((void*)0)) {
416 return 1;
417 }
418 if ((TK_FIND_PHOTO = (Tk_FindPhoto_t)_dfunc(lib, "Tk_FindPhoto")) == NULL((void*)0)) {
419 return 1;
420 }
421 /* Tk_PhotoPutBlock_Panic defined as of 8.5.0 */
422 TK_LT_85 = (dlsym(lib, "Tk_PhotoPutBlock_Panic") == NULL((void*)0));
423 if (TK_LT_85) {
424 return (
425 ((TK_PHOTO_PUT_BLOCK_84 =
426 (Tk_PhotoPutBlock_84_t)_dfunc(lib, "Tk_PhotoPutBlock")) == NULL((void*)0)) ||
427 ((TK_PHOTO_SET_SIZE_84 =
428 (Tk_PhotoSetSize_84_t)_dfunc(lib, "Tk_PhotoSetSize")) == NULL((void*)0)));
429 }
430 return (
431 (TK_PHOTO_PUT_BLOCK_85 =
432 (Tk_PhotoPutBlock_85_t)_dfunc(lib, "Tk_PhotoPutBlock")) == NULL((void*)0));
433}
434
435int
436load_tkinter_funcs(void) {
437 /*
438 * Load tkinter global funcs from tkinter compiled module.
439 * Return 0 for success, non-zero for failure.
440 */
441
442 int ret = -1;
443 void *main_program, *tkinter_lib;
444 char *tkinter_libname;
445 PyObject *pModule = NULL((void*)0), *pString = NULL((void*)0);
446
447 /* Try loading from the main program namespace first */
448 main_program = dlopen(NULL((void*)0), RTLD_LAZY0x00001);
449 if (_func_loader(main_program) == 0) {
1
Taking false branch
450 dlclose(main_program);
451 return 0;
452 }
453 /* Clear exception triggered when we didn't find symbols above */
454 PyErr_Clear();
455
456 /* Now try finding the tkinter compiled module */
457 pModule = PyImport_ImportModule(TKINTER_FINDER"PIL._tkinter_finder");
458 if (pModule == NULL((void*)0)) {
2
Assuming 'pModule' is not equal to NULL
3
Taking false branch
459 goto exit;
460 }
461 pString = PyObject_GetAttrString(pModule, "TKINTER_LIB");
462 if (pString == NULL((void*)0)) {
4
Assuming 'pString' is not equal to NULL
5
Taking false branch
463 goto exit;
464 }
465 tkinter_libname = fname2char(pString);
6
Calling 'fname2char'
466 if (tkinter_libname == NULL((void*)0)) {
467 goto exit;
468 }
469 tkinter_lib = dlopen(tkinter_libname, RTLD_LAZY0x00001);
470 if (tkinter_lib == NULL((void*)0)) {
471 PyErr_SetString(PyExc_RuntimeError, "Cannot dlopen tkinter module file");
472 goto exit;
473 }
474 ret = _func_loader(tkinter_lib);
475 /* dlclose probably safe because tkinter has been imported. */
476 dlclose(tkinter_lib);
477exit:
478 dlclose(main_program);
479 Py_XDECREF(pModule)_Py_XDECREF(((PyObject*)(pModule)));
480 Py_XDECREF(pString)_Py_XDECREF(((PyObject*)(pString)));
481 return ret;
482}
483#endif /* end not Windows */

/opt/pyrefcon/lib/pyrefcon/models/models/PyUnicode_EncodeFSDefault.model

1#ifndef PyUnicode_EncodeFSDefault
2struct _object;
3typedef struct _object PyObject;
4PyObject* clang_analyzer_PyObject_New_Reference();
5PyObject* PyUnicode_EncodeFSDefault(PyObject *unicode) {
6 return clang_analyzer_PyObject_New_Reference();
8
Setting reference count to 1
7}
8#else
9#warning "API PyUnicode_EncodeFSDefault is defined as a macro."
10#endif