Description: Security fixes from FreeXL 1.0.5.
 heap-buffer-overflow in freexl::destroy_cell of FreeXL 1.0.4
 https://bugzilla.redhat.com/show_bug.cgi?id=1547879
 .
 heap-buffer-overflow in freexl.c:1805 parse_SST parse_SST
 https://bugzilla.redhat.com/show_bug.cgi?id=1547883
 .
 heap-buffer-overflow in freexl.c:1866 parse_SST of FreeXL 1.0.4
 https://bugzilla.redhat.com/show_bug.cgi?id=1547885
 .
 heap-buffer-overflow in freexl.c:383 parse_unicode_string of FreeXL 1.0.4
 https://bugzilla.redhat.com/show_bug.cgi?id=1547889
 .
 heap-buffer-overflow in freexl.c:3912 read_mini_biff_next_record of FreeXL 1.0.4
 https://bugzilla.redhat.com/show_bug.cgi?id=1547892
 .
 Reported upstream in:
 https://groups.google.com/d/topic/spatialite-users/b-d9iB5TDPE/discussion
Author: Alessandro Furieri <a.furieri@lqt.it>
Origin: https://www.gaia-gis.it/fossil/freexl/ci/1f00f424a24b355e?sbs=0
        https://www.gaia-gis.it/fossil/freexl/ci/97c9f43cea4fcd54?sbs=0
        https://www.gaia-gis.it/fossil/freexl/ci/9907dcec7fc34a91?sbs=0

--- a/headers/freexl.h
+++ b/headers/freexl.h
@@ -292,6 +292,11 @@ extern "C"
 #define FREEXL_CFBF_ILLEGAL_MINI_FAT_ENTRY	-25 /**< The MiniFAT stream 
                                                      contains an invalid entry.
                                                      Possibly a corrupt file. */
+#define FREEXL_CRAFTED_FILE			-26 /**< A severely corrupted file
+                                                 (may be purposely crafted for 
+                                                 malicious purposes) has been 
+                                                 detected. */
+
 
     /**
      Container for a cell value
--- a/src/freexl.c
+++ b/src/freexl.c
@@ -1108,6 +1108,11 @@ allocate_cells (biff_workbook * workbook
 	return FREEXL_INSUFFICIENT_MEMORY;
 
 /* allocating the cell values array */
+    if (workbook->active_sheet->rows * workbook->active_sheet->columns <= 0)
+      {
+	  workbook->active_sheet->cell_values = NULL;
+	  return FREEXL_OK;
+      }
     workbook->active_sheet->cell_values =
 	malloc (sizeof (biff_cell_value) *
 		(workbook->active_sheet->rows *
@@ -1798,6 +1803,12 @@ parse_SST (biff_workbook * workbook, int
 		      unsigned int i;
 		      for (i = 0; i < len; i++)
 			{
+			    if (p_string - workbook->record >=
+				workbook->record_size)
+			      {
+				  /* buffer overflow: it's a preasumable crafted file intended to crash FreeXL */
+				  return FREEXL_CRAFTED_FILE;
+			      }
 			    *(utf16_buf + (utf16_off * 2) + (i * 2)) =
 				*p_string;
 			    p_string++;
@@ -1898,6 +1909,11 @@ parse_SST (biff_workbook * workbook, int
 		return FREEXL_OK;
 	    }
 
+	  if (len <= 0)
+	    {
+		/* zero length - it's a preasumable crafted file intended to crash FreeXL */
+		return FREEXL_CRAFTED_FILE;
+	    }
 	  if (!parse_unicode_string
 	      (workbook->utf16_converter, len, utf16, p_string, &utf8_string))
 	      return FREEXL_INVALID_CHARACTER;
@@ -3051,6 +3067,11 @@ parse_biff_record (biff_workbook * workb
 	  if (swap)
 	      swap32 (&offset);
 	  len = workbook->record[6];
+	  if (len <= 0)
+	    {
+		/* zero length - it's a preasumable crafted file intended to crash FreeXL */
+		return FREEXL_CRAFTED_FILE;
+	    }
 	  if (workbook->biff_version == FREEXL_BIFF_VER_5)
 	    {
 		/* BIFF5: codepage text */
@@ -3210,6 +3231,11 @@ parse_biff_record (biff_workbook * workb
 		get_unicode_params (p_string, swap, &start_offset, &utf16,
 				    &extra_skip);
 		p_string += start_offset;
+		if (len <= 0)
+		  {
+		      /* zero length - it's a preasumable crafted file intended to crash FreeXL */
+		      return FREEXL_CRAFTED_FILE;
+		  }
 		if (!parse_unicode_string
 		    (workbook->utf16_converter, len, utf16, p_string,
 		     &utf8_string))
@@ -3604,6 +3630,11 @@ parse_biff_record (biff_workbook * workb
 		get_unicode_params (p_string, swap, &start_offset, &utf16,
 				    &extra_skip);
 		p_string += start_offset;
+		if (len <= 0)
+		  {
+		      /* zero length - it's a preasumable crafted file intended to crash FreeXL */
+		      return FREEXL_CRAFTED_FILE;
+		  }
 		if (!parse_unicode_string
 		    (workbook->utf16_converter, len, utf16, p_string,
 		     &utf8_string))
@@ -3886,6 +3917,9 @@ read_mini_biff_next_record (biff_workboo
     workbook->record_type = record_type.value;
     workbook->record_size = record_size.value;
 
+    if (workbook->record_size >= 8192)
+	return 0;		/* malformed or crafted file */
+
     if ((workbook->p_in - workbook->fat->miniStream) + workbook->record_size >
 	(int) workbook->size)
 	return 0;		/* unexpected EOF */
