Description: fix heap buffer overflow issue in IMG_pcx.c
 Issue known as TALOS-2019-0841, CVE-2019-12218.
Author: Sam Lantinga <slouken@libsdl.org>
Origin: upstream, https://hg.libsdl.org/SDL_image/rev/7453e79c8cdb
--- a/IMG_pcx.c	2019-07-27 13:21:30.158367768 -0300
+++ b/IMG_pcx.c	2019-07-27 13:21:30.154367811 -0300
@@ -100,6 +100,8 @@
     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 @@
     bpl = pcxh.NPlanes * pcxh.BytesPerLine;
     if (bpl > surface->pitch) {
         error = "bytes per line is too large (corrupt?)";
+        goto done;
     }
-    buf = (Uint8 *)SDL_calloc(SDL_max(bpl, surface->pitch), 1);
+    buf = (Uint8 *)SDL_calloc(surface->pitch, 1);
     row = (Uint8 *)surface->pixels;
     for ( y=0; y<surface->h; ++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 @@
                         error = "file truncated";
                         goto done;
                     }
-                    if( (ch & 0xc0) == 0xc0) {
-                        count = ch & 0x3f;
-                        if(!SDL_RWread(src, &ch, 1, 1)) {
+                    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 @@
                 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 = *innerSrc++;
                     dst += pcxh.NPlanes;
                 }
             }
+        } else {
+            SDL_memcpy(row, buf, bpl);
         }
 
         row += surface->pitch;
@@ -227,8 +236,9 @@
             /* 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 );
 
