Krita Source Code Documentation
Loading...
Searching...
No Matches
xcf-general.c File Reference
#include "xcftools.h"
#include <string.h>
#include <errno.h>
#include <limits.h>

Go to the source code of this file.

Macros

#define ICONV_CONST   const
 

Functions

int computeDimensions (struct tileDimensions *d)
 
int getBasicXcfInfo (void)
 
int xcfNextprop (uint32_t *master, uint32_t *body, PropType *typeOut)
 
int xcfOffset (uint32_t addr, int spaceafter, uint32_t *apparent)
 
const char * xcfString (uint32_t ptr, uint32_t *after)
 

Variables

int use_utf8 = 0
 
struct xcfImage XCF
 
uint8_t * xcf_file = 0
 
size_t xcf_length
 

Macro Definition Documentation

◆ ICONV_CONST

#define ICONV_CONST   const

Definition at line 26 of file xcf-general.c.

Function Documentation

◆ computeDimensions()

int computeDimensions ( struct tileDimensions * d)

Definition at line 220 of file xcf-general.c.

221{
222 // [ CVE-2019-5086 and CVE-2019-5087 ]
223 // This part of code is the check to prevent integer overflow, see CVE-2019-5086 and CVE-2019-5087
224
225 if ((d->c.l + d->width) * 4 > INT_MAX) {
226 FatalBadXCF(("Width is too large (%d)! Stopping execution...\n"), (d->c.l + d->width));
227 return XCF_ERROR;
228 }
229
230 if ((d->c.t + d->height) * 4 > INT_MAX) {
231 FatalBadXCF(("Height is too large (%d)! Stopping execution...\n"), (d->c.t + d->height));
232 return XCF_ERROR;
233 }
234 // [ CVE-2019-5086 and CVE-2019-5087 ]
235
236 d->c.r = d->c.l + d->width ;
237 d->c.b = d->c.t + d->height ;
238 d->tilesx = (d->width+TILE_WIDTH-1)/TILE_WIDTH ;
239 d->tilesy = (d->height+TILE_HEIGHT-1)/TILE_HEIGHT ;
240 d->ntiles = d->tilesx * d->tilesy ;
241
242 return XCF_OK;
243}
void FatalBadXCF(const char *format,...)
Definition utils.c:66
#define TILE_HEIGHT
Definition xcftools.h:155
#define TILE_WIDTH
Definition xcftools.h:154
#define XCF_OK
Definition xcftools.h:106
#define XCF_ERROR
Definition xcftools.h:105

References FatalBadXCF(), TILE_HEIGHT, TILE_WIDTH, XCF_ERROR, and XCF_OK.

◆ getBasicXcfInfo()

int getBasicXcfInfo ( void )

Definition at line 248 of file xcf-general.c.

249{
250 uint32_t ptr, data, layerfile ;
251 PropType type ;
252 int i, j ;
253
254 int errorStatus;
255 uint32_t ptrout;
256
257 if (xcfCheckspace(0,14+7*4,"(very short)") != XCF_OK) {
258 return XCF_ERROR;
259 }
260
261 if( strcmp((char*)xcf_file,"gimp xcf file") == 0 )
262 XCF.version = 0 ;
263 else if( xcf_file[13] == 0 &&
264 sscanf((char*)xcf_file,"gimp xcf v%d",&XCF.version) == 1 )
265 ;
266 else {
267 FatalBadXCF(_("Not an XCF file at all (magic not recognized)"));
268 return XCF_ERROR;
269 }
270
271 if (XCF.version < 0 || XCF.version > 2) {
272 fprintf(stderr, _("Warning: XCF version %d not supported (trying anyway...)\n"), XCF.version);
273 }
274
276 XCF.colormapptr = 0 ;
277
278 ptr = 14 ;
279 XCF.width = xcfL(ptr); ptr += 4 ;
280 XCF.height = xcfL(ptr); ptr += 4 ;
281 XCF.type = xcfL(ptr); ptr += 4 ;
282 while( (errorStatus = xcfNextprop(&ptr,&data, &type)) != XCF_ERROR && type != PROP_END ) {
283 if (errorStatus != XCF_OK) {
284 return XCF_ERROR;
285 }
286
287 switch(type) {
288 case PROP_COLORMAP:
289 XCF.colormapptr = data ;
290 break ;
291 case PROP_COMPRESSION:
292 XCF.compression = xcf_file[data] ;
293 break ;
294 default:
295 /* Ignore unknown properties */
296 break ;
297 }
298 }
299
300 layerfile = ptr ;
301 XCF.numLayers = 0;
302 while (1) {
303 errorStatus = xcfOffset(ptr,8*4, &ptrout);
304 if (errorStatus != XCF_OK) {
305 return XCF_ERROR;
306 }
307 if (!ptrout) {
308 break;
309 }
310 XCF.numLayers++;
311 ptr+=4;
312 }
313 XCF.layers = xcfmalloc(XCF.numLayers * sizeof(struct xcfLayer)) ;
314 for( i = 0 ; i < XCF.numLayers ; i++ ) {
315 struct xcfLayer *L = XCF.layers + i ;
316 ptr = xcfL(layerfile+4*(XCF.numLayers-1-i)) ;
317
319 L->opacity = 255 ;
320 L->isVisible = 1 ;
321 L->hasMask = 0 ;
322 L->dim.width = xcfL(ptr); ptr+=4 ;
323 L->dim.height = xcfL(ptr); ptr+=4 ;
324 L->type = xcfL(ptr); ptr+=4 ;
325 L->name = xcfString(ptr,&ptr);
326 if (L->name == XCF_PTR_EMPTY) {
327 return XCF_ERROR;
328 }
329 L->propptr = ptr ;
330
331 L->isGroup = 0;
332 L->pathLength = 0;
333 L->path = NULL;
334
335 while( (errorStatus = xcfNextprop(&ptr,&data, &type)) != XCF_ERROR && type != PROP_END ) {
336 if (errorStatus != XCF_OK) {
339 return XCF_ERROR;
340 }
341 switch(type) {
342 case PROP_OPACITY:
343 L->opacity = xcfL(data);
344 if( L->opacity > 255 )
345 L->opacity = 255 ;
346 break ;
347 case PROP_VISIBLE:
348 L->isVisible = xcfL(data) != 0 ;
349 break ;
350 case PROP_APPLY_MASK:
351 L->hasMask = xcfL(data) != 0 ;
352 break ;
353 case PROP_OFFSETS:
354 L->dim.c.l = (int32_t)(xcfL(data )) ;
355 L->dim.c.t = (int32_t)(xcfL(data+4)) ;
356 break ;
357 case PROP_MODE:
358 L->mode = xcfL(data);
359 break ;
360 case PROP_GROUP_ITEM:
361 L->isGroup = 1 ;
362 break;
363 case PROP_ITEM_PATH:
364 L->pathLength = (ptr - data - 2) / 4 ;
365
366 if ( L->pathLength != 0 ) {
367
368 L->path = xcfmalloc( L->pathLength * sizeof(unsigned) ) ;
369
370 for ( j = 0; j!=L->pathLength; j++ )
371 *(L->path + j) = (unsigned)xcfL(data + 4 * j);
372 }
373 break;
374 default:
375 /* Ignore unknown properties */
376 break ;
377 }
378 }
379 if ((errorStatus = xcfCheckspace(ptr,8,"(end of layer %s)",L->name)) != XCF_OK) {
382 return XCF_ERROR;
383 }
384 L->pixels.tileptrs = 0 ;
385 if (xcfOffset(ptr , 4*4, &(L->pixels.hierarchy)) != XCF_OK) {
388 return XCF_ERROR;
389 }
390 L->mask.tileptrs = 0 ;
391 if (xcfOffset(ptr+4, 4*4, &(L->mask.hierarchy)) != XCF_OK) {
394 return XCF_ERROR;
395 }
396
397 if (computeDimensions(&L->dim) != XCF_OK) {
398 return XCF_ERROR;
399 }
400 }
401 return XCF_OK;
402}
@ GIMP_NORMAL_MODE
Definition enums.h:9
@ COMPRESS_NONE
Definition enums.h:97
PropType
Definition enums.h:59
@ PROP_MODE
Definition enums.h:67
@ PROP_ITEM_PATH
Definition enums.h:90
@ PROP_VISIBLE
Definition enums.h:68
@ PROP_COMPRESSION
Definition enums.h:77
@ PROP_COLORMAP
Definition enums.h:61
@ PROP_GROUP_ITEM
Definition enums.h:89
@ PROP_OPACITY
Definition enums.h:66
@ PROP_APPLY_MASK
Definition enums.h:71
@ PROP_OFFSETS
Definition enums.h:75
@ PROP_END
Definition enums.h:60
int l
Definition xcftools.h:130
int t
Definition xcftools.h:130
struct rect c
Definition xcftools.h:166
unsigned height
Definition xcftools.h:167
unsigned width
Definition xcftools.h:167
GimpImageBaseType type
Definition xcftools.h:198
XcfCompressionType compression
Definition xcftools.h:199
unsigned height
Definition xcftools.h:197
unsigned width
Definition xcftools.h:197
int numLayers
Definition xcftools.h:200
struct xcfLayer * layers
Definition xcftools.h:201
int version
Definition xcftools.h:196
uint32_t colormapptr
Definition xcftools.h:202
unsigned int opacity
Definition xcftools.h:185
unsigned pathLength
Definition xcftools.h:191
int isVisible
Definition xcftools.h:186
GimpLayerModeEffects mode
Definition xcftools.h:183
struct xcfTiles pixels
Definition xcftools.h:188
int isGroup
Definition xcftools.h:190
int hasMask
Definition xcftools.h:186
uint32_t propptr
Definition xcftools.h:187
struct tileDimensions dim
Definition xcftools.h:181
unsigned * path
Definition xcftools.h:192
const char * name
Definition xcftools.h:182
GimpImageType type
Definition xcftools.h:184
struct xcfTiles mask
Definition xcftools.h:189
uint32_t hierarchy
Definition xcftools.h:177
uint32_t * tileptrs
Definition xcftools.h:176
void * xcfmalloc(size_t size)
Definition utils.c:114
void xcffree(void *block)
Definition utils.c:125
int xcfCheckspace(uint32_t addr, int spaceafter, const char *format,...)
Definition utils.c:75
int xcfOffset(uint32_t addr, int spaceafter, uint32_t *apparent)
Definition xcf-general.c:34
int xcfNextprop(uint32_t *master, uint32_t *body, PropType *typeOut)
Definition xcf-general.c:52
struct xcfImage XCF
const char * xcfString(uint32_t ptr, uint32_t *after)
int computeDimensions(struct tileDimensions *d)
uint8_t * xcf_file
Definition xcf-general.c:29
#define xcfL(a)
Definition xcftools.h:91
#define XCF_PTR_EMPTY
Definition xcftools.h:107
#define _(s)
Definition xcftools.h:32

References _, tileDimensions::c, xcfImage::colormapptr, COMPRESS_NONE, xcfImage::compression, computeDimensions(), xcfLayer::dim, FatalBadXCF(), GIMP_NORMAL_MODE, xcfLayer::hasMask, tileDimensions::height, xcfImage::height, xcfTiles::hierarchy, xcfLayer::isGroup, xcfLayer::isVisible, rect::l, xcfImage::layers, xcfLayer::mask, xcfLayer::mode, xcfLayer::name, xcfImage::numLayers, xcfLayer::opacity, xcfLayer::path, xcfLayer::pathLength, xcfLayer::pixels, PROP_APPLY_MASK, PROP_COLORMAP, PROP_COMPRESSION, PROP_END, PROP_GROUP_ITEM, PROP_ITEM_PATH, PROP_MODE, PROP_OFFSETS, PROP_OPACITY, PROP_VISIBLE, xcfLayer::propptr, rect::t, xcfTiles::tileptrs, xcfLayer::type, xcfImage::type, xcfImage::version, tileDimensions::width, xcfImage::width, XCF, XCF_ERROR, xcf_file, XCF_OK, XCF_PTR_EMPTY, xcfCheckspace(), xcffree(), xcfL, xcfmalloc(), xcfNextprop(), xcfOffset(), and xcfString().

◆ xcfNextprop()

int xcfNextprop ( uint32_t * master,
uint32_t * body,
PropType * typeOut )

Definition at line 52 of file xcf-general.c.

53{
54 int response;
55
56 if (typeOut == 0) {
57 return XCF_ERROR;
58 }
59
60 uint32_t ptr, length, total, minlength ;
61 PropType type ;
62 ptr = *master ;
63 if ((response = xcfCheckspace(ptr,8,"(property header)")) != XCF_OK) {
64 return XCF_ERROR;
65 }
66 type = xcfL(ptr);
67 length = xcfL(ptr+4);
68 *body = ptr+8 ;
69
70 switch(type) {
71 case PROP_COLORMAP:
72 {
73 uint32_t ncolors ;
74 if ((response = xcfCheckspace(ptr+8,4,"(colormap length)")) != XCF_OK) {
75 return XCF_ERROR;
76 }
77 ncolors = xcfL(ptr+8) ;
78 if( ncolors > 256 ) {
79 FatalBadXCF("Colormap has %" PRIu32 " entries",ncolors);
80 return XCF_ERROR;
81 }
82
83 /* Surprise! Some older version of the Gimp computed the wrong length
84 * word, and the _reader_ always just reads three bytes per color
85 * and ignores the length tag! Duplicate this so we too can read
86 * the buggy XCF files.
87 */
88 length = minlength = 4+3*ncolors;
89 break;
90 }
91 case PROP_COMPRESSION: minlength = 1; break;
92 case PROP_OPACITY: minlength = 4; break;
93 case PROP_APPLY_MASK: minlength = 4; break;
94 case PROP_OFFSETS: minlength = 8; break;
95 case PROP_MODE: minlength = 4; break;
96 default: minlength = 0; break;
97 }
98 if( length < minlength ) {
99 FatalBadXCF("Short %s property at %" PRIX32 " (%" PRIu32 "<%" PRIu32 ")",
100 showPropType(type),ptr,length,minlength);
101 return XCF_ERROR;
102 }
103 *master = ptr+8+length ;
104 total = 8 + length + (type != PROP_END ? 8 : 0) ;
105 if( total < length ) { /* Check overwrap */
106 FatalBadXCF("Overlong property at %" PRIX32, ptr);
107 return XCF_ERROR;
108 }
109 if((response = xcfCheckspace(ptr,total,"Overlong property at %" PRIX32,ptr)) != 0) {
110 return XCF_ERROR;
111 }
112 *typeOut = type;
113 return XCF_OK;
114}
qreal length(const QPointF &vec)
Definition Ellipse.cc:82
const char * showPropType(PropType x)
Definition enums.c:69

References FatalBadXCF(), length(), PROP_APPLY_MASK, PROP_COLORMAP, PROP_COMPRESSION, PROP_END, PROP_MODE, PROP_OFFSETS, PROP_OPACITY, showPropType(), XCF_ERROR, XCF_OK, xcfCheckspace(), and xcfL.

◆ xcfOffset()

int xcfOffset ( uint32_t addr,
int spaceafter,
uint32_t * apparent )

Definition at line 34 of file xcf-general.c.

35{
36 if (!apparent) {
37 return XCF_ERROR;
38 }
39 if(xcfCheckspace(addr,4,"(xcfOffset)") != XCF_OK) {
40 return XCF_ERROR;
41 }
42 *apparent = xcfL(addr);
43 if (xcfCheckspace(*apparent,spaceafter,
44 "Too large offset (%" PRIX32 ") at position %" PRIX32,
45 *apparent,addr) != XCF_OK) {
46 return XCF_ERROR;
47 }
48 return XCF_OK;
49}

References XCF_ERROR, XCF_OK, xcfCheckspace(), and xcfL.

◆ xcfString()

const char * xcfString ( uint32_t ptr,
uint32_t * after )

Definition at line 117 of file xcf-general.c.

118{
119 uint32_t length ;
120 unsigned i ;
121 ICONV_CONST char *utf8master ;
122
123 if (xcfCheckspace(ptr,4,"(string length)") != XCF_OK) {
124 return XCF_PTR_EMPTY;
125 }
126 length = xcfL(ptr) ;
127 ptr += 4 ;
128 if (xcfCheckspace(ptr,length,"(string)") != XCF_OK) {
129 return XCF_PTR_EMPTY;
130 }
131 utf8master = (ICONV_CONST char*)(xcf_file+ptr) ;
132 if( after ) *after = ptr + length ;
133 if( length == 0 || utf8master[length-1] != 0 ) {
134 FatalBadXCF("String at %" PRIX32 " not zero-terminated",ptr-4);
135 return XCF_PTR_EMPTY;
136 }
137 length-- ;
138
139 if( use_utf8 ) return utf8master ;
140
141 /* We assume that the local character set includes ASCII...
142 * Check if conversion is needed at all
143 */
144 for( i=0 ; ; i++ ) {
145 if( i == length )
146 return utf8master ; /* Only ASCII after all */
147 if( utf8master[i] == 0 ) {
148 FatalBadXCF("String at %" PRIX32 " has embedded zeroes",ptr-4);
149 return XCF_PTR_EMPTY;
150 }
151 if( (int8_t) utf8master[i] < 0 )
152 break ;
153 }
154#ifdef HAVE_ICONV
155 {
156 size_t targetsize = length+1 ;
157 int sloppy_translation = 0 ;
158 iconv_t cd = iconv_open("//TRANSLIT","UTF-8");
159 if( cd == (iconv_t) -1 ) {
160 cd = iconv_open("","UTF-8");
161 sloppy_translation = 1 ;
162 }
163 if( cd == (iconv_t) -1 )
164 iconv_close(cd) ; /* Give up; perhaps iconv doesn't know UTF-8 */
165 else
166 while(1) {
167 char *buffer = xcfmalloc(targetsize) ;
168 ICONV_CONST char *inbuf = utf8master ;
169 char *outbuf = buffer ;
170 size_t incount = length ;
171 size_t outcount = targetsize ;
172 while(1) { /* Loop for systems without //ICONV support */
173 size_t result = iconv(cd,&inbuf,&incount,&outbuf,&outcount) ;
174 if( result == (size_t)-1 && errno == EILSEQ &&
175 sloppy_translation && outcount > 0 ) {
176 *outbuf++ = '?' ;
177 outcount-- ;
178 while( (int8_t)*inbuf < 0 ) inbuf++, incount-- ;
179 continue ;
180 }
181 if( result != (size_t)-1 ) {
182 if( outcount == 0 )
183 errno = E2BIG ;
184 else {
185 *outbuf = 0 ;
186 iconv_close(cd) ;
187 return buffer ;
188 }
189 }
190 break ;
191 }
192 if( errno == EILSEQ || errno == EINVAL ) {
193 FatalBadXCF("Bad UTF-8 encoding '%s' at %" PRIXPTR,
194 inbuf,(uintptr_t)((inbuf-utf8master)+ptr));
195 return XCF_PTR_EMPTY;
196 }
197 if( errno == E2BIG ) {
198 targetsize += 1+incount ;
199 xcffree(buffer) ;
200 continue ;
201 }
202 FatalUnexpected("!iconv on layer name at %" PRIX32, ptr);
203 return XCF_PTR_EMPTY:
204 }
205 }
206#endif
207 {
208 static int warned = 0 ;
209 if( !warned ) {
210 fprintf(stderr,_("Warning: one or more layer names could not be\n"
211 " translated to the local character set.\n"));
212 warned = 1 ;
213 }
214 }
215 return utf8master ;
216}
void FatalUnexpected(const char *format,...)
Definition utils.c:56
int use_utf8
Definition xcf-general.c:31
#define ICONV_CONST
Definition xcf-general.c:26

References _, FatalBadXCF(), FatalUnexpected(), ICONV_CONST, length(), use_utf8, xcf_file, XCF_OK, XCF_PTR_EMPTY, xcfCheckspace(), xcffree(), xcfL, and xcfmalloc().

Variable Documentation

◆ use_utf8

int use_utf8 = 0

Definition at line 31 of file xcf-general.c.

◆ XCF

struct xcfImage XCF

Definition at line 245 of file xcf-general.c.

◆ xcf_file

uint8_t* xcf_file = 0

Definition at line 29 of file xcf-general.c.

◆ xcf_length

size_t xcf_length

Definition at line 30 of file xcf-general.c.