gnumeric r16356 - in branches/gnumeric-1-8: . plugins/excel
- From: mortenw svn gnome org
- To: svn-commits-list gnome org
- Subject: gnumeric r16356 - in branches/gnumeric-1-8: . plugins/excel
- Date: Thu, 7 Feb 2008 23:28:21 +0000 (GMT)
Author: mortenw
Date: Thu Feb 7 23:28:20 2008
New Revision: 16356
URL: http://svn.gnome.org/viewvc/gnumeric?rev=16356&view=rev
Log:
2008-02-07 Morten Welinder <terra gnome org>
* ms-chart.c (xl_chart_import_error_bar): Avoid crash in missing
parent-series case. Fixes #514630.
* ms-formula-read.c (excel_parse_formula1, excel_parse_formula):
Grow a maxlen argument and make sure we do not read more. Fixes
#514637.
* ms-excel-read.c (excel_read_string_header, excel_get_text): Grow
an array_length argument and make sure we do not read more array
data than call. All callers changed.
(excel_biff_text, excel_biff_text_1, excel_biff_text_2): New
Biff-record based wrappers for excel_get_text.
(excel_formula_shared): Make sure to copy the data behind the
expression too.
Modified:
branches/gnumeric-1-8/NEWS
branches/gnumeric-1-8/plugins/excel/ChangeLog
branches/gnumeric-1-8/plugins/excel/ms-chart.c
branches/gnumeric-1-8/plugins/excel/ms-excel-read.c
branches/gnumeric-1-8/plugins/excel/ms-excel-read.h
branches/gnumeric-1-8/plugins/excel/ms-formula-read.c
branches/gnumeric-1-8/plugins/excel/ms-formula-read.h
branches/gnumeric-1-8/plugins/excel/ms-obj.c
branches/gnumeric-1-8/plugins/excel/ms-pivot.c
Modified: branches/gnumeric-1-8/NEWS
==============================================================================
--- branches/gnumeric-1-8/NEWS (original)
+++ branches/gnumeric-1-8/NEWS Thu Feb 7 23:28:20 2008
@@ -9,7 +9,7 @@
* Fix corrupted-xls-file problems. [#512984] [#513005] [#513313]
[#513317] [#513361] [#513364] [#513551] [#513605] [#513608] [#513790]
[#513787] [#513835] [#513963] [#514229] [#514230] [#514295] [#514435]
- [#514436] [#514437] [#514506] [#514510]
+ [#514436] [#514437] [#514506] [#514510] [#514630] [#514637]
* Fix non-ascii export problem. [#511135]
* Band-aid evaluation problem with broken xls. [#513559]
* Fix circular array formula problem.
Modified: branches/gnumeric-1-8/plugins/excel/ms-chart.c
==============================================================================
--- branches/gnumeric-1-8/plugins/excel/ms-chart.c (original)
+++ branches/gnumeric-1-8/plugins/excel/ms-chart.c Thu Feb 7 23:28:20 2008
@@ -1902,7 +1902,7 @@
if (slen == 0)
return FALSE;
- str = excel_get_text (s->container.importer, q->data + 3, slen, NULL);
+ str = excel_biff_text_1 (s->container.importer, q, 2);
d (2, g_printerr ("'%s';\n", str););
if (s->currentSeries != NULL &&
@@ -3010,7 +3010,8 @@
chart_parse_expr (MSContainer *container, guint8 const *data, int length)
{
return excel_parse_formula (container, NULL, 0, 0,
- data, length, FALSE, NULL);
+ data, length, 0 /* FIXME? */,
+ FALSE, NULL);
}
static Sheet *
@@ -3108,10 +3109,13 @@
GogMSDimType msdim;
char const *prop_name = (series->err_type < 3)
? "x-errors" : "y-errors";
- GParamSpec *pspec = g_object_class_find_property (
+ GParamSpec *pspec;
+
+ XL_CHECK_CONDITION (parent->series != NULL);
+
+ pspec = g_object_class_find_property (
G_OBJECT_GET_CLASS (parent->series),
prop_name);
-
state->plot = parent->series->plot;
if (pspec == NULL) {
pspec = g_object_class_find_property (
@@ -3131,8 +3135,8 @@
GOData *data;
g_object_get (G_OBJECT (parent->series),
- prop_name, &error_bar,
- NULL);
+ prop_name, &error_bar,
+ NULL);
if (!error_bar) {
error_bar = g_object_new (GOG_ERROR_BAR_TYPE, NULL);
error_bar->display = GOG_ERROR_BAR_DISPLAY_NONE;
@@ -3237,15 +3241,14 @@
static void
ms_excel_chart_read_LABEL (BiffQuery *q, XLChartReadState *state)
{
- guint16 row, sernum, len;
+ guint16 row, sernum;
char *label;
XLChartSeries *series;
- XL_CHECK_CONDITION (q->length >= 8);
+ XL_CHECK_CONDITION (q->length >= 6);
row = GSF_LE_GET_GUINT16 (q->data + 0);
sernum = GSF_LE_GET_GUINT16 (q->data + 2);
/* xf = GSF_LE_GET_GUINT16 (q->data + 4); */
- len = GSF_LE_GET_GUINT16 (q->data + 6);
if (state->cur_role < 0 ||
state->series == NULL ||
@@ -3253,7 +3256,7 @@
NULL == (series = g_ptr_array_index (state->series, sernum)))
return;
- label = excel_get_text (state->container.importer, q->data + 8, len, NULL);
+ label = excel_biff_text_2 (state->container.importer, q, 6);
if (label != NULL &&
series->data[state->cur_role].value != NULL) {
value_release (series->data[state->cur_role].value->vals[0][row]);
Modified: branches/gnumeric-1-8/plugins/excel/ms-excel-read.c
==============================================================================
--- branches/gnumeric-1-8/plugins/excel/ms-excel-read.c (original)
+++ branches/gnumeric-1-8/plugins/excel/ms-excel-read.c Thu Feb 7 23:28:20 2008
@@ -289,7 +289,8 @@
g_return_val_if_fail (length > 0, NULL);
texpr = excel_parse_formula (&esheet->container, esheet, 0, 0,
- data, length, FALSE, NULL);
+ data, length, 0 /* FIXME */,
+ FALSE, NULL);
if (ms_excel_read_debug > 8) {
char *tmp;
GnmParsePos pp;
@@ -825,52 +826,68 @@
/**
* excel_read_string_header :
- * @ptr : a pointer to the start of the string header
+ * @data : a pointer to the start of the string header
+ * @maxlen : the length of the data area
* @use_utf16 : Is the content in 8 or 16 bit chars
* @n_markup : number of trailing markup records
* @has_extended : Is there trailing extended string info (eg japanese PHONETIC)
* @post_data_len :
*
- * returns a pointer to the start of the string
+ * returns the length of the header (in bytes)
**/
-static unsigned
-excel_read_string_header (guint8 const *data,
+static guint32
+excel_read_string_header (guint8 const *data, guint32 maxlen,
gboolean *use_utf16,
unsigned *n_markup,
gboolean *has_extended,
- unsigned *post_data_len)
+ unsigned *post_data_len)
{
- guint8 header = GSF_LE_GET_GUINT8 (data);
- guint8 const *ptr = data;
+ guint8 header;
+ guint32 len;
- *post_data_len = 0;
+ if (G_UNLIKELY (maxlen < 1))
+ goto error;
- /* be anal and double check that the header looks valid */
- if (((header & 0xf2) == 0)) {
- *use_utf16 = (header & 0x1) != 0;
-
- ptr++; /* skip header */
- if ((header & 0x8) != 0) {
- *n_markup = GSF_LE_GET_GUINT16 (ptr);
- *post_data_len += *n_markup * 4; /* 4 bytes per */
- ptr += 2;
- } else
- *n_markup = 0;
- if ((*has_extended = (header & 0x4) != 0)) {
- guint32 len_ext_rst = GSF_LE_GET_GUINT32 (ptr); /* A byte length */
- *post_data_len += len_ext_rst;
- ptr += 4;
-
- g_warning ("extended string support unimplemented:"
- "ignoring %u bytes\n", len_ext_rst);
- }
+ header = GSF_LE_GET_GUINT8 (data);
+ if (((header & 0xf2) != 0))
+ goto error;
+
+ *use_utf16 = (header & 0x1) != 0;
+
+ if ((header & 0x8) != 0) {
+ if (G_UNLIKELY (maxlen < 3))
+ goto error;
+ *n_markup = GSF_LE_GET_GUINT16 (data + 1);
+ *post_data_len = *n_markup * 4; /* 4 bytes per */
+ len = 3;
} else {
- g_warning ("potential problem. A string with an invalid header was found");
- *use_utf16 = *has_extended = FALSE;
*n_markup = 0;
+ *post_data_len = 0;
+ len = 1;
+ }
+
+ *has_extended = (header & 0x4) != 0;
+ if (*has_extended) {
+ guint32 len_ext_rst;
+
+ if (G_UNLIKELY (maxlen < len + 4))
+ goto error;
+ len_ext_rst = GSF_LE_GET_GUINT32 (data + len); /* A byte length */
+ *post_data_len += len_ext_rst;
+ len += 4;
+
+ g_warning ("Extended string support unimplemented; "
+ "ignoring %u bytes\n", len_ext_rst);
}
- return ptr - data;
+ return len;
+
+ error:
+ *use_utf16 = *has_extended = FALSE;
+ *n_markup = 0;
+ *post_data_len = 0;
+ g_warning ("Invalid string record.");
+ return 0;
}
char *
@@ -902,10 +919,10 @@
return ans;
}
-static char *
-excel_get_text_full (GnmXLImporter const *importer,
- guint8 const *pos, guint32 length,
- guint32 *byte_length, guint32 maxlen)
+char *
+excel_get_text (GnmXLImporter const *importer,
+ guint8 const *pos, guint32 length,
+ guint32 *byte_length, guint32 maxlen)
{
char *ans;
guint8 const *ptr;
@@ -919,8 +936,10 @@
*byte_length = 1; /* the header */
if (length == 0)
return NULL;
- ptr = pos + excel_read_string_header (pos,
- &use_utf16, &n_markup, &has_extended, &trailing_data_len);
+ ptr = pos + excel_read_string_header
+ (pos, maxlen,
+ &use_utf16, &n_markup, &has_extended,
+ &trailing_data_len);
*byte_length += trailing_data_len;
} else {
*byte_length = 0; /* no header */
@@ -957,7 +976,7 @@
}
/**
- * excel_get_text :
+ * excel_get_text_fixme :
* @importer :
* @pos : pointer to the start of string information
* @length : in _characters_
@@ -965,12 +984,12 @@
*
* 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_fixme (GnmXLImporter const *importer,
+ guint8 const *pos, guint32 length, guint32 *byte_length)
{
- return excel_get_text_full (importer, pos, length, byte_length,
- G_MAXUINT);
+ return excel_get_text (importer, pos, length, byte_length,
+ G_MAXUINT);
}
static char *
@@ -979,11 +998,11 @@
{
XL_CHECK_CONDITION_VAL (q->length >= ofs, NULL);
- return excel_get_text_full (importer, q->data + ofs, length,
+ return excel_get_text (importer, q->data + ofs, length,
NULL, q->length - ofs);
}
-static char *
+char *
excel_biff_text_1 (GnmXLImporter const *importer,
const BiffQuery *q, guint32 ofs)
{
@@ -993,11 +1012,11 @@
length = GSF_LE_GET_GUINT8 (q->data + ofs);
ofs++;
- return excel_get_text_full (importer, q->data + ofs, length,
+ return excel_get_text (importer, q->data + ofs, length,
NULL, q->length - ofs);
}
-static char *
+char *
excel_biff_text_2 (GnmXLImporter const *importer,
const BiffQuery *q, guint32 ofs)
{
@@ -1007,8 +1026,8 @@
length = GSF_LE_GET_GUINT16 (q->data + ofs);
ofs += 2;
- return excel_get_text_full (importer, q->data + ofs, length,
- NULL, q->length - ofs);
+ return excel_get_text (importer, q->data + ofs, length,
+ NULL, q->length - ofs);
}
typedef struct {
@@ -1098,9 +1117,10 @@
offset += 2;
do {
offset = ms_biff_query_bound_check (q, offset, 1);
- offset += excel_read_string_header (q->data + offset,
- &use_utf16, &n_markup, &has_extended,
- &post_data_len);
+ offset += excel_read_string_header
+ (q->data + offset, q->length - offset,
+ &use_utf16, &n_markup, &has_extended,
+ &post_data_len);
total_end_len += post_data_len;
total_n_markup += n_markup;
chars_left = (q->length - offset) / (use_utf16 ? 2 : 1);
@@ -2403,8 +2423,8 @@
static GnmExprTop const *
excel_formula_shared (BiffQuery *q, ExcelReadSheet *esheet, GnmCell *cell)
{
- guint16 opcode, data_len;
- GnmRange r;
+ guint16 opcode, data_len, data_ofs, array_data_len;
+ GnmRange r;
gboolean is_array;
GnmExprTop const *texpr;
guint8 const *data;
@@ -2420,6 +2440,7 @@
}
ms_biff_query_next (q);
+ XL_CHECK_CONDITION_VAL (q->length >= 6, NULL);
r.start.row = GSF_LE_GET_GUINT16 (q->data + 0);
r.end.row = GSF_LE_GET_GUINT16 (q->data + 2);
r.start.col = GSF_LE_GET_GUINT8 (q->data + 4);
@@ -2467,15 +2488,17 @@
is_array = (q->opcode != BIFF_SHRFMLA);
- if (esheet_ver (esheet) > MS_BIFF_V4) {
- data = q->data + (is_array ? 14 : 10);
- data_len = GSF_LE_GET_GUINT16 (q->data + (is_array ? 12 : 8));
- } else {
- data = q->data + 10;
- data_len = GSF_LE_GET_GUINT16 (q->data + 8);
- }
+ data_ofs = (esheet_ver (esheet) > MS_BIFF_V4 && is_array) ? 14 : 10;
+ XL_CHECK_CONDITION_VAL (q->length >= data_ofs, NULL);
+ data = q->data + data_ofs;
+ data_len = GSF_LE_GET_GUINT16 (q->data + (data_ofs - 2));
+ XL_CHECK_CONDITION_VAL (q->length >= data_ofs + data_len, NULL);
+ array_data_len = data_len > 0 ? q->length - (data_ofs + data_len) : 0;
+
texpr = excel_parse_formula (&esheet->container, esheet,
- r.start.col, r.start.row, data, data_len, !is_array, NULL);
+ r.start.col, r.start.row,
+ data, data_len, array_data_len,
+ !is_array, NULL);
sf = g_new (XLSharedFormula, 1);
@@ -2486,8 +2509,9 @@
*/
sf->key = cell->pos;
sf->is_array = is_array;
- sf->data = data_len > 0 ? g_memdup (data, data_len) : NULL;
+ sf->data = data_len > 0 ? g_memdup (data, data_len + array_data_len) : NULL;
sf->data_len = data_len;
+ sf->array_data_len = array_data_len;
d (1, fprintf (stderr,"Shared formula, extent %s\n", range_as_string (&r)););
@@ -2546,31 +2570,20 @@
* and have this checking done there.
*/
if (esheet_ver (esheet) >= MS_BIFF_V5) {
+ XL_CHECK_CONDITION (q->length >= 22);
expr_length = GSF_LE_GET_GUINT16 (q->data + 20);
offset = 22;
} else if (esheet_ver (esheet) >= MS_BIFF_V3) {
+ XL_CHECK_CONDITION (q->length >= 18);
expr_length = GSF_LE_GET_GUINT16 (q->data + 16);
offset = 18;
} else {
+ XL_CHECK_CONDITION (q->length >= 17);
expr_length = GSF_LE_GET_GUINT8 (q->data + 16);
offset = 17;
val_dat++; /* compensate for the 3 byte style */
}
-
- if (q->length < offset) {
- g_printerr ("FIXME: serious formula error: "
- "invalid FORMULA (0x%x) record with length %d (should >= %d)\n",
- q->opcode, q->length, offset);
- gnm_cell_set_value (cell, value_new_error (NULL, "Formula Error"));
- return;
- }
- if (q->length < (unsigned)(offset + expr_length)) {
- g_printerr ("FIXME: serious formula error: "
- "supposed length 0x%x, real len 0x%x\n",
- expr_length, q->length - offset);
- gnm_cell_set_value (cell, value_new_error (NULL, "Formula Error"));
- return;
- }
+ XL_CHECK_CONDITION (q->length >= offset + expr_length);
/* Get the current value so that we can format, do this BEFORE handling
* shared/array formulas or strings in case we need to go to the next
@@ -2594,7 +2607,9 @@
}
texpr = excel_parse_formula (&esheet->container, esheet, col, row,
- (q->data + offset), expr_length, FALSE, &array_elem);
+ q->data + offset, expr_length,
+ q->length - (offset + expr_length),
+ FALSE, &array_elem);
#if 0
/* dump the trailing array and natural language data */
gsf_mem_dump (q->data + offset + expr_length,
@@ -2746,16 +2761,15 @@
XL_CHECK_CONDITION (pos.col < SHEET_MAX_COLS && pos.row < SHEET_MAX_ROWS);
if (esheet_ver (esheet) >= MS_BIFF_V8) {
- guint16 options, obj_id, author_len;
+ guint16 options, obj_id;
gboolean hidden;
MSObj *obj;
char *author;
- XL_CHECK_CONDITION (q->length >= 10);
+ XL_CHECK_CONDITION (q->length >= 8);
options = GSF_LE_GET_GUINT16 (q->data + 4);
hidden = (options & 0x2)==0;
obj_id = GSF_LE_GET_GUINT16 (q->data + 6);
- author_len = GSF_LE_GET_GUINT16 (q->data + 8);
/* Docs claim that only 0x2 is valid, all other flags should
* be 0 but we have seen examples with 0x100 'pusiuhendused juuli 2003.xls'
@@ -2766,7 +2780,7 @@
if (options & 0xe7d)
g_warning ("unknown flag on NOTE record %hx", options);
- author = excel_biff_text (esheet->container.importer, q, 10, author_len);
+ author = excel_biff_text_2 (esheet->container.importer, q, 8);
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,
@@ -3168,7 +3182,8 @@
if (expr_len != 0) {
texpr = excel_parse_formula (&importer->container, NULL, 0, 0,
- expr_data, expr_len, TRUE, NULL);
+ expr_data, expr_len, 0 /* FIXME? */,
+ TRUE, NULL);
if (texpr == NULL) {
gnm_io_warning (importer->context, _("Failure parsing name '%s'"), name);
@@ -3220,9 +3235,10 @@
use_utf16 = has_extended = FALSE;
n_markup = trailing_data_len = 0;
} else
- str += excel_read_string_header (str,
- &use_utf16, &n_markup, &has_extended,
- &trailing_data_len);
+ str += excel_read_string_header
+ (str, G_MAXINT /* FIXME */,
+ &use_utf16, &n_markup, &has_extended,
+ &trailing_data_len);
/* pull out the magic builtin enum */
builtin = excel_builtin_name (str);
@@ -3236,7 +3252,7 @@
name = g_strdup (builtin);
*name_len += str - data;
} else /* converts char len to byte len, and handles header */
- name = excel_get_text (importer, data, *name_len, name_len);
+ name = excel_get_text_fixme (importer, data, *name_len, name_len);
return name;
}
@@ -3491,13 +3507,13 @@
char *help_txt;
char *status_txt;
- menu_txt = excel_get_text (importer, data, menu_txt_len, NULL);
+ menu_txt = excel_get_text_fixme (importer, data, menu_txt_len, NULL);
data += menu_txt_len;
- descr_txt = excel_get_text (importer, data, descr_txt_len, NULL);
+ descr_txt = excel_get_text_fixme (importer, data, descr_txt_len, NULL);
data += descr_txt_len;
- help_txt = excel_get_text (importer, data, help_txt_len, NULL);
+ help_txt = excel_get_text_fixme (importer, data, help_txt_len, NULL);
data += help_txt_len;
- status_txt = excel_get_text (importer, data, status_txt_len, NULL);
+ status_txt = excel_get_text_fixme (importer, data, status_txt_len, NULL);
g_printerr ("Name record: '%s', '%s', '%s', '%s', '%s'\n",
name ? name : "(null)",
@@ -3588,7 +3604,7 @@
XL_NEED_BYTES (1);
len = *data++;
v = value_new_string_nocopy (
- excel_get_text (importer, data, len, NULL));
+ excel_get_text_fixme (importer, data, len, NULL));
data += len;
break;
@@ -4956,22 +4972,22 @@
data = q->data + 4;
XL_CHECK_CONDITION (data+3 <= end);
- input_title = excel_get_text (esheet->container.importer, data + 2,
+ input_title = excel_get_text_fixme (esheet->container.importer, data + 2,
GSF_LE_GET_GUINT16 (data), &len);
data += len + 2;
XL_CHECK_CONDITION (data+3 <= end);
- error_title = excel_get_text (esheet->container.importer, data + 2,
+ error_title = excel_get_text_fixme (esheet->container.importer, data + 2,
GSF_LE_GET_GUINT16 (data), &len);
data += len + 2;
XL_CHECK_CONDITION (data+3 <= end);
- input_msg = excel_get_text (esheet->container.importer, data + 2,
+ input_msg = excel_get_text_fixme (esheet->container.importer, data + 2,
GSF_LE_GET_GUINT16 (data), &len);
data += len + 2;
XL_CHECK_CONDITION (data+3 <= end);
- error_msg = excel_get_text (esheet->container.importer, data + 2,
+ error_msg = excel_get_text_fixme (esheet->container.importer, data + 2,
GSF_LE_GET_GUINT16 (data), &len);
data += len + 2;
@@ -5058,13 +5074,15 @@
if (expr1_len > 0)
texpr1 = excel_parse_formula (&esheet->container, esheet,
- col, row,
- expr1_dat, expr1_len, TRUE, NULL);
+ col, row,
+ expr1_dat, expr1_len, 0 /* FIXME */,
+ TRUE, NULL);
if (expr2_len > 0)
texpr2 = excel_parse_formula (&esheet->container, esheet,
- col, row,
- expr2_dat, expr2_len, TRUE, NULL);
+ col, row,
+ expr2_dat, expr2_len, 0 /* FIXME */,
+ TRUE, NULL);
d (1, fprintf (stderr,"style = %d, type = %d, op = %d\n",
style, type, op););
@@ -5450,12 +5468,12 @@
data = q->data + 24;
if (len0 > 0) {
v0 = value_new_string_nocopy (
- excel_get_text (esheet->container.importer, data, len0, NULL));
+ excel_get_text_fixme (esheet->container.importer, data, len0, NULL));
data += len0;
}
if (len1 > 0)
v1 = value_new_string_nocopy (
- excel_get_text (esheet->container.importer, data, len1, NULL));
+ excel_get_text_fixme (esheet->container.importer, data, len1, NULL));
if (op1 == GNM_FILTER_UNUSED) {
cond = gnm_filter_condition_new_single (op0, v0);
@@ -5741,7 +5759,7 @@
: GSF_LE_GET_GUINT16 (q->data + 6);
XL_CHECK_CONDITION (q->length - 8 >= in_len);
- txt = excel_get_text (esheet->container.importer, q->data + 8,
+ txt = excel_get_text_fixme (esheet->container.importer, q->data + 8,
in_len, &str_len);
d (0, fprintf (stderr,"%s in %s;\n",
@@ -6345,7 +6363,7 @@
gsf_mem_dump (q->data + 4 + 1, len);
for (data = q->data + 4 + 1 + len, i = 0; i < numTabs ; i++) {
len = GSF_LE_GET_GUINT16 (data);
- name = excel_get_text (importer, data + 2, len, &byte_length);
+ name = excel_get_text_fixme (importer, data + 2, len, &byte_length);
g_printerr ("\t-> %s\n", name);
g_free (name);
data += byte_length + 2;
Modified: branches/gnumeric-1-8/plugins/excel/ms-excel-read.h
==============================================================================
--- branches/gnumeric-1-8/plugins/excel/ms-excel-read.h (original)
+++ branches/gnumeric-1-8/plugins/excel/ms-excel-read.h Thu Feb 7 23:28:20 2008
@@ -50,7 +50,7 @@
typedef struct {
GnmCellPos key;
guint8 *data;
- guint32 data_len;
+ guint32 data_len, array_data_len;
gboolean is_array;
} XLSharedFormula;
@@ -135,10 +135,12 @@
char *excel_get_chars (GnmXLImporter const *importer,
guint8 const *ptr, size_t length,
- gboolean use_utf16);
-char *excel_get_text (GnmXLImporter const *importer,
- guint8 const *ptr, guint32 length,
- guint32 *byte_length);
+ gboolean use_utf16);
+char * excel_get_text (GnmXLImporter const *importer,
+ guint8 const *pos, guint32 length,
+ guint32 *byte_length, guint32 maxlen);
+char *excel_biff_text_1 (GnmXLImporter const *importer, const BiffQuery *q, guint32 ofs);
+char *excel_biff_text_2 (GnmXLImporter const *importer, const BiffQuery *q, guint32 ofs);
GnmColor *excel_palette_get (GnmXLImporter *importer, gint idx);
ExcelFont const *excel_font_get (GnmXLImporter const *importer, unsigned idx);
Modified: branches/gnumeric-1-8/plugins/excel/ms-formula-read.c
==============================================================================
--- branches/gnumeric-1-8/plugins/excel/ms-formula-read.c (original)
+++ branches/gnumeric-1-8/plugins/excel/ms-formula-read.c Thu Feb 7 23:28:20 2008
@@ -843,6 +843,39 @@
"PTG_REF_ERR_3D", "PTG_AREA_ERR_3D", "PTG_3E", "PTG_3F"
};
+
+static gboolean
+check_formula_len (int left, int needed)
+{
+ if (needed > left) {
+ g_warning ("File is most likely corrupted.\n"
+ "(Needed %d bytes for formula item, has only %d.)",
+ needed, left);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+#define CHECK_FORMULA_LEN(len_) \
+do { \
+ ptg_length = (len_); \
+ if (check_formula_len (len_left, ptg_length + 1)) { \
+ goto length_error; \
+ } \
+} while (0) \
+
+#define CHECK_FORMULA_ARRAY_LEN(len_) \
+do { \
+ int needed_ = len_; \
+ int left_ = array_length - (array_data - array_data0); \
+ if (check_formula_len (left_, needed_)) { \
+ if (v) \
+ value_release (v); \
+ goto length_error; \
+ } \
+} while (0)
+
/**
* Parse that RP Excel formula, see S59E2B.HTM
* Return a dynamicly allocated GnmExpr containing the formula, or NULL
@@ -851,7 +884,7 @@
excel_parse_formula1 (MSContainer const *container,
ExcelReadSheet const *esheet,
int fn_col, int fn_row,
- guint8 const *mem, guint16 length,
+ guint8 const *mem, guint16 length, guint16 array_length,
gboolean shared,
gboolean *array_element)
{
@@ -861,7 +894,8 @@
guint8 const *cur = mem + 1;
/* Array sizes and values are stored at the end of the stream */
- guint8 const *array_data = mem + length;
+ guint8 const *array_data0 = mem + length;
+ guint8 const *array_data = array_data0;
int len_left = length;
GnmExprList *stack = NULL;
@@ -901,8 +935,14 @@
XLSharedFormula *sf;
GnmCellPos top_left;
+ if (ver >= MS_BIFF_V3) {
+ CHECK_FORMULA_LEN(3);
+ top_left.col = GSF_LE_GET_GUINT16 (cur+2);
+ } else {
+ CHECK_FORMULA_LEN(4);
+ top_left.col = GSF_LE_GET_GUINT8 (cur+2);
+ }
top_left.row = GSF_LE_GET_GUINT16 (cur+0);
- top_left.col = (ver >= MS_BIFF_V3) ? GSF_LE_GET_GUINT16 (cur+2) : GSF_LE_GET_GUINT8 (cur+2);
sf = excel_sheet_shared_formula (esheet, &top_left);
if (sf == NULL) {
@@ -926,7 +966,8 @@
d (0, fprintf (stderr, "Parse shared formula\n"););
expr = excel_parse_formula1 (container, esheet, fn_col, fn_row,
- sf->data, sf->data_len, TRUE, array_element);
+ sf->data, sf->data_len, sf->array_data_len,
+ TRUE, array_element);
parse_list_push (&stack, expr);
ptg_length = length; /* Force it to be the only token */
@@ -937,8 +978,14 @@
XLDataTable *dt;
GnmCellPos top_left;
+ if (ver >= MS_BIFF_V3) {
+ CHECK_FORMULA_LEN(3);
+ top_left.col = GSF_LE_GET_GUINT16 (cur+2);
+ } else {
+ CHECK_FORMULA_LEN(4);
+ top_left.col = GSF_LE_GET_GUINT8 (cur+2);
+ }
top_left.row = GSF_LE_GET_GUINT16 (cur+0);
- top_left.col = (ver >= MS_BIFF_V3) ? GSF_LE_GET_GUINT16 (cur+2) : GSF_LE_GET_GUINT8 (cur+2);
dt = excel_sheet_data_table (esheet, &top_left);
if (dt == NULL) {
@@ -1018,15 +1065,17 @@
break;
case FORMULA_PTG_ATTR : { /* FIXME: not fully implemented */
- guint8 grbit = GSF_LE_GET_GUINT8 (cur);
+ guint8 grbit;
guint16 w;
if (ver >= MS_BIFF_V3) {
+ CHECK_FORMULA_LEN(3);
w = GSF_LE_GET_GUINT16 (cur+1);
- ptg_length = 3;
} else {
+ CHECK_FORMULA_LEN(2);
w = GSF_LE_GET_GUINT8 (cur+1);
- ptg_length = 2;
}
+
+ grbit = GSF_LE_GET_GUINT8 (cur);
if (grbit == 0x00) {
#if 0
ms_excel_dump_cellname (container->importer, esheet, fn_col, fn_row);
@@ -1080,61 +1129,47 @@
break;
case FORMULA_PTG_SHEET:
+ CHECK_FORMULA_LEN(10);
g_warning ("PTG_SHEET! please send us a copy of this file.");
- ptg_length = 10;
break;
case FORMULA_PTG_SHEET_END:
+ CHECK_FORMULA_LEN(4);
g_warning ("PTG_SHEET_END! please send us a copy of this file.");
- ptg_length = 4;
break;
case FORMULA_PTG_ERR:
+ CHECK_FORMULA_LEN(1);
parse_list_push_raw (&stack, biff_get_error (NULL, GSF_LE_GET_GUINT8 (cur)));
- ptg_length = 1;
break;
case FORMULA_PTG_INT:
+ CHECK_FORMULA_LEN(2);
parse_list_push_raw (&stack, value_new_int (GSF_LE_GET_GUINT16 (cur)));
- ptg_length = 2;
break;
case FORMULA_PTG_BOOL:
+ CHECK_FORMULA_LEN(1);
parse_list_push_raw (&stack, value_new_bool (GSF_LE_GET_GUINT8 (cur)));
- ptg_length = 1;
break;
case FORMULA_PTG_NUM:
+ CHECK_FORMULA_LEN(8);
parse_list_push_raw (&stack, value_new_float (gsf_le_get_double (cur)));
- ptg_length = 8;
break;
case FORMULA_PTG_STR: {
char *str;
guint32 byte_len;
- int char_len = GSF_LE_GET_GUINT8 (cur);
+ int char_len;
- if (char_len <= len_left) {
- str = excel_get_text (container->importer, cur+1, char_len, &byte_len);
- ptg_length = 1 + byte_len;
- /* data validation has a non-standard form of expression
- */
-#if 0
- if (str != NULL && ) {
- int res_char_len = g_utf8_strlen (str, byte_len);
- }
-#endif
- } else {
- str = NULL;
+ CHECK_FORMULA_LEN(1);
+ char_len = GSF_LE_GET_GUINT8 (cur);
-#if 0
- /* we can not flag this because some versions of gnumeric
- * produced invalid output where "" was stored as
- * PTG_STR with no length **/
- g_warning ("invalid string of len %d, larger than remaining space %d",
- len, len_left);
-#endif
- }
+ str = excel_get_text (container->importer, cur+1,
+ char_len, &byte_len,
+ len_left - 1);
+ ptg_length = 1 + byte_len;
if (str != NULL) {
d (2, fprintf (stderr, " -> '%s'\n", str););
@@ -1147,7 +1182,7 @@
}
case FORMULA_PTG_EXTENDED : { /* Extended Ptgs for Biff8 */
- ptg_length = 1;
+ CHECK_FORMULA_LEN(1);
switch ((eptg = GSF_LE_GET_GUINT8 (cur))) {
default :
g_warning ("EXCEL : unknown ePtg type %02x", eptg);
@@ -1248,11 +1283,15 @@
break;
case FORMULA_PTG_ARRAY : {
- unsigned cols = GSF_LE_GET_GUINT8 (array_data + 0);
- unsigned rows = GSF_LE_GET_GUINT16 (array_data + 1);
- unsigned lpx, lpy, elem_len = 0;
- GnmValue *v, *elem;
- guint8 val_type;
+ unsigned cols, rows;
+ unsigned lpx, lpy;
+ GnmValue *v = NULL;
+
+ CHECK_FORMULA_LEN(7);
+ CHECK_FORMULA_ARRAY_LEN(3);
+ cols = GSF_LE_GET_GUINT8 (array_data + 0);
+ rows = GSF_LE_GET_GUINT16 (array_data + 1);
+ array_data += 3;
if (ver >= MS_BIFF_V8) {
cols++;
@@ -1261,7 +1300,6 @@
cols = 256;
v = value_new_array (cols, rows);
- ptg_length = 7;
#ifndef NO_DEBUG_EXCEL
if (ms_excel_formula_debug > 4) {
@@ -1272,10 +1310,14 @@
cols, rows);
}
#endif
- array_data += 3;
for (lpy = 0; lpy < rows; lpy++) {
for (lpx = 0; lpx < cols; lpx++) {
+ GnmValue *elem;
+ guint8 val_type;
+
+ CHECK_FORMULA_ARRAY_LEN(1);
val_type = GSF_LE_GET_GUINT8 (array_data);
+ array_data++;
#ifndef NO_DEBUG_EXCEL
if (ms_excel_formula_debug > 5) {
fprintf (stderr, "\tArray elem type 0x%x (%d,%d)\n", val_type, lpx, lpy);
@@ -1283,23 +1325,29 @@
#endif
switch (val_type) {
case 1:
- elem = value_new_float (gsf_le_get_double (array_data+1));
- elem_len = 9;
+ CHECK_FORMULA_ARRAY_LEN(8);
+ elem = value_new_float (gsf_le_get_double (array_data));
+ array_data += 8;
break;
case 2: {
- guint32 len;
+ guint32 len, chars;
char *str;
if (ver >= MS_BIFF_V8) {
- str = excel_get_text (container->importer, array_data + 3,
- GSF_LE_GET_GUINT16 (array_data+1), &len);
- elem_len = len + 3;
+ CHECK_FORMULA_ARRAY_LEN(2);
+ chars = GSF_LE_GET_GUINT16 (array_data);
+ array_data += 2;
} else {
- str = excel_get_text (container->importer, array_data + 2,
- GSF_LE_GET_GUINT8 (array_data+1), &len);
- elem_len = len + 2;
+ CHECK_FORMULA_ARRAY_LEN(1);
+ chars = GSF_LE_GET_GUINT8 (array_data);
+ array_data++;
}
+ str = excel_get_text
+ (container->importer, array_data,
+ chars, &len,
+ array_length - (array_data - array_data0));
+ array_data += len;
if (str) {
#ifndef NO_DEBUG_EXCEL
@@ -1314,22 +1362,21 @@
}
case 4:
- elem = value_new_bool (array_data [1] ? TRUE : FALSE);
- elem_len = 9;
+ CHECK_FORMULA_ARRAY_LEN(8);
+ elem = value_new_bool (array_data[0] ? TRUE : FALSE);
break;
case 16:
- elem = biff_get_error (NULL, array_data [1]);
- elem_len = 9;
+ CHECK_FORMULA_ARRAY_LEN(8);
+ elem = biff_get_error (NULL, array_data[0]);
break;
default :
- fprintf (stderr, "FIXME: Duff array item type %d @ %s%d:%d,%d with %d\n",
- val_type, col_name(fn_col), fn_row+1, lpx, lpy, elem_len);
- gsf_mem_dump (array_data-elem_len-9, 9+elem_len+9);
+ fprintf (stderr, "FIXME: Duff array item type %d @ %s%d:%d,%d\n",
+ val_type, col_name(fn_col), fn_row+1, lpx, lpy);
+ gsf_mem_dump (array_data-1, 9);
elem = value_new_empty ();
}
value_array_set (v, lpx, lpy, elem);
- array_data += elem_len;
}
}
parse_list_push_raw (&stack, v);
@@ -1341,10 +1388,10 @@
int iftab;
if (ver >= MS_BIFF_V4) {
- ptg_length = 2;
+ CHECK_FORMULA_LEN(2);
iftab = GSF_LE_GET_GUINT16 (cur);
} else {
- ptg_length = 1;
+ CHECK_FORMULA_LEN(1);
iftab = GSF_LE_GET_GUINT8 (cur);
}
@@ -1356,7 +1403,7 @@
}
case FORMULA_PTG_FUNC_VAR: {
- int const numargs = (GSF_LE_GET_GUINT8 ( cur ) & 0x7f);
+ int numargs;
/* index into fn table */
int iftab;
#if 0
@@ -1366,12 +1413,13 @@
int const cmdquiv = (GSF_LE_GET_GUINT16 (cur+1) & 0x8000);
#endif
if (ver >= MS_BIFF_V4) {
- ptg_length = 3;
+ CHECK_FORMULA_LEN(3);
iftab = (GSF_LE_GET_GUINT16 (cur+1) & 0x7fff);
} else {
- ptg_length = 2;
+ CHECK_FORMULA_LEN(2);
iftab = GSF_LE_GET_GUINT8 (cur+1);
}
+ numargs = (GSF_LE_GET_GUINT8 (cur) & 0x7f);
if (!make_function (&stack, iftab, numargs, container->importer->wb)) {
error = TRUE;
@@ -1381,17 +1429,18 @@
}
case FORMULA_PTG_NAME: {
- guint16 name_idx = GSF_LE_GET_GUINT16 (cur);
+ guint16 name_idx;
GPtrArray *names;
GnmExpr const*name;
GnmNamedExpr *nexpr = NULL;
if (ver >= MS_BIFF_V8)
- ptg_length = 4; /* Docs are wrong, no ixti */
+ CHECK_FORMULA_LEN(4); /* Docs are wrong, no ixti */
else if (ver >= MS_BIFF_V5)
- ptg_length = 14;
+ CHECK_FORMULA_LEN(14);
else
- ptg_length = 10;
+ CHECK_FORMULA_LEN(10);
+ name_idx = GSF_LE_GET_GUINT16 (cur);
names = container->importer->names;
if (name_idx < 1 || names->len < name_idx ||
@@ -1426,29 +1475,29 @@
break;
case FORMULA_PTG_REF_ERR:
- ptg_length = (ver >= MS_BIFF_V8) ? 4 : 3;
+ CHECK_FORMULA_LEN(ver >= MS_BIFF_V8 ? 4 : 3);
parse_list_push_raw (&stack, value_new_error_REF (NULL));
break;
case FORMULA_PTG_AREA_ERR:
- ptg_length = (ver >= MS_BIFF_V8) ? 8 : 6;
+ CHECK_FORMULA_LEN(ver >= MS_BIFF_V8 ? 8 : 6);
parse_list_push_raw (&stack, value_new_error_REF (NULL));
break;
case FORMULA_PTG_REF: case FORMULA_PTG_REFN: {
GnmCellRef ref;
if (ver >= MS_BIFF_V8) {
+ CHECK_FORMULA_LEN(4);
getRefV8 (&ref,
GSF_LE_GET_GUINT16 (cur),
GSF_LE_GET_GUINT16 (cur + 2),
fn_col, fn_row, ptgbase == FORMULA_PTG_REFN);
- ptg_length = 4;
} else {
+ CHECK_FORMULA_LEN(3);
getRefV7 (&ref,
GSF_LE_GET_GUINT8 (cur+2),
GSF_LE_GET_GUINT16 (cur),
fn_col, fn_row, ptgbase == FORMULA_PTG_REFN);
- ptg_length = 3;
}
parse_list_push (&stack, gnm_expr_new_cellref (&ref));
break;
@@ -1457,6 +1506,7 @@
case FORMULA_PTG_AREA: case FORMULA_PTG_AREAN: {
GnmCellRef first, last;
if (ver >= MS_BIFF_V8) {
+ CHECK_FORMULA_LEN(8);
getRefV8 (&first,
GSF_LE_GET_GUINT16 (cur+0),
GSF_LE_GET_GUINT16 (cur+4),
@@ -1465,8 +1515,8 @@
GSF_LE_GET_GUINT16 (cur+2),
GSF_LE_GET_GUINT16 (cur+6),
fn_col, fn_row, ptgbase == FORMULA_PTG_AREAN);
- ptg_length = 8;
} else {
+ CHECK_FORMULA_LEN(6);
getRefV7 (&first,
GSF_LE_GET_GUINT8 (cur+4),
GSF_LE_GET_GUINT16 (cur+0),
@@ -1475,7 +1525,6 @@
GSF_LE_GET_GUINT8 (cur+5),
GSF_LE_GET_GUINT16 (cur+2),
fn_col, fn_row, ptgbase == FORMULA_PTG_AREAN);
- ptg_length = 6;
}
parse_list_push_raw (&stack, value_new_cellrange (&first, &last, fn_col, fn_row));
@@ -1485,12 +1534,12 @@
case FORMULA_PTG_MEM_AREA :
case FORMULA_PTG_MEM_ERR :
/* ignore this, we handle at run time */
- ptg_length = 6;
+ CHECK_FORMULA_LEN(6);
break;
case FORMULA_PTG_MEM_FUNC:
/* ignore this, we handle at run time */
- ptg_length = 2;
+ CHECK_FORMULA_LEN(2);
break;
case FORMULA_PTG_NAME_X : {
@@ -1501,9 +1550,13 @@
Sheet *sheet = NULL;
if (ver >= MS_BIFF_V8) {
- guint16 sheet_idx = GSF_LE_GET_GINT16 (cur);
- ExcelExternSheetV8 const *es = excel_externsheet_v8 (
- container->importer, sheet_idx);
+ guint16 sheet_idx;
+ ExcelExternSheetV8 const *es;
+
+ CHECK_FORMULA_LEN(6);
+ sheet_idx = GSF_LE_GET_GINT16 (cur);
+ es = excel_externsheet_v8 (container->importer, sheet_idx);
+
if (es != NULL && es->supbook < container->importer->v8.supbook->len) {
ExcelSupBook const *sup = &g_array_index (
container->importer->v8.supbook,
@@ -1520,10 +1573,11 @@
d (2, fprintf (stderr, "name %hu : externsheet %hu\n",
name_idx, sheet_idx););
-
- ptg_length = 6;
} else {
- gint16 sheet_idx = GSF_LE_GET_GINT16 (cur);
+ gint16 sheet_idx;
+
+ CHECK_FORMULA_LEN(24);
+ sheet_idx = GSF_LE_GET_GINT16 (cur);
name_idx = GSF_LE_GET_GUINT16 (cur+10);
#if 0
gsf_mem_dump (cur, 24);
@@ -1536,7 +1590,6 @@
} else
names = container->v7.externnames;
sheet = excel_externsheet_v7 (container, sheet_idx);
- ptg_length = 24;
}
if (names == NULL || name_idx < 1 || names->len < name_idx ||
@@ -1563,19 +1616,19 @@
case FORMULA_PTG_REF_3D : { /* see S59E2B.HTM */
GnmCellRef first, last;
if (ver >= MS_BIFF_V8) {
+ CHECK_FORMULA_LEN(6);
getRefV8 (&first,
GSF_LE_GET_GUINT16 (cur + 2),
GSF_LE_GET_GUINT16 (cur + 4),
fn_col, fn_row, 0);
last = first;
- ptg_length = 6;
} else {
+ CHECK_FORMULA_LEN(17);
getRefV7 (&first,
GSF_LE_GET_GUINT8 (cur + 16),
GSF_LE_GET_GUINT16 (cur + 14),
fn_col, fn_row, shared);
last = first;
- ptg_length = 17;
}
if (excel_formula_parses_ref_sheets (container, cur, &first.sheet, &last.sheet))
@@ -1592,6 +1645,7 @@
GnmCellRef first, last;
if (ver >= MS_BIFF_V8) {
+ CHECK_FORMULA_LEN(10);
getRefV8 (&first,
GSF_LE_GET_GUINT16 (cur+2),
GSF_LE_GET_GUINT16 (cur+6),
@@ -1600,8 +1654,8 @@
GSF_LE_GET_GUINT16 (cur+4),
GSF_LE_GET_GUINT16 (cur+8),
fn_col, fn_row, 0);
- ptg_length = 10;
} else {
+ CHECK_FORMULA_LEN(20);
getRefV7 (&first,
GSF_LE_GET_GUINT8 (cur+18),
GSF_LE_GET_GUINT16 (cur+14),
@@ -1610,7 +1664,6 @@
GSF_LE_GET_GUINT8 (cur+19),
GSF_LE_GET_GUINT16 (cur+16),
fn_col, fn_row, shared);
- ptg_length = 20;
}
if (excel_formula_parses_ref_sheets (container, cur, &first.sheet, &last.sheet))
parse_list_push_raw (&stack, value_new_error_REF (NULL));
@@ -1620,12 +1673,12 @@
}
case FORMULA_PTG_REF_ERR_3D :
- ptg_length = (ver >= MS_BIFF_V8) ? 6 : 17;
+ CHECK_FORMULA_LEN(ver >= MS_BIFF_V8 ? 6 : 17);
parse_list_push_raw (&stack, value_new_error_REF (NULL));
break;
case FORMULA_PTG_AREA_ERR_3D :
- ptg_length = (ver >= MS_BIFF_V8) ? 10 : 20;
+ CHECK_FORMULA_LEN(ver >= MS_BIFF_V8 ? 10 : 20);
parse_list_push_raw (&stack, value_new_error_REF (NULL));
break;
@@ -1645,6 +1698,8 @@
len_left -= ptg_length + 1;
}
+ length_error:
+
if (error) {
g_printerr ("formula data : %s\n", (shared?" (shared)":"(NOT shared)"));
gsf_mem_dump (mem, length);
@@ -1676,19 +1731,21 @@
#endif
return parse_list_pop (&stack);
}
+#undef CHECK_FORMULA_LEN
+#undef CHECK_FORMULA_ARRAY_LEN
GnmExprTop const *
excel_parse_formula (MSContainer const *container,
ExcelReadSheet const *esheet,
int fn_col, int fn_row,
- guint8 const *mem, guint16 length,
+ guint8 const *mem, guint16 length, guint16 array_length,
gboolean shared,
gboolean *array_element)
{
GnmExprTop const *texpr =
gnm_expr_top_new (excel_parse_formula1 (container, esheet,
fn_col, fn_row,
- mem, length,
+ mem, length, array_length,
shared,
array_element));
return texpr
Modified: branches/gnumeric-1-8/plugins/excel/ms-formula-read.h
==============================================================================
--- branches/gnumeric-1-8/plugins/excel/ms-formula-read.h (original)
+++ branches/gnumeric-1-8/plugins/excel/ms-formula-read.h Thu Feb 7 23:28:20 2008
@@ -18,10 +18,10 @@
GnmExprTop const *
excel_parse_formula (MSContainer const *container,
- ExcelReadSheet const *esheet,
- int fn_col, int fn_row,
- guint8 const *mem, guint16 length,
- gboolean shared,
- gboolean *array_element);
+ ExcelReadSheet const *esheet,
+ int fn_col, int fn_row,
+ guint8 const *mem, guint16 length, guint16 array_length,
+ gboolean shared,
+ gboolean *array_element);
#endif /* GNM_MS_FORMULA_R_H */
Modified: branches/gnumeric-1-8/plugins/excel/ms-obj.c
==============================================================================
--- branches/gnumeric-1-8/plugins/excel/ms-obj.c (original)
+++ branches/gnumeric-1-8/plugins/excel/ms-obj.c Thu Feb 7 23:28:20 2008
@@ -883,10 +883,11 @@
char *type;
guint32 len;
- if ((data+16) > last)
+ if (last - data < 16)
return;
type = excel_get_text (c->importer, data + 16,
- GSF_LE_GET_GUINT16 (data + 14 ), &len);
+ GSF_LE_GET_GUINT16 (data + 14),
+ &len, last - data);
if (NULL == type || strncmp (type, "Forms.", 6)) {
g_free (type);
return;
Modified: branches/gnumeric-1-8/plugins/excel/ms-pivot.c
==============================================================================
--- branches/gnumeric-1-8/plugins/excel/ms-pivot.c (original)
+++ branches/gnumeric-1-8/plugins/excel/ms-pivot.c Thu Feb 7 23:28:20 2008
@@ -100,8 +100,7 @@
guint16 base_fields = GSF_LE_GET_GUINT16 (q->data + 10); /* base */
/* guint16 zero */
guint16 type = GSF_LE_GET_GUINT16 (q->data + 16);
- char *who = excel_get_text (s->importer,
- q->data + 20, GSF_LE_GET_GUINT16 (q->data + 18), NULL);
+ char *who = excel_biff_text_2 (s->importer, q, 18);
fprintf (stderr, "num_rec = %u;\nstream_id = %hu;\n"
"rec per block = %hu;\nbase fields = %hu;\ntotal fields = %hu;\n"
"last modified by = '%s';type = 0x%x, flags = 0x%x;\n",
@@ -139,8 +138,7 @@
guint16 grouped_items = GSF_LE_GET_GUINT16 (q->data + 8);
guint16 base_items = GSF_LE_GET_GUINT16 (q->data + 10);
guint16 std_items = GSF_LE_GET_GUINT16 (q->data + 12);
- char *name = excel_get_text (s->importer, q->data + 16,
- GSF_LE_GET_GUINT16 (q->data + 14), NULL);
+ char *name = excel_biff_text_2 (s->importer, q, 14);
switch (index_type) {
case 1 : /* items follow field description with no index */
s->num_items = GSF_LE_GET_GUINT16 (q->data + 6);
@@ -212,8 +210,7 @@
break;
case BIFF_SXSTRING: if (check_min_len (q, 2)) {
- char *val = excel_get_text (s->importer, q->data + 2,
- GSF_LE_GET_GUINT16 (q->data + 0), NULL);
+ char *val = excel_biff_text_2 (s->importer, q, 0);
d_item (s);
d (2, fprintf (stderr, "'%s' (string);\n", val););
g_free (val);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]