gnumeric r16390 - in branches/gnumeric-1-8/plugins: excel qpro
- From: mortenw svn gnome org
- To: svn-commits-list gnome org
- Subject: gnumeric r16390 - in branches/gnumeric-1-8/plugins: excel qpro
- Date: Wed, 20 Feb 2008 12:59:06 +0000 (GMT)
Author: mortenw
Date: Wed Feb 20 12:59:06 2008
New Revision: 16390
URL: http://svn.gnome.org/viewvc/gnumeric?rev=16390&view=rev
Log:
Handle more corruption.
Modified:
branches/gnumeric-1-8/plugins/excel/ChangeLog
branches/gnumeric-1-8/plugins/excel/ms-escher.c
branches/gnumeric-1-8/plugins/qpro/qpro-read.c
Modified: branches/gnumeric-1-8/plugins/excel/ms-escher.c
==============================================================================
--- branches/gnumeric-1-8/plugins/excel/ms-escher.c (original)
+++ branches/gnumeric-1-8/plugins/excel/ms-escher.c Wed Feb 20 12:59:06 2008
@@ -181,6 +181,9 @@
state->segment_len = q->length;
}
+ g_return_val_if_fail (offset >= state->start_offset, NULL);
+ g_return_val_if_fail ((size_t)(offset - state->start_offset) < q->length, NULL);
+
res = q->data + offset - state->start_offset;
if ((*needs_free = ((offset + num_bytes) > state->end_offset))) {
guint8 *buffer = g_malloc (num_bytes);
Modified: branches/gnumeric-1-8/plugins/qpro/qpro-read.c
==============================================================================
--- branches/gnumeric-1-8/plugins/qpro/qpro-read.c (original)
+++ branches/gnumeric-1-8/plugins/qpro/qpro-read.c Wed Feb 20 12:59:06 2008
@@ -100,8 +100,35 @@
Workbook *wb;
Sheet *cur_sheet;
GIConv converter;
+ gboolean corrupted;
} QProReadState;
+static void
+corrupted (QProReadState *state)
+{
+ if (!state->corrupted) {
+ state->corrupted = TRUE;
+ g_printerr (_("File is most likely corrupted.\n"));
+ }
+}
+
+static void
+q_condition_barf (QProReadState *state, const char *cond)
+{
+ corrupted (state);
+ /* Translation is screwed here. */
+ g_printerr ("Condition \"%s\" failed.\n", cond);
+}
+
+#define Q_CHECK_CONDITION(cond_) \
+ do { \
+ if (!(cond_)) { \
+ q_condition_barf (state, #cond_); \
+ goto error; \
+ } \
+ } while (0)
+
+
static GnmValue *
qpro_new_string (QProReadState *state, gchar const *data)
{
@@ -116,10 +143,9 @@
{
guint8 const *data;
- if (NULL == (data = gsf_input_read (state->input, 4, NULL))) {
- g_warning ("read failure");
- return NULL;
- }
+ data = gsf_input_read (state->input, 4, NULL);
+ Q_CHECK_CONDITION (data != NULL);
+
*id = GSF_LE_GET_GUINT16 (data + 0);
*len = GSF_LE_GET_GUINT16 (data + 2);
@@ -132,13 +158,16 @@
/* some sanity checking */
if (*id != QPRO_UNDOCUMENTED_837) {
- g_return_val_if_fail (*len < 0x2000, NULL);
+ Q_CHECK_CONDITION (*len < 0x2000);
}
data = gsf_input_read (state->input, *len, NULL);
- if (data == NULL)
- g_warning ("huh? failure reading %hd for type %hd", *len, *id);
+ Q_CHECK_CONDITION (data != NULL);
+
return data;
+
+error:
+ return NULL;
}
#define validate(f,expected) qpro_validate_len (state, #f, len, expected)
@@ -146,10 +175,10 @@
static gboolean
qpro_validate_len (QProReadState *state, char const *id, guint16 len, int expected_len)
{
- if (expected_len >= 0 && len != expected_len) {
- gnm_io_warning (state->io_context,
- _("Invalid '%s' record of length %hd instead of %d"),
- id, len, expected_len);
+ if (expected_len >= 0 && len != expected_len) {
+ corrupted (state);
+ g_printerr ("Invalid '%s' record of length %hd instead of %d\n",
+ id, len, expected_len);
return FALSE;
}
@@ -345,35 +374,16 @@
}
static void
-q_condition_barf (const char *cond)
-{
- g_warning ("File is most likely corrupted.\n"
- "(Condition \"%s\" failed.)\n",
- cond);
-}
-
-#define Q_CHECK_CONDITION(cond_) \
- do { \
- if (!(cond_)) { \
- q_condition_barf (#cond_); \
- fmla = refs; \
- goto error; \
- } \
- } while (0)
-
-
-static void
qpro_parse_formula (QProReadState *state, int col, int row,
guint8 const *data, guint8 const *end)
{
- int magic = GSF_LE_GET_GUINT16 (data + 6) & 0x7ff8;
+ guint16 magic, ref_offset;
#if 0
int flags = GSF_LE_GET_GUINT16 (data + 8);
int length = GSF_LE_GET_GUINT16 (data + 10);
#endif
- guint16 ref_offset = GSF_LE_GET_GUINT16 (data + 12);
GnmValue *val;
- GSList *stack = NULL;
+ GSList *stack = NULL;
GnmExprTop const *texpr = NULL;
guint8 const *refs, *fmla;
@@ -381,9 +391,13 @@
dump_missing_functions ();
#endif
+ Q_CHECK_CONDITION (end - data >= 14);
+ magic = GSF_LE_GET_GUINT16 (data + 6) & 0x7ff8;
+ ref_offset = GSF_LE_GET_GUINT16 (data + 12);
+
fmla = data + 14;
refs = fmla + ref_offset;
- g_return_if_fail (refs <= end);
+ Q_CHECK_CONDITION (refs <= end);
#if 0
puts (cell_coord_name (col, row));
@@ -408,7 +422,10 @@
case QPRO_OP_CELLREF: {
GnmCellRef ref;
- guint16 tmp = GSF_LE_GET_GUINT16 (refs + 4);
+ guint16 tmp;
+
+ Q_CHECK_CONDITION (end - refs >= 6);
+ tmp = GSF_LE_GET_GUINT16 (refs + 4);
ref.sheet = NULL;
ref.col = *((gint8 *)(refs + 2));
ref.col_relative = (tmp & 0x4000) ? TRUE : FALSE;
@@ -426,6 +443,8 @@
GnmCellRef a, b;
guint16 tmp;
+ Q_CHECK_CONDITION (end - refs >= 10);
+
tmp = GSF_LE_GET_GUINT16 (refs + 4);
a.sheet = NULL;
a.col = *((gint8 *)(refs + 2));
@@ -530,7 +549,6 @@
char const *name = qpro_functions[idx].name;
int args = qpro_functions[idx].args;
GnmExprList *arglist = NULL;
- GSList *tmp = stack;
GnmFunc *f;
if (name == NULL) {
@@ -548,20 +566,7 @@
if (args == ARGS_UNKNOWN) {
g_warning ("QPRO function %s is not supported.",
name);
- for (tmp = stack; tmp; tmp = tmp->next) {
- GnmParsePos pp;
- char *p;
-
- pp.wb = state->wb;
- pp.sheet = state->cur_sheet;
- pp.eval.col = col;
- pp.eval.row = row;
- p = gnm_expr_as_string (tmp->data, &pp, gnm_conventions_default);
- g_print ("Expr: %s\n", p);
- g_free (p);
- }
- g_print ("-----\n");
- break;
+ goto error;
}
if (args == ARGS_COUNT_FOLLOWS) {
@@ -576,8 +581,8 @@
args--;
}
if (args > 0) {
- g_warning ("File is probably corrupted.\n"
- "(Expression stack is short by %d arguments)",
+ g_printerr ("File is probably corrupted.\n"
+ "(Expression stack is short by %d arguments)",
args);
while (args > 0) {
GnmExpr const *e = gnm_expr_new_constant (value_new_empty ());
@@ -589,7 +594,8 @@
expr = gnm_expr_new_funcall (f, arglist);
break;
} else {
- g_warning ("Operator %d encountered.", op);
+ corrupted (state);
+ g_printerr ("Operator %d encountered.\n", op);
}
}
if (expr != NULL) {
@@ -612,7 +618,7 @@
again:
data = qpro_get_record (state, &id, &len);
- g_return_if_fail (data != NULL);
+ Q_CHECK_CONDITION (data != NULL);
if (id == QPRO_UNDOCUMENTED_270) {
/*
@@ -620,7 +626,9 @@
* more or less embedding a copy of the formula
* record.
*/
+#if 0
g_warning ("Encountered 270 record.");
+#endif
goto again;
}
@@ -658,13 +666,12 @@
for (tmp = stack; tmp; tmp = tmp->next) {
GnmExpr *expr = tmp->data;
- char *p;
-
- p = gnm_expr_as_string (expr, &pp,
- gnm_conventions_default);
+#ifdef DEBUG_EXPR_STACK
+ char *p = gnm_expr_as_string (expr, &pp,
+ gnm_conventions_default);
g_printerr ("Expr: %s\n", p);
g_free (p);
-
+#endif
gnm_expr_free (expr);
}
g_slist_free (stack);
@@ -884,6 +891,7 @@
state.wb = wb_view_get_workbook (new_wb_view);
state.cur_sheet = NULL;
state.converter = g_iconv_open ("UTF-8", "ISO-8859-1");
+ state.corrupted = FALSE;
/* check for >= QPro 6.0 which is OLE based */
ole = gsf_infile_msole_new (input, NULL);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]