# HG changeset patch
# User Thomas Bernard <miniupnp@free.fr>
# Date 1543572255 -3600
#      Fri Nov 30 11:04:15 2018 +0100
# Branch SDL-1.2
# Node ID 68f958f43339b1aa1ad61d470dc8a6b9ef670dcf
# Parent  89225c8816d6d487bee10642d0380442dc19490d
IMG_xcf.c: Avoid infinite loop in read_xcf_header()

diff -r 89225c8816d6 -r 68f958f43339 IMG_xcf.c
--- a/IMG_xcf.c	Tue Oct 23 23:00:02 2018 +0300
+++ b/IMG_xcf.c	Fri Nov 30 11:04:15 2018 +0100
@@ -263,12 +263,12 @@
     |  ((v & 0xFF000000));
 }
 
-static void xcf_read_property (SDL_RWops * src, xcf_prop * prop) {
+static int xcf_read_property (SDL_RWops * src, xcf_prop * prop) {
   prop->id = SDL_ReadBE32 (src);
   prop->length = SDL_ReadBE32 (src);
 
 #if DEBUG
-  printf ("%.8X: %s: %d\n", SDL_RWtell (src), prop->id < 25 ? prop_names [prop->id] : "unknown", prop->length);
+  printf ("%.8X: %s(%u): %u\n", SDL_RWtell (src), prop->id < 25 ? prop_names [prop->id] : "unknown", prop->id, prop->length);
 #endif
 
   switch (prop->id) {
@@ -301,8 +301,10 @@
     break;
   default:
     //    SDL_RWread (src, &prop->data, prop->length, 1);
-    SDL_RWseek (src, prop->length, RW_SEEK_CUR);
+    if (SDL_RWseek (src, prop->length, RW_SEEK_CUR) < 0)
+      return 0;  // ERROR
   }
+  return 1;  // OK
 }
 
 static void free_xcf_header (xcf_header * h) {
@@ -325,6 +327,10 @@
   h->width       = SDL_ReadBE32 (src);
   h->height      = SDL_ReadBE32 (src);
   h->image_type  = SDL_ReadBE32 (src);
+#ifdef DEBUG
+  printf ("XCF signature : %.14s\n", h->sign);
+  printf (" (%u,%u) type=%u\n", h->width, h->height, h->image_type);
+#endif
 
   h->properties = NULL;
   h->layer_file_offsets = NULL;
@@ -334,7 +340,10 @@
 
   // Just read, don't save
   do {
-    xcf_read_property (src, &prop);
+    if (!xcf_read_property (src, &prop)) {
+      free_xcf_header (h);
+      return NULL;
+    }
     if (prop.id == PROP_COMPRESSION)
       h->compr = (xcf_compr_type)prop.data.compression;
     else if (prop.id == PROP_COLORMAP) {
@@ -378,7 +387,10 @@
   l->name = read_string (src);
 
   do {
-    xcf_read_property (src, &prop);
+    if (!xcf_read_property (src, &prop)) {
+      free_xcf_layer (l);
+      return NULL;
+    }
     if (prop.id == PROP_OFFSETS) {
       l->offset_x = prop.data.offset.x;
       l->offset_y = prop.data.offset.y;
@@ -410,7 +422,10 @@
 
   l->selection = 0;
   do {
-    xcf_read_property (src, &prop);
+    if (!xcf_read_property (src, &prop)) {
+      free_xcf_channel (l);
+      return NULL;
+    }
     switch (prop.id) {
     case PROP_OPACITY:
       l->opacity = prop.data.opacity << 24;
