[gnumeric] xls: fix crash on corrupted file.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] xls: fix crash on corrupted file.
- Date: Tue, 9 Jul 2013 15:46:22 +0000 (UTC)
commit 5f4baa93c84b02544276a668fdcfec734df6cd42
Author: Morten Welinder <terra gnome org>
Date: Tue Jul 9 11:46:04 2013 -0400
xls: fix crash on corrupted file.
NEWS | 2 +-
plugins/excel/ChangeLog | 5 ++++
plugins/excel/ms-formula-read.c | 44 ++++++++++++++++++++++++++------------
3 files changed, 36 insertions(+), 15 deletions(-)
---
diff --git a/NEWS b/NEWS
index 12ea2b2..35761d9 100644
--- a/NEWS
+++ b/NEWS
@@ -17,7 +17,7 @@ Jean:
Morten:
* Improve accuracy for 2-argument ERF.
- * Fix crashes on corrupted files. [#703143] [#703307]
+ * Fix crashes on corrupted files. [#703143] [#703307] [#703306]
* Fix --with-long-double tests. [#703397]
* Fix problems saving auto filters to xls. [#703308]
* Improve handling of large graph ranges. [#703546]
diff --git a/plugins/excel/ChangeLog b/plugins/excel/ChangeLog
index 50c0300..0f441ae 100644
--- a/plugins/excel/ChangeLog
+++ b/plugins/excel/ChangeLog
@@ -1,3 +1,8 @@
+2013-07-09 Morten Welinder <terra gnome org>
+
+ * ms-formula-read.c (getRefV8): Take GnmSheetSize argument.
+ Verify row against that. All callers changed. Fixes #703306.
+
2013-07-02 Andreas J. Guelzow <aguelzow pyrshep ca>
* xlsx-read.c (xlsx_sheet_dtd): attach protectedRange to the
diff --git a/plugins/excel/ms-formula-read.c b/plugins/excel/ms-formula-read.c
index ec44de5..fa7b58e 100644
--- a/plugins/excel/ms-formula-read.c
+++ b/plugins/excel/ms-formula-read.c
@@ -571,8 +571,10 @@ getRefV7 (GnmCellRef *cr,
cr->row = row;
} else
cr->row = row - currow;
- } else
+ } else {
+ /* By construction this cannot exceed 0x3fff. */
cr->row = row;
+ }
cr->col_relative = (gbitrw & 0x4000) != 0;
if (cr->col_relative) {
@@ -580,18 +582,19 @@ getRefV7 (GnmCellRef *cr,
cr->col = (gint8)col;
else
cr->col = col - curcol;
- } else
+ } else {
+ /* By construction this cannot exceed 0xff. */
cr->col = col;
+ }
}
/**
- * A useful routine for extracting data from a common
- * storage structure.
+ * A useful routine for extracting data from a common storage structure.
**/
static void
getRefV8 (GnmCellRef *cr,
guint16 row, guint16 gbitcl, int curcol, int currow,
- gboolean const shared)
+ gboolean const shared, GnmSheetSize const *ss)
{
guint8 const col = (guint8)(gbitcl & 0xff);
@@ -606,8 +609,13 @@ getRefV8 (GnmCellRef *cr,
cr->row = (gint16)row;
else
cr->row = row - currow;
- } else
+ } else {
cr->row = row;
+ if (row >= ss->max_rows) {
+ g_warning ("Row too big: %d", row);
+ cr->row = ss->max_rows - 1;
+ }
+ }
cr->col_relative = (gbitcl & 0x4000) != 0;
if (cr->col_relative) {
@@ -615,8 +623,10 @@ getRefV8 (GnmCellRef *cr,
cr->col = (gint8)col;
else
cr->col = col - curcol;
- } else
+ } else {
+ /* By construction this cannot exceed 0xff. */
cr->col = col;
+ }
}
static void
@@ -961,6 +971,9 @@ excel_parse_formula1 (MSContainer const *container,
gboolean *array_element)
{
MsBiffVersion const ver = container->importer->ver;
+ GnmSheetSize const *ss = esheet
+ ? gnm_sheet_get_size (esheet->sheet)
+ : workbook_get_sheet_size (container->importer->wb);
/* so that the offsets and lengths match the documentation */
guint8 const *cur = mem + 1;
@@ -1316,7 +1329,7 @@ excel_parse_formula1 (MSContainer const *container,
getRefV8 (&ref,
GSF_LE_GET_GUINT16 (cur + 1),
GSF_LE_GET_GUINT16 (cur + 3),
- fn_col, fn_row, shared);
+ fn_col, fn_row, shared, ss);
if ((eptg % 2)) /* Column are odd */
ref.row = ref.row_relative ? 0 : fn_row;
else /* Row */
@@ -1573,7 +1586,8 @@ excel_parse_formula1 (MSContainer const *container,
getRefV8 (&ref,
GSF_LE_GET_GUINT16 (cur),
GSF_LE_GET_GUINT16 (cur + 2),
- fn_col, fn_row, ptgbase == FORMULA_PTG_REFN);
+ fn_col, fn_row, ptgbase == FORMULA_PTG_REFN,
+ ss);
} else {
CHECK_FORMULA_LEN(3);
getRefV7 (&ref,
@@ -1592,11 +1606,13 @@ excel_parse_formula1 (MSContainer const *container,
getRefV8 (&first,
GSF_LE_GET_GUINT16 (cur+0),
GSF_LE_GET_GUINT16 (cur+4),
- fn_col, fn_row, ptgbase == FORMULA_PTG_AREAN);
+ fn_col, fn_row, ptgbase == FORMULA_PTG_AREAN,
+ ss);
getRefV8 (&last,
GSF_LE_GET_GUINT16 (cur+2),
GSF_LE_GET_GUINT16 (cur+6),
- fn_col, fn_row, ptgbase == FORMULA_PTG_AREAN);
+ fn_col, fn_row, ptgbase == FORMULA_PTG_AREAN,
+ ss);
} else {
CHECK_FORMULA_LEN(6);
getRefV7 (&first,
@@ -1702,7 +1718,7 @@ excel_parse_formula1 (MSContainer const *container,
getRefV8 (&first,
GSF_LE_GET_GUINT16 (cur + 2),
GSF_LE_GET_GUINT16 (cur + 4),
- fn_col, fn_row, 0);
+ fn_col, fn_row, FALSE, ss);
last = first;
} else {
CHECK_FORMULA_LEN(17);
@@ -1731,11 +1747,11 @@ excel_parse_formula1 (MSContainer const *container,
getRefV8 (&first,
GSF_LE_GET_GUINT16 (cur+2),
GSF_LE_GET_GUINT16 (cur+6),
- fn_col, fn_row, 0);
+ fn_col, fn_row, FALSE, ss);
getRefV8 (&last,
GSF_LE_GET_GUINT16 (cur+4),
GSF_LE_GET_GUINT16 (cur+8),
- fn_col, fn_row, 0);
+ fn_col, fn_row, FALSE, ss);
} else {
CHECK_FORMULA_LEN(20);
getRefV7 (&first,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]