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
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | #include "../libImaging/Imaging.h" |
43 | #include "_tkmini.h" |
44 | |
45 | #include <stdlib.h> |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | static int TK_LT_85 = 0; |
52 | static Tcl_CreateCommand_t TCL_CREATE_COMMAND; |
53 | static Tcl_AppendResult_t TCL_APPEND_RESULT; |
54 | static Tk_FindPhoto_t TK_FIND_PHOTO; |
55 | static Tk_PhotoGetImage_t TK_PHOTO_GET_IMAGE; |
56 | static Tk_PhotoPutBlock_84_t TK_PHOTO_PUT_BLOCK_84; |
57 | static Tk_PhotoSetSize_84_t TK_PHOTO_SET_SIZE_84; |
58 | static Tk_PhotoPutBlock_85_t TK_PHOTO_PUT_BLOCK_85; |
59 | |
60 | static Imaging |
61 | ImagingFind(const char *name) { |
62 | Py_ssize_t id; |
63 | |
64 | |
65 | #if defined(_WIN64) |
66 | id = _atoi64(name); |
67 | #else |
68 | id = atol(name); |
69 | #endif |
70 | if (!id) { |
71 | return NULL; |
72 | } |
73 | |
74 | return (Imaging)id; |
75 | } |
76 | |
77 | static int |
78 | PyImagingPhotoPut( |
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); |
87 | return TCL_ERROR; |
88 | } |
89 | |
90 | |
91 | photo = TK_FIND_PHOTO(interp, argv[1]); |
92 | if (photo == NULL) { |
93 | TCL_APPEND_RESULT(interp, "destination photo must exist", (char *)NULL); |
94 | return TCL_ERROR; |
95 | } |
96 | |
97 | |
98 | im = ImagingFind(argv[2]); |
99 | if (!im) { |
100 | TCL_APPEND_RESULT(interp, "bad name", (char *)NULL); |
101 | return TCL_ERROR; |
102 | } |
103 | if (!im->block) { |
104 | TCL_APPEND_RESULT(interp, "bad display memory", (char *)NULL); |
105 | return TCL_ERROR; |
106 | } |
107 | |
108 | |
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; |
120 | } else { |
121 | block.offset[3] = 0; |
122 | } |
123 | } else { |
124 | TCL_APPEND_RESULT(interp, "Bad mode", (char *)NULL); |
125 | return TCL_ERROR; |
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) { |
134 | TK_PHOTO_PUT_BLOCK_84( |
135 | photo, &block, 0, 0, block.width, block.height, TK_PHOTO_COMPOSITE_SET); |
136 | if (strcmp(im->mode, "RGBA") == 0) { |
137 | |
138 | |
139 | TK_PHOTO_SET_SIZE_84(photo, block.width, block.height); |
140 | } |
141 | } else { |
142 | |
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_SET); |
152 | } |
153 | |
154 | return TCL_OK; |
155 | } |
156 | |
157 | static int |
158 | PyImagingPhotoGet( |
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); |
168 | return TCL_ERROR; |
169 | } |
170 | |
171 | |
172 | photo = TK_FIND_PHOTO(interp, argv[1]); |
173 | if (photo == NULL) { |
174 | TCL_APPEND_RESULT(interp, "source photo must exist", (char *)NULL); |
175 | return TCL_ERROR; |
176 | } |
177 | |
178 | |
179 | im = ImagingFind(argv[2]); |
180 | if (!im) { |
181 | TCL_APPEND_RESULT(interp, "bad name", (char *)NULL); |
182 | return TCL_ERROR; |
183 | } |
184 | |
185 | TK_PHOTO_GET_IMAGE(photo, &block); |
186 | |
187 | for (y = 0; y < block.height; y++) { |
188 | UINT8 *out = (UINT8 *)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_OK; |
198 | } |
199 | |
200 | void |
201 | TkImaging_Init(Tcl_Interp *interp) { |
202 | TCL_CREATE_COMMAND( |
203 | interp, |
204 | "PyImagingPhoto", |
205 | PyImagingPhotoPut, |
206 | (ClientData)0, |
207 | (Tcl_CmdDeleteProc *)NULL); |
208 | TCL_CREATE_COMMAND( |
209 | interp, |
210 | "PyImagingPhotoGet", |
211 | PyImagingPhotoGet, |
212 | (ClientData)0, |
213 | (Tcl_CmdDeleteProc *)NULL); |
214 | } |
215 | |
216 | |
217 | |
218 | |
219 | |
220 | #define TKINTER_FINDER "PIL._tkinter_finder" |
221 | |
222 | #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) |
223 | |
224 | |
225 | |
226 | |
227 | |
228 | |
229 | |
230 | |
231 | #include <windows.h> |
232 | #define PSAPI_VERSION 1 |
233 | #include <psapi.h> |
234 | |
235 | |
236 | #define TKINTER_PKG "tkinter" |
237 | |
238 | FARPROC |
239 | _dfunc(HMODULE lib_handle, const char *func_name) { |
240 | |
241 | |
242 | |
243 | |
244 | |
245 | |
246 | char message[100]; |
247 | |
248 | FARPROC func = GetProcAddress(lib_handle, func_name); |
249 | if (func == NULL) { |
250 | sprintf(message, "Cannot load function %s", func_name); |
251 | PyErr_SetString(PyExc_RuntimeError, message); |
252 | } |
253 | return func; |
254 | } |
255 | |
256 | int |
257 | get_tcl(HMODULE hMod) { |
258 | |
259 | |
260 | |
261 | |
262 | |
263 | |
264 | if ((TCL_CREATE_COMMAND = |
265 | (Tcl_CreateCommand_t)GetProcAddress(hMod, "Tcl_CreateCommand")) == NULL) { |
266 | return 0; |
267 | } |
268 | return ((TCL_APPEND_RESULT = |
269 | (Tcl_AppendResult_t)_dfunc(hMod, "Tcl_AppendResult")) == NULL) |
270 | ? -1 |
271 | : 1; |
272 | } |
273 | |
274 | int |
275 | get_tk(HMODULE hMod) { |
276 | |
277 | |
278 | |
279 | |
280 | |
281 | |
282 | FARPROC func = GetProcAddress(hMod, "Tk_PhotoPutBlock"); |
283 | if (func == NULL) { |
284 | return 0; |
285 | } |
286 | if ((TK_PHOTO_GET_IMAGE = (Tk_PhotoGetImage_t)_dfunc(hMod, "Tk_PhotoGetImage")) == |
287 | NULL) { |
288 | return -1; |
289 | }; |
290 | if ((TK_FIND_PHOTO = (Tk_FindPhoto_t)_dfunc(hMod, "Tk_FindPhoto")) == NULL) { |
291 | return -1; |
292 | }; |
293 | TK_LT_85 = GetProcAddress(hMod, "Tk_PhotoPutBlock_Panic") == NULL; |
294 | |
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) |
299 | ? -1 |
300 | : 1; |
301 | } |
302 | TK_PHOTO_PUT_BLOCK_85 = (Tk_PhotoPutBlock_85_t)func; |
303 | return 1; |
304 | } |
305 | |
306 | int |
307 | load_tkinter_funcs(void) { |
308 | |
309 | |
310 | |
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 | |
321 | PyObject *pModule = PyImport_ImportModule(TKINTER_PKG); |
322 | if (pModule == NULL) { |
323 | return 1; |
324 | } |
325 | Py_DECREF(pModule); |
326 | |
327 | |
328 | hProcess = GetCurrentProcess(); |
329 | |
330 | |
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 | |
363 | |
364 | |
365 | |
366 | |
367 | |
368 | char * |
369 | fname2char(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) { |
| 10 | | Assuming 'bytes' is not equal to NULL | |
|
| |
373 | return NULL; |
374 | } |
375 | return PyBytes_AsString(bytes); |
376 | } |
377 | |
378 | #include <dlfcn.h> |
379 | |
380 | void * |
381 | _dfunc(void *lib_handle, const char *func_name) { |
382 | |
383 | |
384 | |
385 | |
386 | |
387 | |
388 | void *func; |
389 | |
390 | dlerror(); |
391 | func = dlsym(lib_handle, func_name); |
392 | if (func == NULL) { |
393 | const char *error = dlerror(); |
394 | PyErr_SetString(PyExc_RuntimeError, error); |
395 | } |
396 | return func; |
397 | } |
398 | |
399 | int |
400 | _func_loader(void *lib) { |
401 | |
402 | |
403 | |
404 | |
405 | |
406 | if ((TCL_CREATE_COMMAND = (Tcl_CreateCommand_t)_dfunc(lib, "Tcl_CreateCommand")) == |
407 | NULL) { |
408 | return 1; |
409 | } |
410 | if ((TCL_APPEND_RESULT = (Tcl_AppendResult_t)_dfunc(lib, "Tcl_AppendResult")) == |
411 | NULL) { |
412 | return 1; |
413 | } |
414 | if ((TK_PHOTO_GET_IMAGE = (Tk_PhotoGetImage_t)_dfunc(lib, "Tk_PhotoGetImage")) == |
415 | NULL) { |
416 | return 1; |
417 | } |
418 | if ((TK_FIND_PHOTO = (Tk_FindPhoto_t)_dfunc(lib, "Tk_FindPhoto")) == NULL) { |
419 | return 1; |
420 | } |
421 | |
422 | TK_LT_85 = (dlsym(lib, "Tk_PhotoPutBlock_Panic") == NULL); |
423 | if (TK_LT_85) { |
424 | return ( |
425 | ((TK_PHOTO_PUT_BLOCK_84 = |
426 | (Tk_PhotoPutBlock_84_t)_dfunc(lib, "Tk_PhotoPutBlock")) == NULL) || |
427 | ((TK_PHOTO_SET_SIZE_84 = |
428 | (Tk_PhotoSetSize_84_t)_dfunc(lib, "Tk_PhotoSetSize")) == NULL)); |
429 | } |
430 | return ( |
431 | (TK_PHOTO_PUT_BLOCK_85 = |
432 | (Tk_PhotoPutBlock_85_t)_dfunc(lib, "Tk_PhotoPutBlock")) == NULL); |
433 | } |
434 | |
435 | int |
436 | load_tkinter_funcs(void) { |
437 | |
438 | |
439 | |
440 | |
441 | |
442 | int ret = -1; |
443 | void *main_program, *tkinter_lib; |
444 | char *tkinter_libname; |
445 | PyObject *pModule = NULL, *pString = NULL; |
446 | |
447 | |
448 | main_program = dlopen(NULL, RTLD_LAZY); |
449 | if (_func_loader(main_program) == 0) { |
| |
450 | dlclose(main_program); |
451 | return 0; |
452 | } |
453 | |
454 | PyErr_Clear(); |
455 | |
456 | |
457 | pModule = PyImport_ImportModule(TKINTER_FINDER); |
458 | if (pModule == NULL) { |
| 2 | | Assuming 'pModule' is not equal to NULL | |
|
| |
459 | goto exit; |
460 | } |
461 | pString = PyObject_GetAttrString(pModule, "TKINTER_LIB"); |
462 | if (pString == NULL) { |
| 4 | | Assuming 'pString' is not equal to NULL | |
|
| |
463 | goto exit; |
464 | } |
465 | tkinter_libname = fname2char(pString); |
| |
466 | if (tkinter_libname == NULL) { |
467 | goto exit; |
468 | } |
469 | tkinter_lib = dlopen(tkinter_libname, RTLD_LAZY); |
470 | if (tkinter_lib == NULL) { |
471 | PyErr_SetString(PyExc_RuntimeError, "Cannot dlopen tkinter module file"); |
472 | goto exit; |
473 | } |
474 | ret = _func_loader(tkinter_lib); |
475 | |
476 | dlclose(tkinter_lib); |
477 | exit: |
478 | dlclose(main_program); |
479 | Py_XDECREF(pModule); |
480 | Py_XDECREF(pString); |
481 | return ret; |
482 | } |
483 | #endif /* end not Windows */ |