=============================== CVE-2017-2887.patch From: Sam Lantinga Date: Fri, 6 Oct 2017 15:40:19 -0700 Subject: Fixed security vulnerability in XCF image loader (thanks Yves!) Originally hg commit 318484db0705d07d4d1f4c0a1d3d5ea69f6ba2b0. Bug: https://security-tracker.debian.org/tracker/CVE-2017-2887 Origin: backport, 2.0.2, commit:https://github.com/libsdl-org/SDL_image/commit/e7723676825cd2b2ffef3316ec1879d7726618f2 --- IMG_xcf.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/IMG_xcf.c b/IMG_xcf.c index 1dced65..b0a4901 100644 --- a/IMG_xcf.c +++ b/IMG_xcf.c @@ -251,6 +251,7 @@ static Uint32 Swap32 (Uint32 v) { } static void xcf_read_property (SDL_RWops * src, xcf_prop * prop) { + Uint32 len; prop->id = SDL_ReadBE32 (src); prop->length = SDL_ReadBE32 (src); @@ -274,7 +275,12 @@ static void xcf_read_property (SDL_RWops * src, xcf_prop * prop) { break; case PROP_COMPRESSION: case PROP_COLOR: - SDL_RWread (src, &prop->data, prop->length, 1); + if (prop->length > sizeof(prop->data)) { + len = sizeof(prop->data); + } else { + len = prop->length; + } + SDL_RWread(src, &prop->data, len, 1); break; case PROP_VISIBLE: prop->data.visible = SDL_ReadBE32 (src); =============================== CVE-2017-12122-1.patch From: "Ryan C. Gordon" Date: Wed, 24 Jan 2018 01:44:36 -0500 Subject: lbm: use correct variable to check color planes. Bug: https://security-tracker.debian.org/tracker/CVE-2017-12122 Origin: upstream, 2.0.3, commit:16772bbb1b09, commit:https://github.com/libsdl-org/SDL_image/commit/571c0d7c62daeebeae30fb03f5712385bd3a95f0 --- IMG_lbm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/IMG_lbm.c b/IMG_lbm.c index f475c60..9ff8374 100644 --- a/IMG_lbm.c +++ b/IMG_lbm.c @@ -249,7 +249,7 @@ SDL_Surface *IMG_LoadLBM_RW( SDL_RWops *src ) goto done; } - if ( ( Image = SDL_CreateRGBSurface( SDL_SWSURFACE, width, bmhd.h, (bmhd.planes==24 || flagHAM==1)?24:8, 0, 0, 0, 0 ) ) == NULL ) + if ( ( Image = SDL_CreateRGBSurface( SDL_SWSURFACE, width, bmhd.h, (nbplanes==24 || flagHAM==1)?24:8, 0, 0, 0, 0 ) ) == NULL ) goto done; if ( bmhd.mask & 2 ) /* There is a transparent color */ @@ -276,7 +276,7 @@ SDL_Surface *IMG_LoadLBM_RW( SDL_RWops *src ) /* The 32 last colors are the same but divided by 2 */ /* Some Amiga pictures save 64 colors with 32 last wrong colors, */ /* they shouldn't !, and here we overwrite these 32 bad colors. */ - if ( (nbcolors==32 || flagEHB ) && (1< (1< (1< Date: Wed, 24 Jan 2018 01:45:04 -0500 Subject: lbm: Fail to load images with unsupported/bogus color depth. Origin: upstream, 2.0.3, commit:97f7f01e0665, commit:https://github.com/libsdl-org/SDL_image/commit/b48777d41c742227dd1c64fa1021fca55f53b9f3 --- IMG_lbm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/IMG_lbm.c b/IMG_lbm.c index 9ff8374..c19fe9f 100644 --- a/IMG_lbm.c +++ b/IMG_lbm.c @@ -237,6 +237,12 @@ SDL_Surface *IMG_LoadLBM_RW( SDL_RWops *src ) nbplanes = 1; } + if ((nbplanes != 1) && (nbplanes != 4) && (nbplanes != 8) && (nbplanes != 24)) + { + error="unsupported number of color planes"; + goto done; + } + stencil = (bmhd.mask & 1); /* There is a mask ( 'stencil' ) */ /* Allocate memory for a temporary buffer ( used for =============================== CVE-2017-14440.patch From: "Ryan C. Gordon" Date: Wed, 24 Jan 2018 12:00:24 -0500 Subject: lbm: Don't overflow static colormap buffer. Bug: https://security-tracker.debian.org/tracker/CVE-2017-14440 Origin: upstream, 2.0.3, commit:bfa08dc02b3c, commit:https://github.com/libsdl-org/SDL_image/commit/1559b5ce67e25c8de65f0d4af020c1ec50cb7b85 --- IMG_lbm.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/IMG_lbm.c b/IMG_lbm.c index c19fe9f..cf70b53 100644 --- a/IMG_lbm.c +++ b/IMG_lbm.c @@ -187,6 +187,11 @@ SDL_Surface *IMG_LoadLBM_RW( SDL_RWops *src ) if ( !memcmp( id, "CMAP", 4 ) ) /* palette ( Color Map ) */ { + if (size > sizeof (colormap)) { + error="colormap size is too large"; + goto done; + } + if ( !SDL_RWread( src, &colormap, size, 1 ) ) { error="error reading CMAP chunk"; =============================== CVE-2017-14441.patch From: "Ryan C. Gordon" Date: Wed, 24 Jan 2018 13:02:04 -0500 Subject: ico: reject obviously incorrect image sizes. Bug: https://security-tracker.debian.org/tracker/CVE-2017-14441 Origin: upstream, 2.0.3, commit:a1e9b624ca10, commit:https://github.com/libsdl-org/SDL_image/commit/da6a5c54fdc0c926ab1233ae4792a1703c83e810 --- IMG_bmp.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/IMG_bmp.c b/IMG_bmp.c index b3c7580..60ba1a5 100644 --- a/IMG_bmp.c +++ b/IMG_bmp.c @@ -662,6 +662,14 @@ LoadICOCUR_RW(SDL_RWops * src, int type, int freesrc) goto done; } + /* sanity check image size, so we don't overflow integers, etc. */ + if ((biWidth < 0) || (biWidth > 0xFFFFFF) || + (biHeight < 0) || (biHeight > 0xFFFFFF)) { + IMG_SetError("Unsupported or invalid ICO dimensions"); + was_error = SDL_TRUE; + goto done; + } + /* Create a RGBA surface */ biHeight = biHeight >> 1; //printf("%d x %d\n", biWidth, biHeight); =============================== CVE-2017-14442.patch From: "Ryan C. Gordon" Date: Wed, 24 Jan 2018 13:12:07 -0500 Subject: bmp: don't overflow palette buffer with bogus biClrUsed values. Bug: https://security-tracker.debian.org/tracker/CVE-2017-14442 Origin: upstream, 2.0.3, commit:37445f6180a8, commit:https://github.com/libsdl-org/SDL_image/commit/071a19952241576f2dcc579a9956e65555776e78 --- IMG_bmp.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/IMG_bmp.c b/IMG_bmp.c index 60ba1a5..a77d045 100644 --- a/IMG_bmp.c +++ b/IMG_bmp.c @@ -687,6 +687,11 @@ LoadICOCUR_RW(SDL_RWops * src, int type, int freesrc) if (biClrUsed == 0) { biClrUsed = 1 << biBitCount; } + if (biClrUsed > SDL_arraysize(palette)) { + IMG_SetError("Unsupported or incorrect biClrUsed field"); + was_error = SDL_TRUE; + goto done; + } for (i = 0; i < (int) biClrUsed; ++i) { SDL_RWread(src, &palette[i], 4, 1); } =============================== CVE-2017-14448.patch From: "Ryan C. Gordon" Date: Sat, 27 Jan 2018 17:27:55 -0500 Subject: xcf: deal with bogus data in rle tile decoding. Bug: https://security-tracker.debian.org/tracker/CVE-2017-14448 Origin: backport, 2.0.3, commit:7df1580f1695, commit:https://github.com/libsdl-org/SDL_image/commit/8b6b94de1e4d228fef91a70f7f3bc4fc26d79cb2 --- IMG_xcf.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/IMG_xcf.c b/IMG_xcf.c index b0a4901..8a65507 100644 --- a/IMG_xcf.c +++ b/IMG_xcf.c @@ -476,6 +476,7 @@ static unsigned char * load_xcf_tile_rle (SDL_RWops * src, Uint32 len, int bpp, reallen = SDL_RWread (src, t, 1, len); data = (unsigned char *) malloc (x*y*bpp); + data = (unsigned char *) calloc (1, x*y*bpp); for (i = 0; i < bpp; i++) { d = data + i; size = x*y; @@ -492,6 +493,12 @@ static unsigned char * load_xcf_tile_rle (SDL_RWops * src, Uint32 len, int bpp, t += 2; } + if (((size_t) (t - load) + length) >= len) { + break; /* bogus data */ + } else if (length > size) { + break; /* bogus data */ + } + count += length; size -= length; @@ -507,6 +514,12 @@ static unsigned char * load_xcf_tile_rle (SDL_RWops * src, Uint32 len, int bpp, t += 2; } + if (((size_t) (t - load)) >= len) { + break; /* bogus data */ + } else if (length > size) { + break; /* bogus data */ + } + count += length; size -= length; @@ -518,6 +531,10 @@ static unsigned char * load_xcf_tile_rle (SDL_RWops * src, Uint32 len, int bpp, } } } + + if (size > 0) { + break; /* just drop out, untouched data initialized to zero. */ + } } free (load); =============================== CVE-2017-14450.patch From: "Ryan C. Gordon" Date: Sat, 27 Jan 2018 23:28:09 -0500 Subject: gif: report error on bogus LWZ data, instead of overflowing a buffer. Bug: https://security-tracker.debian.org/tracker/CVE-2017-14450 Origin: upstream, 2.0.3, commit:45e750f92c84, commit:https://github.com/libsdl-org/SDL_image/commit/4c830d4862461b5d0b086289b251b850884cbd57 --- IMG_gif.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/IMG_gif.c b/IMG_gif.c index de93fa7..321eea6 100644 --- a/IMG_gif.c +++ b/IMG_gif.c @@ -494,8 +494,10 @@ LWZReadByte(SDL_RWops *src, int flag, int input_code_size) } while (code >= clear_code) { *sp++ = table[1][code]; - if (code == table[0][code]) - RWSetMsg("circular table entry BIG ERROR"); + if (code == table[0][code]) { + RWSetMsg("circular table entry BIG ERROR"); + return -3; + } code = table[0][code]; } =============================== CVE-2018-3837.patch From: "Ryan C. Gordon" Date: Wed, 7 Feb 2018 15:43:51 -0500 Subject: pcx: don't overflow buffer if bytes-per-line is less than image width. Bug: https://security-tracker.debian.org/tracker/CVE-2018-3837 Origin: backport, 2.0.3, commit:2938fc80591a, commit:https://github.com/libsdl-org/SDL_image/commit/f6769997411b2152ed48d0ec11a062e363bf94fd --- IMG_pcx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IMG_pcx.c b/IMG_pcx.c index f62eac1..9f92a46 100644 --- a/IMG_pcx.c +++ b/IMG_pcx.c @@ -149,7 +149,7 @@ SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src) if (bpl > surface->pitch) { error = "bytes per line is too large (corrupt?)"; } - buf = malloc(bpl); + buf = calloc(SDL_max(bpl, surface->pitch), 1); row = surface->pixels; for ( y=0; yh; ++y ) { /* decode a scan line to a temporary buffer first */ =============================== CVE-2018-3838.patch From: "Ryan C. Gordon" Date: Wed, 7 Feb 2018 16:18:54 -0500 Subject: xcf: Prevent infinite loop and/or buffer overflow on bogus data. Bug: https://security-tracker.debian.org/tracker/CVE-2018-3838 Origin: upstream, 2.0.3, commit:c5f9cbb5d2bb, commit:https://github.com/libsdl-org/SDL_image/commit/4e006adf42593e8b0fd34b99f6f7b0b66f1e64f5 --- IMG_xcf.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/IMG_xcf.c b/IMG_xcf.c index 8a65507..6624a50 100644 --- a/IMG_xcf.c +++ b/IMG_xcf.c @@ -472,6 +472,10 @@ static unsigned char * load_xcf_tile_rle (SDL_RWops * src, Uint32 len, int bpp, int i, size, count, j, length; unsigned char val; + if (len == 0) { /* probably bogus data. */ + return NULL; + } + t = load = (unsigned char *) malloc (len); reallen = SDL_RWread (src, t, 1, len); @@ -604,6 +608,16 @@ static int do_layer_surface (SDL_Surface * surface, SDL_RWops * src, xcf_header ox, oy); } + if (!tile) { + if (hierarchy) { + free_xcf_hierarchy(hierarchy); + } + if (level) { + free_xcf_level(level); + } + return 1; + } + p8 = tile; p16 = (Uint16 *) p8; p = (Uint32 *) p8; =============================== CVE-2018-3839.patch From: "Ryan C. Gordon" Date: Wed, 7 Feb 2018 16:29:51 -0500 Subject: xcf: check for some potential integer overflows. Bug: https://security-tracker.debian.org/tracker/CVE-2018-3839 Origin: upstream, 2.0.3, commit:fb643e371806, commit:https://github.com/libsdl-org/SDL_image/commit/f9ad7549ad71609f6ea47c5951c7e09ad5d1a104.patch --- IMG_xcf.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/IMG_xcf.c b/IMG_xcf.c index 6624a50..064e641 100644 --- a/IMG_xcf.c +++ b/IMG_xcf.c @@ -582,6 +582,18 @@ static int do_layer_surface (SDL_Surface * surface, SDL_RWops * src, xcf_header SDL_RWseek (src, layer->hierarchy_file_offset, RW_SEEK_SET); hierarchy = read_xcf_hierarchy (src); + if (hierarchy->bpp > 4) { /* unsupported. */ + fprintf(stderr, "Unknown Gimp image bpp (%u)\n", (unsigned int) hierarchy->bpp); + free_xcf_hierarchy(hierarchy); + return 1; + } + + if ((hierarchy->width > 20000) || (hierarchy->height > 20000)) { /* arbitrary limit to avoid integer overflow. */ + fprintf(stderr, "Gimp image too large (%ux%u)\n", (unsigned int) hierarchy->width, (unsigned int) hierarchy->height); + free_xcf_hierarchy(hierarchy); + return 1; + } + level = NULL; for (i = 0; hierarchy->level_file_offsets [i]; i++) { SDL_RWseek (src, hierarchy->level_file_offsets [i], RW_SEEK_SET); =============================== CVE-2018-3977.patch From: "Ryan C. Gordon" Date: Wed, 26 Sep 2018 14:58:31 -0400 Subject: xcf: Fix potential buffer overflow on corrupt or maliciously-crafted XCF file. Bug: https://security-tracker.debian.org/tracker/CVE-2018-3977 Origin: upstream, 2.0.4, commit:170d7d32e4a8, commit:https://github.com/libsdl-org/SDL_image/commit/8373c58aa8c66e67e714e7a7caf8bd54ef162eac --- IMG_xcf.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/IMG_xcf.c b/IMG_xcf.c index 064e641..93b6929 100644 --- a/IMG_xcf.c +++ b/IMG_xcf.c @@ -634,6 +634,9 @@ static int do_layer_surface (SDL_Surface * surface, SDL_RWops * src, xcf_header p16 = (Uint16 *) p8; p = (Uint32 *) p8; for (y=ty; y < ty+oy; y++) { + if ((ty >= surface->h) || ((tx+ox) > surface->w)) { + break; + } row = (Uint32 *)((Uint8 *)surface->pixels + y*surface->pitch + tx*4); switch (hierarchy->bpp) { case 4: =============================== CVE-2019-12218.patch From: Sam Lantinga Date: Sun, 5 Dec 2021 11:11:54 +0000 Subject: Fixed TALOS-2019-0841, heap buffer overlow exploit Also fixed loading some images with incorrect palette location Bug: https://security-tracker.debian.org/tracker/CVE-2019-12218 Origin: backport, 2.0.5, commit:7453e79c8cdb, commit:https://github.com/libsdl-org/SDL_image/commit/782d29a101351cf48c9e9f42e625f76027a93c5d --- IMG_pcx.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/IMG_pcx.c b/IMG_pcx.c index 9f92a46..424810c 100644 --- a/IMG_pcx.c +++ b/IMG_pcx.c @@ -100,6 +100,8 @@ SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src) Uint8 *row, *buf = NULL; char *error = NULL; int bits, src_bits; + int count = 0; + Uint8 ch; if ( !src ) { /* The error message has been set in SDL_RWFromFile */ @@ -148,14 +150,14 @@ SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src) bpl = pcxh.NPlanes * pcxh.BytesPerLine; if (bpl > surface->pitch) { error = "bytes per line is too large (corrupt?)"; + goto done; } - buf = calloc(SDL_max(bpl, surface->pitch), 1); + buf = (Uint8 *)SDL_calloc(surface->pitch, 1); row = surface->pixels; for ( y=0; yh; ++y ) { /* decode a scan line to a temporary buffer first */ - int i, count = 0; - Uint8 ch; - Uint8 *dst = (src_bits == 8) ? row : buf; + int i; + Uint8 *dst = buf; if ( pcxh.Encoding == 0 ) { if(!SDL_RWread(src, dst, bpl, 1)) { error = "file truncated"; @@ -168,14 +170,15 @@ SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src) error = "file truncated"; goto done; } - if( (ch & 0xc0) == 0xc0) { - count = ch & 0x3f; + if( ch < 0xc0) { + count = 1; + } else { + count = ch - 0xc0; if(!SDL_RWread(src, &ch, 1, 1)) { error = "file truncated"; goto done; } - } else - count = 1; + } } dst[i] = ch; count--; @@ -207,10 +210,16 @@ SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src) int x; dst = row + plane; for(x = 0; x < width; x++) { + if ( dst >= row+surface->pitch ) { + error = "decoding out of bounds (corrupt?)"; + goto done; + } *dst = *src++; dst += pcxh.NPlanes; } } + } else { + SDL_memcpy(row, buf, bpl); } row += surface->pitch; @@ -227,8 +236,9 @@ SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src) /* look for a 256-colour palette */ do { if ( !SDL_RWread(src, &ch, 1, 1)) { - error = "file truncated"; - goto done; + /* Couldn't find the palette, try the end of the file */ + SDL_RWseek(src, -768, RW_SEEK_END); + break; } } while ( ch != 12 ); =============================== CVE-2019-5052.patch From: Sam Lantinga Date: Mon, 10 Jun 2019 13:12:46 -0700 Subject: Fixed TALOS-2019-0821, reading invalid data from the file when bpl is -1 Origin: upstream, 2.0.5, commit:b920be2b3fc6, commit:https://github.com/libsdl-org/SDL_image/commit/802a9ecaad2cebb18223ba69d6570069725c6a0d --- IMG_pcx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IMG_pcx.c b/IMG_pcx.c index 424810c..0116f17 100644 --- a/IMG_pcx.c +++ b/IMG_pcx.c @@ -148,7 +148,7 @@ SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src) goto done; bpl = pcxh.NPlanes * pcxh.BytesPerLine; - if (bpl > surface->pitch) { + if (bpl < 0 || bpl > surface->pitch) { error = "bytes per line is too large (corrupt?)"; goto done; } =============================== IMG_pcx-out-of-bounds.patch From: Sam Lantinga Date: Mon, 10 Jun 2019 15:41:09 -0700 Subject: Fixed bug 4628 - SEGV_UNKNOW in function SDL_free_REAL at SDL_malloc.c:5372-5 The PCX format specifies pcxh.BytesPerLine, which represents the size of a single plane's scanline in bytes. Valid PCX images should have pcxh.BytesPerLine >= surface->pitch. pcxh.BytesPerLine and surface->pitch can legitimately be different because pcxh.BytesPerLine is padded to be a multiple of machine word length (where file was created). If src_bits == 8 we directly read a whole scanline from src to row. This is a problem in the case where bpl > surface->pitch because row is too small. This allows attacker to perform unlimited OOB write on the heap. + remove pointless check bpl > surface->pitch, this is a valid situation + make sure we always read into buf which is big enough + in the case where src_bits == 8: copy these bytes back to row afterwar Bug: https://security-tracker.debian.org/tracker/CVE-2019-12217 Bug: https://security-tracker.debian.org/tracker/CVE-2019-12219 Bug: https://security-tracker.debian.org/tracker/CVE-2019-12220 Bug: https://security-tracker.debian.org/tracker/CVE-2019-12221 Bug: https://security-tracker.debian.org/tracker/CVE-2019-12222 Origin: upstream, 2.0.5, commit:e7e9786a1a34, commit:https://github.com/libsdl-org/SDL_image/commit/1559b5ce67e25c8de65f0d4af020c1ec50cb7b85 Co-authored-by: Hugo Lefeuvre --- IMG_pcx.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/IMG_pcx.c b/IMG_pcx.c index 0116f17..99af3f5 100644 --- a/IMG_pcx.c +++ b/IMG_pcx.c @@ -148,18 +148,17 @@ SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src) goto done; bpl = pcxh.NPlanes * pcxh.BytesPerLine; - if (bpl < 0 || bpl > surface->pitch) { - error = "bytes per line is too large (corrupt?)"; + buf = (Uint8 *)SDL_calloc(bpl, 1); + if ( !buf ) { + error = "Out of memory"; goto done; } - buf = (Uint8 *)SDL_calloc(surface->pitch, 1); row = surface->pixels; for ( y=0; yh; ++y ) { /* decode a scan line to a temporary buffer first */ int i; - Uint8 *dst = buf; if ( pcxh.Encoding == 0 ) { - if(!SDL_RWread(src, dst, bpl, 1)) { + if(!SDL_RWread(src, buf, bpl, 1)) { error = "file truncated"; goto done; } @@ -180,7 +179,7 @@ SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src) } } } - dst[i] = ch; + buf[i] = ch; count--; } } @@ -202,13 +201,21 @@ SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src) } } } + } else if ( src_bits == 8 ) { + /* directly copy buf content to row */ + Uint8 *innerSrc = buf; + int x; + Uint8 *dst = row; + for ( x = 0; x < width; x++ ) { + *dst++ = *innerSrc++; + } } else if(src_bits == 24) { /* de-interlace planes */ Uint8 *src = buf; int plane; for(plane = 0; plane < pcxh.NPlanes; plane++) { int x; - dst = row + plane; + Uint8 *dst = row + plane; for(x = 0; x < width; x++) { if ( dst >= row+surface->pitch ) { error = "decoding out of bounds (corrupt?)"; @@ -218,8 +225,6 @@ SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src) dst += pcxh.NPlanes; } } - } else { - SDL_memcpy(row, buf, bpl); } row += surface->pitch; =============================== CVE-2019-7635.patch From: Sam Lantinga Date: Sun, 5 Dec 2021 11:11:54 +0000 Subject: Fixed CVE-2019-7635 and bug 4498 - Heap-Buffer Overflow in Blit1to4 pertaining to SDL_blit_1.c The root cause is that the POC BMP file declares 3 colors used and 4 bpp palette, but pixel at line 28 and column 1 (counted from 0) has color number 3. Then when the image loaded into a surface is passed to SDL_DisplayFormat(), in order to convert it to a video format, a used bliting function looks up a color number 3 in a 3-element long color bliting map. (The map obviously has the same number entries as the surface format has colors.) Proper fix should refuse broken BMP images that have a pixel with a color index higher than declared number of "used" colors. Possibly more advanced fix could try to relocate the out-of-range color index into a vacant index (if such exists). Bug: https://security-tracker.debian.org/tracker/CVE-2019-7635 Origin: upstream, 2.0.5, commit:03bd33e8cb49, commit:https://github.com/libsdl-org/SDL_image/commit/66d067c406bc01b516a2cae804f5d09768f73855 Co-authored-by: Petr Pisar --- IMG_bmp.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/IMG_bmp.c b/IMG_bmp.c index a77d045..e4a394d 100644 --- a/IMG_bmp.c +++ b/IMG_bmp.c @@ -292,6 +292,14 @@ static SDL_Surface *LoadBMP_RW (SDL_RWops *src, int freesrc) ExpandBMP = biBitCount; biBitCount = 8; break; + case 2: + case 3: + case 5: + case 6: + case 7: + IMG_SetError("%d-bpp BMP images are not supported", biBitCount); + was_error = SDL_TRUE; + goto done; default: ExpandBMP = 0; break; @@ -444,7 +452,12 @@ static SDL_Surface *LoadBMP_RW (SDL_RWops *src, int freesrc) goto done; } } - *(bits+i) = (pixel>>shift); + bits[i] = (pixel >> shift); + if (bits[i] >= biClrUsed) { + IMG_SetError("A BMP image contains a pixel with a color out of the palette"); + was_error = SDL_TRUE; + goto done; + } pixel <<= ExpandBMP; } } break; @@ -456,6 +469,15 @@ static SDL_Surface *LoadBMP_RW (SDL_RWops *src, int freesrc) was_error = SDL_TRUE; goto done; } + if (biBitCount == 8 && palette && biClrUsed < (1 << biBitCount)) { + for (i = 0; i < surface->w; ++i) { + if (bits[i] >= biClrUsed) { + IMG_SetError("A BMP image contains a pixel with a color out of the palette"); + was_error = SDL_TRUE; + goto done; + } + } + } #if SDL_BYTEORDER == SDL_BIG_ENDIAN /* Byte-swap the pixels if needed. Note that the 24bpp case has already been taken care of above. */ @@ -650,6 +672,14 @@ LoadICOCUR_RW(SDL_RWops * src, int type, int freesrc) Bmask = 0x000000FF; ExpandBMP = 0; break; + case 2: + case 3: + case 5: + case 6: + case 7: + SDL_SetError("%d-bpp BMP images are not supported", biBitCount); + was_error = SDL_TRUE; + goto done; default: IMG_SetError("ICO file with unsupported bit count"); was_error = SDL_TRUE; =============================== CVE-2019-5058.patch From: Sam Lantinga Date: Mon, 10 Jun 2019 17:24:08 -0700 Subject: Fixed TALOS-2019-0842 - XCF Image Code Execution Vulnerability This patch addresses a bug in a previous security patch for CVE-2018-3977. The initial patch failing to address this issue, the bug was "re-discovered" later and addressed CVE-2019-5058. Bug: https://security-tracker.debian.org/tracker/CVE-2019-5058 Origin: upstream, 2.0.5, commit:b1a80aec2b10, commit:https://github.com/libsdl-org/SDL_image/commit/0c1db6f7bcf62feb897bc639976d118d2f3fa51b --- IMG_xcf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IMG_xcf.c b/IMG_xcf.c index 93b6929..e26f66d 100644 --- a/IMG_xcf.c +++ b/IMG_xcf.c @@ -634,7 +634,7 @@ static int do_layer_surface (SDL_Surface * surface, SDL_RWops * src, xcf_header p16 = (Uint16 *) p8; p = (Uint32 *) p8; for (y=ty; y < ty+oy; y++) { - if ((ty >= surface->h) || ((tx+ox) > surface->w)) { + if ((y >= surface->h) || ((tx+ox) > surface->w)) { break; } row = (Uint32 *)((Uint8 *)surface->pixels + y*surface->pitch + tx*4); =============================== CVE-2019-5059.patch From: Sam Lantinga Date: Mon, 10 Jun 2019 23:50:21 -0700 Subject: Fixed TALOS-2019-0843 - XPM image color code code execution vulnerability By providing a sufficiently large ncolors and cpp value, the buffer allocation size can overflow into a size too small to hold the color code string. This causes the memcpy to cause a heap overflow, potentially resulting in code execution. Bug: https://security-tracker.debian.org/tracker/CVE-2019-5059 Origin: backport, 2.0.5, commit:https://github.com/libsdl-org/SDL_image/commit/52b9d17eaf7b121c92328ce5d70c22be5739b0be --- IMG_xpm.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/IMG_xpm.c b/IMG_xpm.c index 486992f..438b78a 100644 --- a/IMG_xpm.c +++ b/IMG_xpm.c @@ -359,6 +359,11 @@ static SDL_Surface *load_xpm(char **xpm, SDL_RWops *src) goto done; } + /* Check for allocation overflow */ + if ((size_t)(ncolors * cpp)/cpp != ncolors) { + error = "Invalid color specification"; + goto done; + } keystrings = malloc(ncolors * cpp); if(!keystrings) { error = "Out of memory"; =============================== CVE-2019-5060.patch From: Sam Lantinga Date: Tue, 11 Jun 2019 00:15:06 -0700 Subject: Fixed TALOS-2019-0844 - XPM image colorhash parsing Code Execution Vulnerability The table entry in the color_hash is created in the create_colorhash function based on the number of colors passed into the function. The size of the color_hash table is the first value in the powers of 2 larger than the passed in number of colors [2]. The size of the allocation is this calculated value * 8 (sizeof(struct hash_entry **)) [3]. This multiplication can cause an overflow, resulting in a very small allocation. Bug: https://security-tracker.debian.org/tracker/CVE-2019-5060 Origin: backport, 2.0.5, commit:https://github.com/libsdl-org/SDL_image/commit/585b17706cbf1f553bfc507dd9ccbb8253611c9b --- IMG_xpm.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/IMG_xpm.c b/IMG_xpm.c index 438b78a..ce22ef4 100644 --- a/IMG_xpm.c +++ b/IMG_xpm.c @@ -106,7 +106,7 @@ static struct color_hash *create_colorhash(int maxnum) /* we know how many entries we need, so we can allocate everything here */ - hash = malloc(sizeof *hash); + hash = calloc(1, sizeof *hash); if(!hash) return NULL; @@ -115,13 +115,27 @@ static struct color_hash *create_colorhash(int maxnum) ; hash->size = s; hash->maxnum = maxnum; + bytes = hash->size * sizeof(struct hash_entry **); - hash->entries = NULL; /* in case malloc fails */ - hash->table = malloc(bytes); + /* Check for overflow */ + if ((bytes / sizeof(struct hash_entry **)) != hash->size) { + IMG_SetError("memory allocation overflow"); + free(hash); + return NULL; + } + hash->table = (struct hash_entry **)calloc(1, bytes); if(!hash->table) return NULL; - memset(hash->table, 0, bytes); - hash->entries = malloc(maxnum * sizeof(struct hash_entry)); + + bytes = maxnum * sizeof(struct hash_entry); + /* Check for overflow */ + if ((bytes / sizeof(struct hash_entry)) != maxnum) { + IMG_SetError("memory allocation overflow"); + free(hash->table); + free(hash); + return NULL; + } + hash->entries = (struct hash_entry *)calloc(1, bytes); if(!hash->entries) { free(hash->table); return NULL; =============================== CVE-2019-13616.patch From: Ozkan Sezer Date: Tue, 30 Jul 2019 21:29:15 +0300 Subject: Fixed bug 4538 - validate image size when loading BMP files Bug: https://security-tracker.debian.org/tracker/CVE-2019-13616 Origin: upstream, https://github.com/libsdl-org/SDL_image/commit/e12c931e5bb260821ac7f11833eb627331779dcf --- IMG_bmp.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/IMG_bmp.c b/IMG_bmp.c index e4a394d..a324099 100644 --- a/IMG_bmp.c +++ b/IMG_bmp.c @@ -272,6 +272,11 @@ static SDL_Surface *LoadBMP_RW (SDL_RWops *src, int freesrc) biClrUsed = SDL_ReadLE32(src); biClrImportant = SDL_ReadLE32(src); } + if (biWidth <= 0 || biHeight == 0) { + IMG_SetError("BMP file with bad dimensions (%dx%d)", biWidth, biHeight); + was_error = SDL_TRUE; + goto done; + } if (biHeight < 0) { topDown = SDL_TRUE; biHeight = -biHeight; =============================== showimage-Add-save-and-quit-options.patch From: Simon McVittie Date: Mon, 23 Sep 2019 15:37:05 +0100 Subject: showimage: Add -save and -quit options This allows showimage to be used as a non-interactive smoke-test to check that the SDL_image library can be linked against successfully. Signed-off-by: Simon McVittie --- showimage.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/showimage.c b/showimage.c index 6f29d7d..20601b6 100644 --- a/showimage.c +++ b/showimage.c @@ -77,11 +77,13 @@ int main(int argc, char *argv[]) { Uint32 flags; SDL_Surface *screen, *image; - int i, depth, done; + int i, depth; + int done = 0; SDL_Event event; #if 0 SDL_RWops* rw_ops; #endif + const char *saveFile = NULL; /* Check command line usage */ if ( ! argv[1] ) { @@ -102,6 +104,15 @@ int main(int argc, char *argv[]) flags |= SDL_FULLSCREEN; continue; } + if ( SDL_strcmp(argv[i], "-quit") == 0 ) { + done = 1; + continue; + } + if ( SDL_strcmp(argv[i], "-save") == 0 && argv[i+1] ) { + ++i; + saveFile = argv[i]; + continue; + } #if 0 rw_ops = SDL_RWFromFile(argv[1], "r"); @@ -125,6 +136,15 @@ int main(int argc, char *argv[]) argv[i], SDL_GetError()); continue; } + + if ( saveFile ) { + if ( SDL_SaveBMP(image, saveFile) == 0 ) { + fprintf(stderr, "Saved a copy of %s to %s\n", argv[i], saveFile); + } else { + fprintf(stderr, "Couldn't save a copy of %s to %s: %s\n", argv[i], saveFile, SDL_GetError()); + } + } + SDL_WM_SetCaption(argv[i], "showimage"); /* Create a display for the image */ @@ -164,7 +184,6 @@ int main(int argc, char *argv[]) SDL_BlitSurface(image, NULL, screen, NULL); SDL_UpdateRect(screen, 0, 0, 0, 0); - done = 0; while ( ! done ) { if ( SDL_PollEvent(&event) ) { switch (event.type) { =============================== bug809038.patch From: Sam Lantinga Date: Wed, 7 Feb 2018 14:21:26 -0800 Subject: Fixed bug Bug 3214 - SDL_image causes "libpng warning: Interlace handling should be turned on when using png_read_image" when loading interlaced images Hans de Goede When starting an app which uses SDL_image to load interlaced png-s with a recent libpng, the following message is printed to the terminal: libpng warning: Interlace handling should be turned on when using png_read_image Once per loaded png. The attached patch fixes this. Origin: backport, 2.0.3, commit:e63624fb63e063be67c788c29a3616ae02c18e99 --- IMG_png.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/IMG_png.c b/IMG_png.c index 5f91f15..613bf2c 100644 --- a/IMG_png.c +++ b/IMG_png.c @@ -95,6 +95,7 @@ static struct { void (*png_set_packing) (png_structp png_ptr); void (*png_set_read_fn) (png_structp png_ptr, png_voidp io_ptr, png_rw_ptr read_data_fn); void (*png_set_strip_16) (png_structp png_ptr); + int (*png_set_interlace_handling) (png_structp png_ptr); int (*png_sig_cmp) (png_bytep sig, png_size_t start, png_size_t num_to_check); #ifndef LIBPNG_VERSION_12 jmp_buf* (*png_set_longjmp_fn) (png_structp, png_longjmp_ptr, size_t); @@ -228,6 +229,13 @@ int IMG_InitPNG() SDL_UnloadObject(lib.handle); return -1; } + lib.png_set_interlace_handling = + (int (*) (png_structp)) + SDL_LoadFunction(lib.handle, "png_set_interlace_handling"); + if ( lib.png_set_interlace_handling == NULL ) { + SDL_UnloadObject(lib.handle); + return -1; + } lib.png_sig_cmp = (int (*) (png_bytep, png_size_t, png_size_t)) SDL_LoadFunction(lib.handle, "png_sig_cmp"); @@ -280,6 +288,7 @@ int IMG_InitPNG() lib.png_set_packing = png_set_packing; lib.png_set_read_fn = png_set_read_fn; lib.png_set_strip_16 = png_set_strip_16; + lib.png_set_interlace_handling = png_set_interlace_handling; lib.png_sig_cmp = png_sig_cmp; #ifndef LIBPNG_VERSION_12 lib.png_set_longjmp_fn = png_set_longjmp_fn; @@ -404,6 +413,9 @@ SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src) /* tell libpng to strip 16 bit/color files down to 8 bits/color */ lib.png_set_strip_16(png_ptr) ; + /* tell libpng to de-interlace (if the image is interlaced) */ + lib.png_set_interlace_handling(png_ptr); + /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single * byte into separate bytes (useful for paletted and grayscale images). */ =============================== png-fixes-for-building-against-libpng-1.6-and-fn.pointer-.patch From: Ozkan Sezer Date: Sun, 14 Oct 2018 15:00:50 +0300 Subject: png: fixes for building against libpng-1.6, and fn.pointer type fixes. from default branch commits f83e70f2ec6c, 4c41cee3e961, 777206f89dd2, 4c73e89f2551, 43873c313f32, e729829dbfc2, 4078e65827ea, ace61a625208, 218eb926ba90, 71f0d661144f, and 4b70bfe18fb7 -- bugs 1884, 1912, 3082, and 3214. Origin: upstream, commit:019f68f9f9460bdc37e5098d360ebc85758cae5c Bug-Debian: https://bugs.debian.org/1075498 --- IMG_png.c | 90 +++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 50 insertions(+), 40 deletions(-) diff --git a/IMG_png.c b/IMG_png.c index 613bf2c..ecf17b1 100644 --- a/IMG_png.c +++ b/IMG_png.c @@ -71,34 +71,44 @@ #include /* Check for the older version of libpng */ -#if (PNG_LIBPNG_VER_MAJOR == 1) && (PNG_LIBPNG_VER_MINOR < 4) +#if (PNG_LIBPNG_VER_MAJOR == 1) +#if (PNG_LIBPNG_VER_MINOR < 5) #define LIBPNG_VERSION_12 +typedef png_bytep png_const_bytep; +typedef png_color *png_const_colorp; +#endif +#if (PNG_LIBPNG_VER_MINOR < 6) +typedef png_structp png_const_structrp; +typedef png_infop png_const_inforp; +typedef png_structp png_structrp; +typedef png_infop png_inforp; +#endif #endif static struct { int loaded; void *handle; - png_infop (*png_create_info_struct) (png_structp png_ptr); + png_infop (*png_create_info_struct) (png_const_structrp png_ptr); png_structp (*png_create_read_struct) (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn); void (*png_destroy_read_struct) (png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr); - png_uint_32 (*png_get_IHDR) (png_structp png_ptr, png_infop info_ptr, png_uint_32 *width, png_uint_32 *height, int *bit_depth, int *color_type, int *interlace_method, int *compression_method, int *filter_method); - png_voidp (*png_get_io_ptr) (png_structp png_ptr); - png_byte (*png_get_channels) (png_structp png_ptr, png_infop info_ptr); - png_uint_32 (*png_get_PLTE) (png_structp png_ptr, png_infop info_ptr, png_colorp *palette, int *num_palette); - png_uint_32 (*png_get_tRNS) (png_structp png_ptr, png_infop info_ptr, png_bytep *trans, int *num_trans, png_color_16p *trans_values); - png_uint_32 (*png_get_valid) (png_structp png_ptr, png_infop info_ptr, png_uint_32 flag); - void (*png_read_image) (png_structp png_ptr, png_bytepp image); - void (*png_read_info) (png_structp png_ptr, png_infop info_ptr); - void (*png_read_update_info) (png_structp png_ptr, png_infop info_ptr); - void (*png_set_expand) (png_structp png_ptr); - void (*png_set_gray_to_rgb) (png_structp png_ptr); - void (*png_set_packing) (png_structp png_ptr); - void (*png_set_read_fn) (png_structp png_ptr, png_voidp io_ptr, png_rw_ptr read_data_fn); - void (*png_set_strip_16) (png_structp png_ptr); + png_uint_32 (*png_get_IHDR) (png_const_structrp png_ptr, png_const_inforp info_ptr, png_uint_32 *width, png_uint_32 *height, int *bit_depth, int *color_type, int *interlace_method, int *compression_method, int *filter_method); + png_voidp (*png_get_io_ptr) (png_const_structrp png_ptr); + png_byte (*png_get_channels) (png_const_structrp png_ptr, png_const_inforp info_ptr); + png_uint_32 (*png_get_PLTE) (png_const_structrp png_ptr, png_inforp info_ptr, png_colorp *palette, int *num_palette); + png_uint_32 (*png_get_tRNS) (png_const_structrp png_ptr, png_inforp info_ptr, png_bytep *trans, int *num_trans, png_color_16p *trans_values); + png_uint_32 (*png_get_valid) (png_const_structrp png_ptr, png_const_inforp info_ptr, png_uint_32 flag); + void (*png_read_image) (png_structrp png_ptr, png_bytepp image); + void (*png_read_info) (png_structrp png_ptr, png_inforp info_ptr); + void (*png_read_update_info) (png_structrp png_ptr, png_inforp info_ptr); + void (*png_set_expand) (png_structrp png_ptr); + void (*png_set_gray_to_rgb) (png_structrp png_ptr); + void (*png_set_packing) (png_structrp png_ptr); + void (*png_set_read_fn) (png_structrp png_ptr, png_voidp io_ptr, png_rw_ptr read_data_fn); + void (*png_set_strip_16) (png_structrp png_ptr); int (*png_set_interlace_handling) (png_structp png_ptr); - int (*png_sig_cmp) (png_bytep sig, png_size_t start, png_size_t num_to_check); + int (*png_sig_cmp) (png_const_bytep sig, png_size_t start, png_size_t num_to_check); #ifndef LIBPNG_VERSION_12 - jmp_buf* (*png_set_longjmp_fn) (png_structp, png_longjmp_ptr, size_t); + jmp_buf* (*png_set_longjmp_fn) (png_structrp, png_longjmp_ptr, size_t); #endif } lib; @@ -111,14 +121,14 @@ int IMG_InitPNG() return -1; } lib.png_create_info_struct = - (png_infop (*) (png_structp)) + (png_infop (*) (png_const_structrp)) SDL_LoadFunction(lib.handle, "png_create_info_struct"); if ( lib.png_create_info_struct == NULL ) { SDL_UnloadObject(lib.handle); return -1; } lib.png_create_read_struct = - (png_structp (*) (png_const_charp, png_voidp, png_error_ptr, png_error_ptr)) + (png_structrp (*) (png_const_charp, png_voidp, png_error_ptr, png_error_ptr)) SDL_LoadFunction(lib.handle, "png_create_read_struct"); if ( lib.png_create_read_struct == NULL ) { SDL_UnloadObject(lib.handle); @@ -132,112 +142,112 @@ int IMG_InitPNG() return -1; } lib.png_get_IHDR = - (png_uint_32 (*) (png_structp, png_infop, png_uint_32 *, png_uint_32 *, int *, int *, int *, int *, int *)) + (png_uint_32 (*) (png_const_structrp, png_const_inforp, png_uint_32 *, png_uint_32 *, int *, int *, int *, int *, int *)) SDL_LoadFunction(lib.handle, "png_get_IHDR"); if ( lib.png_get_IHDR == NULL ) { SDL_UnloadObject(lib.handle); return -1; } lib.png_get_channels = - (png_byte (*) (png_structp, png_infop)) + (png_byte (*) (png_const_structrp, png_const_inforp)) SDL_LoadFunction(lib.handle, "png_get_channels"); if ( lib.png_get_channels == NULL ) { SDL_UnloadObject(lib.handle); return -1; } lib.png_get_io_ptr = - (png_voidp (*) (png_structp)) + (png_voidp (*) (png_const_structrp)) SDL_LoadFunction(lib.handle, "png_get_io_ptr"); if ( lib.png_get_io_ptr == NULL ) { SDL_UnloadObject(lib.handle); return -1; } lib.png_get_PLTE = - (png_uint_32 (*) (png_structp, png_infop, png_colorp *, int *)) + (png_uint_32 (*) (png_const_structrp, png_inforp, png_colorp *, int *)) SDL_LoadFunction(lib.handle, "png_get_PLTE"); if ( lib.png_get_PLTE == NULL ) { SDL_UnloadObject(lib.handle); return -1; } lib.png_get_tRNS = - (png_uint_32 (*) (png_structp, png_infop, png_bytep *, int *, png_color_16p *)) + (png_uint_32 (*) (png_const_structrp, png_inforp, png_bytep *, int *, png_color_16p *)) SDL_LoadFunction(lib.handle, "png_get_tRNS"); if ( lib.png_get_tRNS == NULL ) { SDL_UnloadObject(lib.handle); return -1; } lib.png_get_valid = - (png_uint_32 (*) (png_structp, png_infop, png_uint_32)) + (png_uint_32 (*) (png_const_structrp, png_const_inforp, png_uint_32)) SDL_LoadFunction(lib.handle, "png_get_valid"); if ( lib.png_get_valid == NULL ) { SDL_UnloadObject(lib.handle); return -1; } lib.png_read_image = - (void (*) (png_structp, png_bytepp)) + (void (*) (png_structrp, png_bytepp)) SDL_LoadFunction(lib.handle, "png_read_image"); if ( lib.png_read_image == NULL ) { SDL_UnloadObject(lib.handle); return -1; } lib.png_read_info = - (void (*) (png_structp, png_infop)) + (void (*) (png_structrp, png_inforp)) SDL_LoadFunction(lib.handle, "png_read_info"); if ( lib.png_read_info == NULL ) { SDL_UnloadObject(lib.handle); return -1; } lib.png_read_update_info = - (void (*) (png_structp, png_infop)) + (void (*) (png_structrp, png_inforp)) SDL_LoadFunction(lib.handle, "png_read_update_info"); if ( lib.png_read_update_info == NULL ) { SDL_UnloadObject(lib.handle); return -1; } lib.png_set_expand = - (void (*) (png_structp)) + (void (*) (png_structrp)) SDL_LoadFunction(lib.handle, "png_set_expand"); if ( lib.png_set_expand == NULL ) { SDL_UnloadObject(lib.handle); return -1; } lib.png_set_gray_to_rgb = - (void (*) (png_structp)) + (void (*) (png_structrp)) SDL_LoadFunction(lib.handle, "png_set_gray_to_rgb"); if ( lib.png_set_gray_to_rgb == NULL ) { SDL_UnloadObject(lib.handle); return -1; } lib.png_set_packing = - (void (*) (png_structp)) + (void (*) (png_structrp)) SDL_LoadFunction(lib.handle, "png_set_packing"); if ( lib.png_set_packing == NULL ) { SDL_UnloadObject(lib.handle); return -1; } lib.png_set_read_fn = - (void (*) (png_structp, png_voidp, png_rw_ptr)) + (void (*) (png_structrp, png_voidp, png_rw_ptr)) SDL_LoadFunction(lib.handle, "png_set_read_fn"); if ( lib.png_set_read_fn == NULL ) { SDL_UnloadObject(lib.handle); return -1; } lib.png_set_strip_16 = - (void (*) (png_structp)) + (void (*) (png_structrp)) SDL_LoadFunction(lib.handle, "png_set_strip_16"); if ( lib.png_set_strip_16 == NULL ) { SDL_UnloadObject(lib.handle); return -1; } lib.png_set_interlace_handling = - (int (*) (png_structp)) + (void (*) (png_structp)) SDL_LoadFunction(lib.handle, "png_set_interlace_handling"); if ( lib.png_set_interlace_handling == NULL ) { SDL_UnloadObject(lib.handle); return -1; } lib.png_sig_cmp = - (int (*) (png_bytep, png_size_t, png_size_t)) + (int (*) (png_const_bytep, png_size_t, png_size_t)) SDL_LoadFunction(lib.handle, "png_sig_cmp"); if ( lib.png_sig_cmp == NULL ) { SDL_UnloadObject(lib.handle); @@ -245,7 +255,7 @@ int IMG_InitPNG() } #ifndef LIBPNG_VERSION_12 lib.png_set_longjmp_fn = - (jmp_buf * (*) (png_structp, png_longjmp_ptr, size_t)) + (jmp_buf * (*) (png_structrp, png_longjmp_ptr, size_t)) SDL_LoadFunction(lib.handle, "png_set_longjmp_fn"); if ( lib.png_set_longjmp_fn == NULL ) { SDL_UnloadObject(lib.handle); @@ -527,9 +537,9 @@ SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src) if(color_type == PNG_COLOR_TYPE_GRAY) { palette->ncolors = 256; for(i = 0; i < 256; i++) { - palette->colors[i].r = i; - palette->colors[i].g = i; - palette->colors[i].b = i; + palette->colors[i].r = (Uint8)i; + palette->colors[i].g = (Uint8)i; + palette->colors[i].b = (Uint8)i; } } else if (png_num_palette > 0 ) { palette->ncolors = png_num_palette; =============================== IMG_webp.c-update-to-accomodate-libwebp-abi-changes-since.patch From: Ozkan Sezer Date: Wed, 17 Oct 2018 01:00:32 +0300 Subject: IMG_webp.c: update to accomodate libwebp abi changes since v0.1.99: libwebp < v0.1.99 is incompatible with current versions of the library because the decode function signatures have changed to use size_t over int/uint32_t. This changeset backports three SDL2 commits listed below and copies the Windows and OSX binaries to match it. It also adds compile time checks for (WEBP_DECODER_ABI_VERSION < 0x0100) in order to properly define the function pointers: WEBP_DECODER_ABI_VERSION values are from decoder.h header as found in libwebp git tags at: https://chromium.googlesource.com/webm/libwebp/+refs 0x0100 corresponds to the abi version in 0.1.99 prerelease version. Backported SDL2 commits are as follows: r360: https://hg.libsdl.org/SDL_image/rev/3d002acf103d r378: https://hg.libsdl.org/SDL_image/rev/f83e70f2ec6c r531: https://hg.libsdl.org/SDL_image/rev/4491ac456363 Origin: upstream, commit:abb2c39f0326bd5ec3ebde314907c71a8487e997 Bug-Debian: https://bugs.debian.org/1075498 --- IMG_webp.c | 64 +++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/IMG_webp.c b/IMG_webp.c index 94727ce..e67b95e 100644 --- a/IMG_webp.c +++ b/IMG_webp.c @@ -47,9 +47,15 @@ static struct { int loaded; void *handle; +#if WEBP_DECODER_ABI_VERSION < 0x0100 int/*VP8StatuCode*/ (*webp_get_features_internal) (const uint8_t *data, uint32_t data_size, WebPBitstreamFeatures* const features, int decoder_abi_version); uint8_t* (*webp_decode_rgb_into) (const uint8_t* data, uint32_t data_size, uint8_t* output_buffer, int output_buffer_size, int output_stride); uint8_t* (*webp_decode_rgba_into) (const uint8_t* data, uint32_t data_size, uint8_t* output_buffer, int output_buffer_size, int output_stride); +#else + VP8StatusCode (*webp_get_features_internal) (const uint8_t *data, size_t data_size, WebPBitstreamFeatures* features, int decoder_abi_version); + uint8_t* (*webp_decode_rgb_into) (const uint8_t* data, size_t data_size, uint8_t* output_buffer, size_t output_buffer_size, int output_stride); + uint8_t* (*webp_decode_rgba_into) (const uint8_t* data, size_t data_size, uint8_t* output_buffer, size_t output_buffer_size, int output_stride); +#endif } lib; #ifdef LOAD_WEBP_DYNAMIC @@ -60,8 +66,13 @@ int IMG_InitWEBP() if ( lib.handle == NULL ) { return -1; } + lib.webp_get_features_internal = + #if WEBP_DECODER_ABI_VERSION < 0x0100 ( int (*) (const uint8_t *, uint32_t, WebPBitstreamFeatures* const, int) ) + #else + ( VP8StatusCode (*) (const uint8_t *, size_t, WebPBitstreamFeatures*, int) ) + #endif SDL_LoadFunction(lib.handle, "WebPGetFeaturesInternal" ); if ( lib.webp_get_features_internal == NULL ) { SDL_UnloadObject(lib.handle); @@ -69,7 +80,11 @@ int IMG_InitWEBP() } lib.webp_decode_rgb_into = + #if WEBP_DECODER_ABI_VERSION < 0x0100 ( uint8_t* (*) (const uint8_t*, uint32_t, uint8_t*, int, int ) ) + #else + ( uint8_t* (*) (const uint8_t*, size_t, uint8_t*, size_t, int ) ) + #endif SDL_LoadFunction(lib.handle, "WebPDecodeRGBInto" ); if ( lib.webp_decode_rgb_into == NULL ) { SDL_UnloadObject(lib.handle); @@ -77,8 +92,12 @@ int IMG_InitWEBP() } lib.webp_decode_rgba_into = + #if WEBP_DECODER_ABI_VERSION < 0x0100 ( uint8_t* (*) (const uint8_t*, uint32_t, uint8_t*, int, int ) ) - SDL_LoadFunction(lib.handle, "WebPDecodeRGBInto" ); + #else + ( uint8_t* (*) (const uint8_t*, size_t, uint8_t*, size_t, int ) ) + #endif + SDL_LoadFunction(lib.handle, "WebPDecodeRGBAInto" ); if ( lib.webp_decode_rgba_into == NULL ) { SDL_UnloadObject(lib.handle); return -1; @@ -124,30 +143,36 @@ void IMG_QuitWEBP() static int webp_getinfo( SDL_RWops *src, int *datasize ) { int start; int is_WEBP; - int data; Uint8 magic[20]; - if ( !src ) + if ( !src ) { return 0; + } start = SDL_RWtell(src); is_WEBP = 0; if ( SDL_RWread(src, magic, 1, sizeof(magic)) == sizeof(magic) ) { if ( magic[ 0] == 'R' && - magic[ 1] == 'I' && - magic[ 2] == 'F' && - magic[ 3] == 'F' && - magic[ 8] == 'W' && - magic[ 9] == 'E' && - magic[10] == 'B' && - magic[11] == 'P' && - magic[12] == 'V' && - magic[13] == 'P' && - magic[14] == '8' && - magic[15] == ' ' ) { + magic[ 1] == 'I' && + magic[ 2] == 'F' && + magic[ 3] == 'F' && + magic[ 8] == 'W' && + magic[ 9] == 'E' && + magic[10] == 'B' && + magic[11] == 'P' && + magic[12] == 'V' && + magic[13] == 'P' && + magic[14] == '8' && + /* old versions don't support VP8X and VP8L */ + #if (WEBP_DECODER_ABI_VERSION < 0x0003) + magic[15] == ' ' + #else + (magic[15] == ' ' || magic[15] == 'X' || magic[15] == 'L') + #endif + ) { is_WEBP = 1; - data = magic[16] | magic[17]<<8 | magic[18]<<16 | magic[19]<<24; - if ( datasize ) - *datasize = data; + if ( datasize ) { + *datasize = SDL_RWseek(src, 0, RW_SEEK_END) - start; + } } } SDL_RWseek(src, start, RW_SEEK_SET); @@ -193,12 +218,9 @@ SDL_Surface *IMG_LoadWEBP_RW(SDL_RWops *src) goto error; } - // skip header - SDL_RWseek(src, start+20, RW_SEEK_SET ); - raw_data = (uint8_t*) malloc( raw_data_size ); if ( raw_data == NULL ) { - error = "Failed to allocate enought buffer for WEBP"; + error = "Failed to allocate enough buffer for WEBP"; goto error; }