gnumeric r16347 - in trunk: . plugins/excel



Author: mortenw
Date: Tue Feb  5 03:14:04 2008
New Revision: 16347
URL: http://svn.gnome.org/viewvc/gnumeric?rev=16347&view=rev

Log:
2008-02-04  Morten Welinder  <terra gnome org>

	* ms-excel-read.c (excel_biff_text, excel_biff_text_1,
	excel_biff_text_2): New functions.  Use these where possible to
	add length checks.

	* ms-chart.c (ai): Handle missing series.  Fixes #514435.
	(fontx): Add length checks.  Fixes #514436.
	* ms-biff.c (ms_biff_query_set_decrypt): Handle empty record.
	Fixes #514437.




Modified:
   trunk/NEWS
   trunk/plugins/excel/ChangeLog
   trunk/plugins/excel/ms-biff.c
   trunk/plugins/excel/ms-chart.c
   trunk/plugins/excel/ms-excel-read.c

Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS	(original)
+++ trunk/NEWS	Tue Feb  5 03:14:04 2008
@@ -21,7 +21,8 @@
 	* Fix solver issue.  [#512500]
 	* Fix corrupted-xls-file problems.  [#512984] [#513005] [#513313]
 	  [#513317] [#513361] [#513364] [#513551] [#513605] [#513608] [#513790]
-	  [#513787] [#513835] [#513963] [#514229] [#514230] [#514295]
+	  [#513787] [#513835] [#513963] [#514229] [#514230] [#514295] [#514435]
+	  [#514436] [#514437]
 	* Fix non-ascii export problem.  [#511135]
 	* Band-aid evaluation problem with broken xls.  [#513559]
 	* Fix circular array formula problem.

Modified: trunk/plugins/excel/ms-biff.c
==============================================================================
--- trunk/plugins/excel/ms-biff.c	(original)
+++ trunk/plugins/excel/ms-biff.c	Tue Feb  5 03:14:04 2008
@@ -319,7 +319,7 @@
 	if (password == NULL)
 		return FALSE;
 
-	if (version < MS_BIFF_V8 || q->data[0] == 0)
+	if (version < MS_BIFF_V8 || q->length == 0 || q->data[0] == 0)
 		return ms_biff_pre_biff8_query_set_decrypt (q, password);
 
 	XL_CHECK_CONDITION_VAL (q->length == sizeof_BIFF_8_FILEPASS, FALSE);

Modified: trunk/plugins/excel/ms-chart.c
==============================================================================
--- trunk/plugins/excel/ms-chart.c	(original)
+++ trunk/plugins/excel/ms-chart.c	Tue Feb  5 03:14:04 2008
@@ -364,6 +364,7 @@
 				: gnm_go_data_vector_new_expr (sheet, texpr);
 		}
 	} else if (ref_type == 1 && purpose != GOG_MS_DIM_LABELS &&
+		   s->currentSeries &&
 		   s->currentSeries->data [purpose].num_elements > 0) {
 		if (s->currentSeries->data [purpose].value)
 			g_warning ("Leak?");
@@ -981,9 +982,16 @@
 BC_R(fontx)(XLChartHandler const *handle,
 	    XLChartReadState *s, BiffQuery *q)
 {
-	ExcelFont const *font = excel_font_get (s->container.importer,
-		GSF_LE_GET_GUINT16 (q->data));
-	GOFont const *gfont = excel_font_get_gofont (font);
+	ExcelFont const *font;
+	GOFont const *gfont;
+
+	XL_CHECK_CONDITION_VAL (q->length >= 2, FALSE);
+	font = excel_font_get (s->container.importer,
+			       GSF_LE_GET_GUINT16 (q->data));
+	if (!font)
+		return FALSE;
+
+	gfont = excel_font_get_gofont (font);
 	go_font_ref (gfont);
 	BC_R(get_style) (s);
 	gog_style_set_font (s->style, gfont);

Modified: trunk/plugins/excel/ms-excel-read.c
==============================================================================
--- trunk/plugins/excel/ms-excel-read.c	(original)
+++ trunk/plugins/excel/ms-excel-read.c	Tue Feb  5 03:14:04 2008
@@ -902,22 +902,14 @@
 	return ans;
 }
 
-/**
- * excel_get_text :
- * @importer :
- * @pos : pointer to the start of string information
- * @length : in _characters_
- * @byte_len : The number of bytes between @pos and the end of string data
- *
- * Returns a string which the caller is responsible for freeing
- **/
-char *
-excel_get_text (GnmXLImporter const *importer,
-		guint8 const *pos, guint32 length, guint32 *byte_length)
+static char *
+excel_get_text_full (GnmXLImporter const *importer,
+		     guint8 const *pos, guint32 length,
+		     guint32 *byte_length, guint32 maxlen)
 {
 	char *ans;
 	guint8 const *ptr;
-	unsigned byte_len, trailing_data_len, n_markup;
+	unsigned byte_len, trailing_data_len, n_markup, str_len_bytes;
 	gboolean use_utf16, has_extended;
 
 	if (byte_length == NULL)
@@ -940,7 +932,16 @@
 		ptr = pos;
 	}
 
-	*byte_length += (use_utf16 ? 2 : 1) * length;
+	str_len_bytes = (use_utf16 ? 2 : 1) * length;
+	if (*byte_length > maxlen) {
+		*byte_length = maxlen;
+		length = 0;
+	} else if (maxlen - *byte_length < str_len_bytes) {
+		*byte_length = maxlen;
+		length = (maxlen - *byte_length) / (use_utf16 ? 2 : 1);
+	} else
+		*byte_length += str_len_bytes;
+
 	ans = excel_get_chars (importer, ptr, length, use_utf16);
 
 	d (4, {
@@ -955,6 +956,61 @@
 	return ans;
 }
 
+/**
+ * excel_get_text :
+ * @importer :
+ * @pos : pointer to the start of string information
+ * @length : in _characters_
+ * @byte_len : The number of bytes between @pos and the end of string data
+ *
+ * Returns a string which the caller is responsible for freeing
+ **/
+char *
+excel_get_text (GnmXLImporter const *importer,
+		guint8 const *pos, guint32 length, guint32 *byte_length)
+{
+	return excel_get_text_full (importer, pos, length, byte_length,
+				    G_MAXUINT);
+}
+
+static char *
+excel_biff_text (GnmXLImporter const *importer,
+		 const BiffQuery *q, guint32 ofs, guint32 length)
+{
+	XL_CHECK_CONDITION_VAL (q->length >= ofs, NULL);
+
+	return excel_get_text_full (importer, q->data + ofs, length,
+				    NULL, q->length - ofs);
+}
+
+static char *
+excel_biff_text_1 (GnmXLImporter const *importer,
+		   const BiffQuery *q, guint32 ofs)
+{
+	guint32 length;
+
+	XL_CHECK_CONDITION_VAL (q->length > ofs, NULL);
+	length = GSF_LE_GET_GUINT8 (q->data + ofs);
+	ofs++;
+
+	return excel_get_text_full (importer, q->data + ofs, length,
+				    NULL, q->length - ofs);
+}
+
+static char *
+excel_biff_text_2 (GnmXLImporter const *importer,
+		   const BiffQuery *q, guint32 ofs)
+{
+	guint32 length;
+
+	XL_CHECK_CONDITION_VAL (q->length > ofs + 1, NULL);
+	length = GSF_LE_GET_GUINT16 (q->data + ofs);
+	ofs += 2;
+
+	return excel_get_text_full (importer, q->data + ofs, length,
+				    NULL, q->length - ofs);
+}
+
 typedef struct {
 	unsigned first, last;
 	PangoAttrList *accum;
@@ -1243,8 +1299,7 @@
 		bs->type = MS_BIFF_TYPE_Worksheet;
 		default_name = _("Sheet%d");
 		bs->visibility = GNM_SHEET_VISIBILITY_VISIBLE;
-		bs->name = excel_get_text (importer, q->data + 1,
-			GSF_LE_GET_GUINT8 (q->data), NULL);
+		bs->name = excel_biff_text_1 (importer, q, 0);
 	} else {
 		if (importer->ver > MS_BIFF_V8)
 			g_printerr ("Unknown BIFF Boundsheet spec. Assuming same as Biff7 FIXME\n");
@@ -1288,8 +1343,7 @@
 		* other locales universally seem to treat the first byte as a length
 		* and the second as the unicode flag header.
 		*/
-		bs->name = excel_get_text (importer, q->data + 7,
-			GSF_LE_GET_GUINT8 (q->data + 6), NULL);
+		bs->name = excel_biff_text_1 (importer, q, 6);
 	}
 
 	/* TODO: find some documentation on this.
@@ -1343,10 +1397,8 @@
 		d = g_new (BiffFormatData, 1);
 		d->idx = GSF_LE_GET_GUINT16 (q->data);
 		d->name = (ver >= MS_BIFF_V8)
-			? excel_get_text (importer, q->data + 4,
-				GSF_LE_GET_GUINT16 (q->data + 2), NULL)
-			: excel_get_text (importer, q->data + 3,
-				GSF_LE_GET_GUINT8 (q->data + 2), NULL);
+			? excel_biff_text_2 (importer, q, 2)
+			: excel_biff_text_1 (importer, q, 2);
 	} else {
 		XL_CHECK_CONDITION (q->length >= 3);
 
@@ -1354,10 +1406,8 @@
 		/* no usable index */
 		d->idx = g_hash_table_size (importer->format_table);
 		d->name = (ver >= MS_BIFF_V4)
-			? excel_get_text (importer, q->data + 3,
-				GSF_LE_GET_GUINT8 (q->data + 2), NULL)
-			: excel_get_text (importer, q->data + 1,
-				GSF_LE_GET_GUINT8 (q->data), NULL);
+			? excel_biff_text_1 (importer, q, 2)
+			: excel_biff_text_1 (importer, q, 0);
 	}
 
 	d (3, fprintf (stderr, "Format data: 0x%x == '%s'\n", d->idx, d->name););
@@ -1382,8 +1432,7 @@
 		fd->boldness  = (data & 0x1) ? 0x2bc : 0x190;
 		fd->underline = (data & 0x4) ? UNDERLINE_SINGLE : UNDERLINE_NONE;
 		fd->script = GO_FONT_SCRIPT_STANDARD;
-		fd->fontname = excel_get_text (importer, q->data + 5,
-			GSF_LE_GET_GUINT8 (q->data + 4), NULL);
+		fd->fontname = excel_biff_text_1 (importer, q, 4);
 		if (ms_biff_query_peek_next (q, &opcode) &&
 		    opcode == BIFF_FONT_COLOR) {
 			ms_biff_query_next (q);
@@ -1395,8 +1444,7 @@
 		fd->boldness  = (data & 0x1) ? 0x2bc : 0x190;
 		fd->underline = (data & 0x4) ? UNDERLINE_SINGLE : UNDERLINE_NONE;
 		fd->script = GO_FONT_SCRIPT_STANDARD;
-		fd->fontname = excel_get_text (importer, q->data + 7,
-			GSF_LE_GET_GUINT8 (q->data + 6), NULL);
+		fd->fontname = excel_biff_text_1 (importer, q, 6);
 	} else {
 		fd->color_idx  = GSF_LE_GET_GUINT16 (q->data + 4);
 		fd->boldness   = GSF_LE_GET_GUINT16 (q->data + 6);
@@ -1418,8 +1466,7 @@
 		case 0x21: fd->underline = UNDERLINE_SINGLE; break;	/* single accounting */
 		case 0x22: fd->underline = UNDERLINE_DOUBLE; break;	/* double accounting */
 		}
-		fd->fontname = excel_get_text (importer, q->data + 15,
-			GSF_LE_GET_GUINT8 (q->data + 14), NULL);
+		fd->fontname = excel_biff_text_1 (importer, q, 14);
 	}
 	fd->color_idx &= 0x7f; /* Undocumented but a good idea */
 
@@ -2571,11 +2618,10 @@
 				 *        DAMN! this was us!  we were screwing
 				 *        up when exporting ""
 				 */
-				guint16 const len = (q->data != NULL) ? GSF_LE_GET_GUINT16 (q->data) : 0;
+				guint16 const len = (q->length >= 2) ? GSF_LE_GET_GUINT16 (q->data) : 0;
 
 				if (len > 0)
-					v = excel_get_text (esheet->container.importer,
-						q->data + 2, len, NULL);
+					v = excel_biff_text (esheet->container.importer, q, 2, len);
 				else
 					/*
 					 * Pre-Biff8 seems to use len=0
@@ -2710,7 +2756,7 @@
 		if (options & 0xe7d)
 			g_warning ("unknown flag on NOTE record %hx", options);
 
-		author = excel_get_text (esheet->container.importer, q->data + 10, author_len, NULL);
+		author = excel_biff_text (esheet->container.importer, q, 10, author_len);
 		d (1, fprintf (stderr,"Comment at %s%d id %d options"
 			      " 0x%x hidden %d by '%s'\n",
 			      col_name (pos.col), pos.row + 1,
@@ -2734,8 +2780,8 @@
 			guint16 opcode;
 
 			g_string_append (comment,
-					 excel_get_text (esheet->container.importer,
-							 q->data + 6, 2048, NULL));
+					 excel_biff_text (esheet->container.importer,
+							  q, 6, 2048));
 
 			if (!ms_biff_query_peek_next (q, &opcode) ||
 			    opcode != BIFF_NOTE || !ms_biff_query_next (q) ||
@@ -2745,7 +2791,7 @@
 				return;
 			}
 		}
-		g_string_append (comment, excel_get_text (esheet->container.importer, q->data + 6, len, NULL));
+		g_string_append (comment, excel_biff_text (esheet->container.importer, q, 6, len));
 
 		d (2, fprintf (stderr,"Comment in %s%d: '%s'\n",
 			      col_name (pos.col), pos.row + 1, comment->str););
@@ -3241,15 +3287,13 @@
 	} else if (ver >= MS_BIFF_V5) {
 		XL_CHECK_CONDITION (q->length >= 7);
 
-		name = excel_get_text (container->importer, q->data + 7,
-			GSF_LE_GET_GUINT8 (q->data + 6), NULL);
+		name = excel_biff_text_1 (container->importer, q, 6);
 		nexpr = excel_parse_name (container->importer, NULL,
 			name, NULL, 0, FALSE, NULL);
 	} else {
 		XL_CHECK_CONDITION (q->length >= 3);
 
-		name = excel_get_text (container->importer, q->data + 3,
-			GSF_LE_GET_GUINT8 (q->data + 2), NULL);
+		name = excel_biff_text_1 (container->importer, q, 2);
 		nexpr = excel_parse_name (container->importer, NULL,
 			name, NULL, 0, FALSE, NULL);
 	}
@@ -3363,6 +3407,8 @@
 	}
 
 	name = excel_read_name_str (importer, data, &name_len, builtin_name);
+	XL_NEED_BYTES (name_len);
+	data += name_len;
 
 	if (name != NULL) {
 		Sheet *sheet = NULL;
@@ -3388,8 +3434,10 @@
 		if (importer->num_name_records < importer->names->len)
 			nexpr = g_ptr_array_index (importer->names, importer->num_name_records);
 
+		XL_NEED_BYTES (expr_len);
 		nexpr = excel_parse_name (importer, sheet,
-			name, data + name_len, expr_len, TRUE, nexpr);
+			name, data, expr_len, TRUE, nexpr);
+		data += expr_len;
 
 		/* Add a ref to keep it around after the excel-sheet/wb goes
 		 * away.  externnames do not get references and are unrefed
@@ -3428,7 +3476,6 @@
 		char *help_txt;
 		char *status_txt;
 
-		data += name_len + expr_len;
 		menu_txt = excel_get_text (importer, data, menu_txt_len, NULL);
 		data += menu_txt_len;
 		descr_txt = excel_get_text (importer, data, descr_txt_len, NULL);
@@ -5292,8 +5339,7 @@
 
 	XL_CHECK_CONDITION (q->length >= 2);
 
-	codename = excel_get_text (importer, q->data + 2,
-		GSF_LE_GET_GUINT16 (q->data), NULL);
+	codename = excel_biff_text_2 (importer, q, 0);
 	obj = esheet ? G_OBJECT (esheet->sheet) : G_OBJECT (importer->wb);
 	g_object_set_data_full (obj, CODENAME_KEY, codename, g_free);
 }
@@ -5573,7 +5619,7 @@
 		if (len + 2 > q->length)
 			len = q->length - 2;
 
-		name = excel_get_text (container->importer, q->data + 2, len, NULL);
+		name = excel_biff_text (container->importer, q, 2, len);
 
 		if (name != NULL) {
 			sheet = workbook_sheet_by_name (container->importer->wb, name);
@@ -5743,14 +5789,10 @@
 
 		if (importer->ver >= MS_BIFF_V8) {
 			XL_CHECK_CONDITION (q->length >= 3);
-			str = excel_get_text (importer, q->data + 2,
-					      GSF_LE_GET_GUINT16 (q->data),
-					      NULL);
+			str = excel_biff_text_2 (importer, q, 0);
 		} else {
 			XL_CHECK_CONDITION (q->length >= 2);
-			str = excel_get_text (importer, q->data + 1,
-					      GSF_LE_GET_GUINT8  (q->data),
-					      NULL);
+			str = excel_biff_text_1 (importer, q, 0);
 		}
 		d (2, fprintf (stderr,"%s == '%s'\n", is_header ? "header" : "footer", str););
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]