Bug Summary

File:_build/../cdk-pixbuf/io-qtif.c
Warning:line 441, column 33
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name io-qtif.c -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 -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/rootdir/_build -fcoverage-compilation-dir=/rootdir/_build -resource-dir /usr/lib/llvm-21/lib/clang/21 -I cdk-pixbuf/libpixbufloader-qtif.so.p -I cdk-pixbuf -I ../cdk-pixbuf -I . -I .. -I /usr/include/libpng16 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/librsvg-2.0 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/glycin-2 -I /usr/include/cairo -I /usr/include/libxml2 -I /usr/include/pango-1.0 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/pixman-1 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -D _FILE_OFFSET_BITS=64 -D _POSIX_C_SOURCE=200809L -D _DEFAULT_SOURCE -D _XOPEN_SOURCE=700 -D HAVE_CONFIG_H=1 -D G_LOG_STRUCTURED=1 -D G_LOG_DOMAIN="CdkPixbuf" -D CDK_PIXBUF_COMPILATION -D CDK_PIXBUF_PREFIX="/usr/local" -D CDK_PIXBUF_LOCALEDIR="/usr/local/share/locale" -D CDK_PIXBUF_LIBDIR="/usr/local/lib/x86_64-linux-gnu" -D CDK_PIXBUF_BINARY_VERSION="2.10.0" -D CDK_PIXBUF_ENABLE_BACKEND -D PIXBUF_LIBDIR="/usr/local/lib/x86_64-linux-gnu/cdk-pixbuf-2.0/2.10.0/loaders" -D BUILT_MODULES_DIR="/rootdir/_build/cdk-pixbuf" -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/15/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-int-conversion -Wno-uninitialized -Wno-discarded-qualifiers -std=gnu99 -ferror-limit 19 -fvisibility=hidden -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker security.ArrayBound -analyzer-checker unix.cstring.NotNullTerminated -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2026-08-29-083513-8035-1 -x c ../cdk-pixbuf/io-qtif.c
1/* -*- mode: C; c-file-style: "linux" -*- */
2/* CdkPixbuf library - QTIF image loader
3 *
4 * This module extracts image data from QTIF format and uses
5 * other CDK pixbuf modules to decode the image data.
6 *
7 * Copyright (C) 2008 Kevin Peng
8 *
9 * Authors: Kevin Peng <kevin@zycomtech.com>
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
23 */
24
25
26#include "config.h"
27#include <errno(*__errno_location ()).h>
28#include <libintl.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <setjmp.h>
33#include <glib/gi18n-lib.h>
34#include "cdk-pixbuf.h"
35
36/***
37 * Definitions
38 */
39/* Read buffer size */
40#define READ_BUFFER_SIZE8192 8192
41
42/* Only allow atom of size up to 10MB. */
43#define ATOM_SIZE_MAX100000000 100000000
44
45/* Aborts after going to through this many atoms. */
46#define QTIF_ATOM_COUNT_MAX10u 10u
47
48/* QTIF static image data tag "idat". */
49#define QTIF_TAG_IDATA0x69646174u 0x69646174u
50
51
52/***
53 * Types
54 */
55/* QTIF State */
56typedef enum {
57 STATE_READY,
58 STATE_DATA,
59 STATE_OTHER
60} QTIFState;
61
62/* QTIF Atom Header */
63typedef struct {
64 guint32 length;
65 guint32 tag;
66} QtHeader;
67
68/* QTIF loader context */
69typedef struct {
70 CdkPixbufLoader *loader;
71 gpointer user_data;
72 QTIFState state;
73 guint32 run_length;
74 gint atom_count;
75
76 guchar header_buffer[sizeof(QtHeader)];
77
78 CdkPixbufModuleSizeFunc size_func;
79 CdkPixbufModulePreparedFunc prepared_func;
80 CdkPixbufModuleUpdatedFunc updated_func;
81 gint cb_prepare_count;
82 gint cb_update_count;
83} QTIFContext;
84
85/***
86 * Local function prototypes
87 */
88static CdkPixbuf *cdk_pixbuf__qtif_image_load (FILE *f, GError **error);
89static gpointer cdk_pixbuf__qtif_image_begin_load (CdkPixbufModuleSizeFunc size_func,
90 CdkPixbufModulePreparedFunc prepared_func,
91 CdkPixbufModuleUpdatedFunc updated_func,
92 gpointer user_data,
93 GError **error);
94static gboolean cdk_pixbuf__qtif_image_stop_load (gpointer context, GError **error);
95static gboolean cdk_pixbuf__qtif_image_load_increment(gpointer context,
96 const guchar *buf, guint size,
97 GError **error);
98static gboolean cdk_pixbuf__qtif_image_create_loader (QTIFContext *context, GError **error);
99static gboolean cdk_pixbuf__qtif_image_free_loader (QTIFContext *context, GError **error);
100
101static void cdk_pixbuf__qtif_cb_size_prepared(CdkPixbufLoader *loader,
102 gint width,
103 gint height,
104 gpointer user_data);
105static void cdk_pixbuf__qtif_cb_area_prepared(CdkPixbufLoader *loader, gpointer user_data);
106static void cdk_pixbuf__qtif_cb_area_updated(CdkPixbufLoader *loader,
107 gint x,
108 gint y,
109 gint width,
110 gint height,
111 gpointer user_data);
112
113/***
114 * Function definitions.
115 */
116
117/* Load QTIF from a file handler. */
118static CdkPixbuf *cdk_pixbuf__qtif_image_load (FILE *f, GError **error)
119{
120 guint count;
121
122 if(f == NULL((void*)0))
123 {
124 g_set_error_literal (error, CDK_PIXBUF_ERRORcdk_pixbuf_error_quark (),
125 CDK_PIXBUF_ERROR_BAD_OPTION,
126 _("Input file descriptor is NULL.")((char *) g_dgettext ("cdk-pixbuf", "Input file descriptor is NULL."
))
);
127 return NULL((void*)0);
128 }
129
130 for(count = QTIF_ATOM_COUNT_MAX10u; count != 0u; count--)
131 {
132 QtHeader hdr;
133 size_t rd;
134
135 /* Read QtHeader. */
136 rd = fread(&hdr, 1, sizeof(QtHeader), f);
137 if(rd != sizeof(QtHeader))
138 {
139 g_set_error_literal(error, CDK_PIXBUF_ERRORcdk_pixbuf_error_quark (),
140 CDK_PIXBUF_ERROR_CORRUPT_IMAGE,
141 _("Failed to read QTIF header")((char *) g_dgettext ("cdk-pixbuf", "Failed to read QTIF header"
))
);
142 return NULL((void*)0);
143 }
144
145 hdr.length = GUINT32_FROM_BE(hdr.length)((((__extension__ ({ guint32 __v, __x = ((guint32) (hdr.length
)); if (__builtin_constant_p (__x)) __v = ((guint32) ( (((guint32
) (__x) & (guint32) 0x000000ffU) << 24) | (((guint32
) (__x) & (guint32) 0x0000ff00U) << 8) | (((guint32
) (__x) & (guint32) 0x00ff0000U) >> 8) | (((guint32
) (__x) & (guint32) 0xff000000U) >> 24))); else __asm__
("bswapl %0" : "=r" (__v) : "0" (__x)); __v; })))))
- sizeof(QtHeader);
146 if(hdr.length > ATOM_SIZE_MAX100000000)
147 {
148 g_set_error(error, CDK_PIXBUF_ERRORcdk_pixbuf_error_quark (),
149 CDK_PIXBUF_ERROR_CORRUPT_IMAGE,
150 ngettext ( "QTIF atom size too large (%d byte)",dcngettext (((void*)0), "QTIF atom size too large (%d byte)",
"QTIF atom size too large (%d bytes)", hdr.length, 5)
151 "QTIF atom size too large (%d bytes)",dcngettext (((void*)0), "QTIF atom size too large (%d byte)",
"QTIF atom size too large (%d bytes)", hdr.length, 5)
152 hdr.length)dcngettext (((void*)0), "QTIF atom size too large (%d byte)",
"QTIF atom size too large (%d bytes)", hdr.length, 5)
,
153 hdr.length);
154 return NULL((void*)0);
155 }
156
157 switch(GUINT32_FROM_BE(hdr.tag)((((__extension__ ({ guint32 __v, __x = ((guint32) (hdr.tag))
; if (__builtin_constant_p (__x)) __v = ((guint32) ( (((guint32
) (__x) & (guint32) 0x000000ffU) << 24) | (((guint32
) (__x) & (guint32) 0x0000ff00U) << 8) | (((guint32
) (__x) & (guint32) 0x00ff0000U) >> 8) | (((guint32
) (__x) & (guint32) 0xff000000U) >> 24))); else __asm__
("bswapl %0" : "=r" (__v) : "0" (__x)); __v; })))))
)
158 {
159 case QTIF_TAG_IDATA0x69646174u: /* "idat" data atom. */
160 {
161 /* Load image using CdkPixbufLoader. */
162 guchar *buf;
163 CdkPixbufLoader *loader;
164 CdkPixbuf *pixbuf = NULL((void*)0);
165 GError *tmp = NULL((void*)0);
166
167 /* Allocate read buffer. */
168 buf = g_try_malloc(READ_BUFFER_SIZE8192);
169 if(buf == NULL((void*)0))
170 {
171 g_set_error(error, CDK_PIXBUF_ERRORcdk_pixbuf_error_quark (),
172 CDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
173 ngettext ( "Failed to allocate %d byte for file read buffer",dcngettext (((void*)0), "Failed to allocate %d byte for file read buffer"
, "Failed to allocate %d bytes for file read buffer", 8192, 5
)
174 "Failed to allocate %d bytes for file read buffer",dcngettext (((void*)0), "Failed to allocate %d byte for file read buffer"
, "Failed to allocate %d bytes for file read buffer", 8192, 5
)
175 READ_BUFFER_SIZEdcngettext (((void*)0), "Failed to allocate %d byte for file read buffer"
, "Failed to allocate %d bytes for file read buffer", 8192, 5
)
176 )dcngettext (((void*)0), "Failed to allocate %d byte for file read buffer"
, "Failed to allocate %d bytes for file read buffer", 8192, 5
)
,
177 READ_BUFFER_SIZE8192);
178 return NULL((void*)0);
179 }
180
181 /* Create CdkPixbufLoader. */
182 loader = cdk_pixbuf_loader_new();
183 if(loader == NULL((void*)0))
184 {
185 g_set_error(error, CDK_PIXBUF_ERRORcdk_pixbuf_error_quark (),
186 CDK_PIXBUF_ERROR_CORRUPT_IMAGE,
187 ngettext ( "QTIF atom size too large (%d byte)",dcngettext (((void*)0), "QTIF atom size too large (%d byte)",
"QTIF atom size too large (%d bytes)", hdr.length, 5)
188 "QTIF atom size too large (%d bytes)",dcngettext (((void*)0), "QTIF atom size too large (%d byte)",
"QTIF atom size too large (%d bytes)", hdr.length, 5)
189 hdr.length)dcngettext (((void*)0), "QTIF atom size too large (%d byte)",
"QTIF atom size too large (%d bytes)", hdr.length, 5)
,
190 hdr.length);
191 goto clean_up;
192 }
193
194 /* Read atom data. */
195 while(hdr.length != 0u)
196 {
197 if(fread(buf, 1, rd, f) != rd)
198 {
199 g_set_error(error, CDK_PIXBUF_ERRORcdk_pixbuf_error_quark (),
200 CDK_PIXBUF_ERROR_CORRUPT_IMAGE,
201 _("File error when reading QTIF atom: %s")((char *) g_dgettext ("cdk-pixbuf", "File error when reading QTIF atom: %s"
))
, g_strerror(errno(*__errno_location ())));
202 break;
203 }
204
205 if(!cdk_pixbuf_loader_write(loader, buf, rd, &tmp))
206 {
207 g_propagate_error (error, tmp);
208 break;
209 }
210 hdr.length -= rd;
211 }
212
213clean_up:
214 /* Release loader */
215 if(loader != NULL((void*)0))
216 {
217 cdk_pixbuf_loader_close(loader, NULL((void*)0));
218 pixbuf = cdk_pixbuf_loader_get_pixbuf(loader);
219 if(pixbuf != NULL((void*)0))
220 {
221 g_object_ref(pixbuf)((__typeof__ (pixbuf)) (g_object_ref) (pixbuf));
222 }
223 g_object_unref(loader);
224 }
225 if(buf != NULL((void*)0))
226 {
227 g_free(buf)(__builtin_object_size ((buf), 0) != ((size_t) - 1)) ? g_free_sized
(buf, __builtin_object_size ((buf), 0)) : (g_free) (buf)
;
228 }
229 return pixbuf;
230 }
231
232 default:
233 /* Skip any other types of atom. */
234 if(!fseek(f, hdr.length, SEEK_CUR1))
235 {
236 g_set_error(error, CDK_PIXBUF_ERRORcdk_pixbuf_error_quark (),
237 CDK_PIXBUF_ERROR_CORRUPT_IMAGE,
238 ngettext ( "Failed to skip the next %d byte with seek().",dcngettext (((void*)0), "Failed to skip the next %d byte with seek()."
, "Failed to skip the next %d bytes with seek().", hdr.length
, 5)
239 "Failed to skip the next %d bytes with seek().",dcngettext (((void*)0), "Failed to skip the next %d byte with seek()."
, "Failed to skip the next %d bytes with seek().", hdr.length
, 5)
240 hdr.length)dcngettext (((void*)0), "Failed to skip the next %d byte with seek()."
, "Failed to skip the next %d bytes with seek().", hdr.length
, 5)
,
241 hdr.length);
242 return NULL((void*)0);
243 }
244 break;
245 }
246 }
247 return NULL((void*)0);
248}
249
250/* Incremental load begin. */
251static gpointer cdk_pixbuf__qtif_image_begin_load (CdkPixbufModuleSizeFunc size_func,
252 CdkPixbufModulePreparedFunc prepared_func,
253 CdkPixbufModuleUpdatedFunc updated_func,
254 gpointer user_data,
255 GError **error)
256{
257 QTIFContext *context;
258
259 g_assert (size_func != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_13
= 0; if (size_func != ((void*)0)) _g_boolean_var_13 = 1; _g_boolean_var_13
; }), 1)) ; else g_assertion_message_expr ("CdkPixbuf", "../cdk-pixbuf/io-qtif.c"
, 259, ((const char*) (__func__)), "size_func != NULL"); } while
(0)
;
260 g_assert (prepared_func != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_14
= 0; if (prepared_func != ((void*)0)) _g_boolean_var_14 = 1;
_g_boolean_var_14; }), 1)) ; else g_assertion_message_expr (
"CdkPixbuf", "../cdk-pixbuf/io-qtif.c", 260, ((const char*) (
__func__)), "prepared_func != NULL"); } while (0)
;
261 g_assert (updated_func != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_15
= 0; if (updated_func != ((void*)0)) _g_boolean_var_15 = 1; _g_boolean_var_15
; }), 1)) ; else g_assertion_message_expr ("CdkPixbuf", "../cdk-pixbuf/io-qtif.c"
, 261, ((const char*) (__func__)), "updated_func != NULL"); }
while (0)
;
262
263 /* Create context struct. */
264 context = g_new0(QTIFContext, 1)(QTIFContext *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (QTIFContext); gpointer __p; if (__s == 1) __p =
g_malloc0 (__n); else if (__builtin_constant_p (__n) &&
(__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s
)) __p = g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s
); __p; }))
;
265 if(context == NULL((void*)0))
266 {
267 g_set_error_literal (error, CDK_PIXBUF_ERRORcdk_pixbuf_error_quark (),
268 CDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
269 _("Failed to allocate QTIF context structure.")((char *) g_dgettext ("cdk-pixbuf", "Failed to allocate QTIF context structure."
))
);
270 return NULL((void*)0);
271 }
272
273 /* Fill context parameters. */
274 context->loader = NULL((void*)0);
275 context->user_data = user_data;
276 context->state = STATE_READY;
277 context->run_length = 0u;
278 context->atom_count = QTIF_ATOM_COUNT_MAX10u;
279 context->size_func = size_func;
280 context->prepared_func = prepared_func;
281 context->updated_func = updated_func;
282
283 return context;
284}
285
286/* Incremental load clean up. */
287static gboolean cdk_pixbuf__qtif_image_stop_load (gpointer data, GError **error)
288{
289 QTIFContext *context = (QTIFContext *)data;
290 gboolean ret = TRUE(!(0));
291
292 if(context->loader != NULL((void*)0))
293 {
294 GError *tmp = NULL((void*)0);
295
296 ret = cdk_pixbuf__qtif_image_free_loader(context, &tmp);
297 if(!ret)
298 {
299 g_propagate_error (error, tmp);
300 }
301 }
302 g_free(context)(__builtin_object_size ((context), 0) != ((size_t) - 1)) ? g_free_sized
(context, __builtin_object_size ((context), 0)) : (g_free) (
context)
;
303
304 return ret;
305}
306
307/* Create a new CdkPixbufLoader and connect to its signals. */
308static gboolean cdk_pixbuf__qtif_image_create_loader (QTIFContext *context, GError **error)
309{
310 GError *tmp = NULL((void*)0);
311
312 if(context == NULL((void*)0))
313 {
314 return FALSE(0);
315 }
316
317 /* Free existing loader. */
318 if(context->loader != NULL((void*)0))
319 {
320 cdk_pixbuf__qtif_image_free_loader(context, &tmp);
321 }
322
323 /* Create CdkPixbufLoader object. */
324 context->loader = cdk_pixbuf_loader_new();
325 if(context->loader == NULL((void*)0))
326 {
327 g_set_error_literal (error, CDK_PIXBUF_ERRORcdk_pixbuf_error_quark (),
328 CDK_PIXBUF_ERROR_FAILED,
329 _("Failed to create CdkPixbufLoader object.")((char *) g_dgettext ("cdk-pixbuf", "Failed to create CdkPixbufLoader object."
))
);
330 return FALSE(0);
331 }
332
333 /* Connect signals. */
334 context->cb_prepare_count = 0;
335 context->cb_update_count = 0;
336 g_signal_connect(context->loader, "size-prepared",g_signal_connect_data ((context->loader), ("size-prepared"
), (((GCallback) (cdk_pixbuf__qtif_cb_size_prepared))), (context
), ((void*)0), (GConnectFlags) 0)
337 G_CALLBACK(cdk_pixbuf__qtif_cb_size_prepared),g_signal_connect_data ((context->loader), ("size-prepared"
), (((GCallback) (cdk_pixbuf__qtif_cb_size_prepared))), (context
), ((void*)0), (GConnectFlags) 0)
338 context)g_signal_connect_data ((context->loader), ("size-prepared"
), (((GCallback) (cdk_pixbuf__qtif_cb_size_prepared))), (context
), ((void*)0), (GConnectFlags) 0)
;
339 g_signal_connect(context->loader, "area-prepared",g_signal_connect_data ((context->loader), ("area-prepared"
), (((GCallback) (cdk_pixbuf__qtif_cb_area_prepared))), (context
), ((void*)0), (GConnectFlags) 0)
340 G_CALLBACK(cdk_pixbuf__qtif_cb_area_prepared),g_signal_connect_data ((context->loader), ("area-prepared"
), (((GCallback) (cdk_pixbuf__qtif_cb_area_prepared))), (context
), ((void*)0), (GConnectFlags) 0)
341 context)g_signal_connect_data ((context->loader), ("area-prepared"
), (((GCallback) (cdk_pixbuf__qtif_cb_area_prepared))), (context
), ((void*)0), (GConnectFlags) 0)
;
342 g_signal_connect(context->loader, "area-updated",g_signal_connect_data ((context->loader), ("area-updated")
, (((GCallback) (cdk_pixbuf__qtif_cb_area_updated))), (context
), ((void*)0), (GConnectFlags) 0)
343 G_CALLBACK(cdk_pixbuf__qtif_cb_area_updated),g_signal_connect_data ((context->loader), ("area-updated")
, (((GCallback) (cdk_pixbuf__qtif_cb_area_updated))), (context
), ((void*)0), (GConnectFlags) 0)
344 context)g_signal_connect_data ((context->loader), ("area-updated")
, (((GCallback) (cdk_pixbuf__qtif_cb_area_updated))), (context
), ((void*)0), (GConnectFlags) 0)
;
345 return TRUE(!(0));
346}
347
348/* Free the CdkPixbufLoader and perform callback if haven't done so. */
349static gboolean cdk_pixbuf__qtif_image_free_loader (QTIFContext *context, GError **error)
350{
351 CdkPixbuf *pixbuf;
352 GError *tmp = NULL((void*)0);
353 gboolean ret;
354
355 if((context == NULL((void*)0)) || (context->loader == NULL((void*)0)))
356 {
357 return FALSE(0);
358 }
359
360 /* Close CdkPixbufLoader. */
361 ret = cdk_pixbuf_loader_close(context->loader, &tmp);
362 if(!ret)
363 {
364 g_propagate_error (error, tmp);
365 }
366
367
368 /* Get CdkPixbuf from CdkPixbufLoader. */
369 pixbuf = cdk_pixbuf_loader_get_pixbuf(context->loader);
370 if(pixbuf != NULL((void*)0))
371 {
372 g_object_ref(pixbuf)((__typeof__ (pixbuf)) (g_object_ref) (pixbuf));
373 }
374
375 /* Free CdkPixbufLoader. */
376 g_object_ref(context->loader)((__typeof__ (context->loader)) (g_object_ref) (context->
loader))
;
377 context->loader = NULL((void*)0);
378
379 if(pixbuf != NULL((void*)0))
380 {
381 /* Callback functions should be called for at least once. */
382 if(context->cb_prepare_count == 0)
383 {
384 (context->prepared_func)(pixbuf, NULL((void*)0), context->user_data);
385 }
386
387 if(context->cb_update_count == 0)
388 {
389 gint width;
390 gint height;
391
392 width = cdk_pixbuf_get_width(pixbuf);
393 height = cdk_pixbuf_get_height(pixbuf);
394 (context->updated_func)(pixbuf, 0, 0, width, height, context->user_data);
395 }
396
397 /* Free CdkPixbuf (callback function should ref it). */
398 g_object_ref(pixbuf)((__typeof__ (pixbuf)) (g_object_ref) (pixbuf));
399 }
400
401 return ret;
402}
403
404
405/* Incrementally load the next chunk of data. */
406static gboolean cdk_pixbuf__qtif_image_load_increment (gpointer data,
407 const guchar *buf, guint size,
408 GError **error)
409{
410 QTIFContext *context = (QTIFContext *)data;
411 GError *tmp = NULL((void*)0);
412 gboolean ret = TRUE(!(0)); /* Return TRUE for insufficient data. */
413
414 while(ret && (size != 0u))
415 {
416 switch(context->state)
417 {
418 case STATE_READY:
419 /* Abort if we have seen too many atoms. */
420 if(context->atom_count == 0u)
421 {
422 g_set_error_literal (error, CDK_PIXBUF_ERRORcdk_pixbuf_error_quark (),
423 CDK_PIXBUF_ERROR_CORRUPT_IMAGE,
424 _("Failed to find an image data atom.")((char *) g_dgettext ("cdk-pixbuf", "Failed to find an image data atom."
))
);
425 return FALSE(0);
426 }
427 context->atom_count--;
428
429 /* Copy to header buffer in context, in case supplied data is not enough. */
430 while (context->run_length < sizeof(QtHeader) && size > 0u)
431 {
432 context->header_buffer[context->run_length] = *buf;
433 context->run_length++;
434 buf++;
435 size--;
436 }
437
438 /* Parse buffer as QT header. */
439 if(context->run_length == sizeof(QtHeader))
440 {
441 QtHeader *hdr = (QtHeader *)context->header_buffer;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
442 context->run_length = GUINT32_FROM_BE(hdr->length)((((__extension__ ({ guint32 __v, __x = ((guint32) (hdr->length
)); if (__builtin_constant_p (__x)) __v = ((guint32) ( (((guint32
) (__x) & (guint32) 0x000000ffU) << 24) | (((guint32
) (__x) & (guint32) 0x0000ff00U) << 8) | (((guint32
) (__x) & (guint32) 0x00ff0000U) >> 8) | (((guint32
) (__x) & (guint32) 0xff000000U) >> 24))); else __asm__
("bswapl %0" : "=r" (__v) : "0" (__x)); __v; })))))
- sizeof(QtHeader);
443
444 /* Atom max size check. */
445 if(context->run_length > ATOM_SIZE_MAX100000000)
446 {
447 g_set_error(error, CDK_PIXBUF_ERRORcdk_pixbuf_error_quark (),
448 CDK_PIXBUF_ERROR_CORRUPT_IMAGE,
449 ngettext ( "QTIF atom size too large (%d byte)",dcngettext (((void*)0), "QTIF atom size too large (%d byte)",
"QTIF atom size too large (%d bytes)", hdr->length, 5)
450 "QTIF atom size too large (%d bytes)",dcngettext (((void*)0), "QTIF atom size too large (%d byte)",
"QTIF atom size too large (%d bytes)", hdr->length, 5)
451 hdr->length)dcngettext (((void*)0), "QTIF atom size too large (%d byte)",
"QTIF atom size too large (%d bytes)", hdr->length, 5)
,
452 hdr->length);
453 return FALSE(0);
454 }
455
456 /* Set state according to atom type. */
457 if(GUINT32_FROM_BE(hdr->tag)((((__extension__ ({ guint32 __v, __x = ((guint32) (hdr->tag
)); if (__builtin_constant_p (__x)) __v = ((guint32) ( (((guint32
) (__x) & (guint32) 0x000000ffU) << 24) | (((guint32
) (__x) & (guint32) 0x0000ff00U) << 8) | (((guint32
) (__x) & (guint32) 0x00ff0000U) >> 8) | (((guint32
) (__x) & (guint32) 0xff000000U) >> 24))); else __asm__
("bswapl %0" : "=r" (__v) : "0" (__x)); __v; })))))
== QTIF_TAG_IDATA0x69646174u)
458 {
459 GError *tmp = NULL((void*)0);
460
461 context->state = STATE_DATA;
462
463 /* Create CdkPixbufLoader for this image data. */
464 ret = cdk_pixbuf__qtif_image_create_loader(context, &tmp);
465 if(!ret)
466 {
467 g_propagate_error (error, tmp);
468 }
469 }
470 else
471 {
472 context->state = STATE_OTHER;
473 }
474 }
475 break;
476
477 default: /* Both STATE_DATA and STATE_OTHER will come here. */
478 /* Check for atom boundary. */
479 if(context->run_length > size)
480 {
481 /* Supply image data to CdkPixbufLoader if in STATE_DATA. */
482 if(context->state == STATE_DATA)
483 {
484 tmp = NULL((void*)0);
485 ret = cdk_pixbuf_loader_write(context->loader, buf, size, &tmp);
486 if(!ret && (error != NULL((void*)0)) && (*error == NULL((void*)0)))
487 {
488 g_propagate_error (error, tmp);
489 }
490 }
491 context->run_length -= size;
492 size = 0u;
493 }
494 else
495 {
496 /* Supply image data to CdkPixbufLoader if in STATE_DATA. */
497 if(context->state == STATE_DATA)
498 {
499 gboolean r;
500
501 /* Here we should have concluded a complete image atom. */
502 tmp = NULL((void*)0);
503 ret = cdk_pixbuf_loader_write(context->loader, buf, context->run_length, &tmp);
504 if(!ret && (error != NULL((void*)0)) && (*error == NULL((void*)0)))
505 {
506 g_propagate_error (error, tmp);
507 }
508
509 /* Free CdkPixbufLoader and handle callback. */
510 tmp = NULL((void*)0);
511 r = cdk_pixbuf__qtif_image_free_loader(context, &tmp);
512 if(!r)
513 {
514 if((error != NULL((void*)0)) && (*error == NULL((void*)0)))
515 {
516 g_propagate_error (error, tmp);
517 }
518 ret = FALSE(0);
519 }
520 }
521 buf = &buf[context->run_length];
522 size -= context->run_length;
523 context->run_length = 0u;
524 context->state = STATE_READY;
525 }
526 break;
527 }
528 }
529
530 return ret;
531}
532
533/* Event handlers */
534static void cdk_pixbuf__qtif_cb_size_prepared(CdkPixbufLoader *loader,
535 gint width,
536 gint height,
537 gpointer user_data)
538{
539 QTIFContext *context = (QTIFContext *)user_data;
540 (context->size_func)(&width, &height, context->user_data);
541 context->cb_prepare_count++;
542}
543
544static void cdk_pixbuf__qtif_cb_area_prepared(CdkPixbufLoader *loader, gpointer user_data)
545{
546 QTIFContext *context = (QTIFContext *)user_data;
547 CdkPixbuf *pixbuf = cdk_pixbuf_loader_get_pixbuf(context->loader);
548 (context->prepared_func)(pixbuf, NULL((void*)0), context->user_data);
549 context->cb_update_count++;
550}
551
552static void cdk_pixbuf__qtif_cb_area_updated(CdkPixbufLoader *loader,
553 gint x,
554 gint y,
555 gint width,
556 gint height,
557 gpointer user_data)
558{
559 QTIFContext *context = (QTIFContext *)user_data;
560 CdkPixbuf *pixbuf = cdk_pixbuf_loader_get_pixbuf(context->loader);
561 (context->updated_func)(pixbuf, x, y, width, height, context->user_data);
562}
563
564
565#ifndef INCLUDE_qtif
566#define MODULE_ENTRY(function)__attribute__((visibility("default"))) void function G_MODULE_EXPORT__attribute__((visibility("default"))) void function
567#else
568#define MODULE_ENTRY(function)__attribute__((visibility("default"))) void function void _cdk_pixbuf__qtif_ ## function
569#endif
570
571MODULE_ENTRY (fill_vtable)__attribute__((visibility("default"))) void fill_vtable (CdkPixbufModule *module)
572{
573 module->load = cdk_pixbuf__qtif_image_load;
574 module->begin_load = cdk_pixbuf__qtif_image_begin_load;
575 module->stop_load = cdk_pixbuf__qtif_image_stop_load;
576 module->load_increment = cdk_pixbuf__qtif_image_load_increment;
577}
578
579MODULE_ENTRY (fill_info)__attribute__((visibility("default"))) void fill_info (CdkPixbufFormat *info)
580{
581 static const CdkPixbufModulePattern signature[] = {
582 { "abcdidsc", "xxxx ", 100 },
583 { "abcdidat", "xxxx ", 100 },
584 { NULL((void*)0), NULL((void*)0), 0 }
585 };
586 static const gchar *mime_types[] = {
587 "image/x-quicktime",
588 "image/qtif",
589 NULL((void*)0)
590 };
591 static const gchar *extensions[] = {
592 "qtif",
593 "qif",
594 NULL((void*)0)
595 };
596
597 info->name = "qtif";
598 info->signature = (CdkPixbufModulePattern *) signature;
599 info->description = NC_("image format", "QuickTime")("QuickTime");
600 info->mime_types = (gchar **) mime_types;
601 info->extensions = (gchar **) extensions;
602 info->flags = CDK_PIXBUF_FORMAT_THREADSAFE;
603 info->license = "LGPL";
604}
605