Commit 2fff297d authored by Michael Meeks's avatar Michael Meeks Committed by Michael Meeks

fix memory corruption bug with continue.

2000-06-03  Michael Meeks  <michael@helixcode.com>

	* ms-obj.c (ms_read_TXO): fix memory corruption bug with continue.

	* ms-escher.c (ms_escher_read_Blip): update for Oaf.

	* ms-biff.c (ms_biff_query_new): kill merging.
	(ms_biff_merge_continues): kill forever.
	(ms_biff_query_next_merge): rename to (ms_biff_query_next): and
	clean. (ms_biff_query_unmerge): kill.

2000-06-02  Michael Meeks  <michael@helixcode.com>

	* ms-excel-read.c (biff_get_text): hack nasty auto-header
	detection. (read_sst): split from (ms_excel_read_workbook).
	(get_xtn_lens): split from (biff_get_text).
	(get_utf8_chars, get_string, sst_boundcheck): implement.

2000-01-31  Michael Meeks  <mmeeks@gnu.org>

	* ms-obj.c (ms_read_TXO): re-implement to swallow CONTINUEs &
	make safer.

	* ms-biff.c (ms_biff_query_next_merge): hack do_merge = FALSE
	for now; big clean possible later.

	* ms-escher.c (ms_escher_read_Blip): always use image-generic;
	it works, disable writing image files unless debugging.
	(write_file): conditional compile out.
	(ms_escher_get_data): add BIFF_CONTINUE.

2000-01-30  Michael Meeks  <michael@mejm2.dow.cam.ac.uk>

	* ms-excel-read.c (ms_excel_read_sheet): kill blank_sheet_pos.
parent e2124646
2000-06-03 Michael Meeks <michael@helixcode.com>
* ms-obj.c (ms_read_TXO): fix memory corruption bug with continue.
* ms-escher.c (ms_escher_read_Blip): update for Oaf.
* ms-biff.c (ms_biff_query_new): kill merging.
(ms_biff_merge_continues): kill forever.
(ms_biff_query_next_merge): rename to (ms_biff_query_next): and
clean. (ms_biff_query_unmerge): kill.
2000-06-02 Michael Meeks <michael@helixcode.com>
* ms-excel-read.c (biff_get_text): hack nasty auto-header
detection. (read_sst): split from (ms_excel_read_workbook).
(get_xtn_lens): split from (biff_get_text).
(get_utf8_chars, get_string, sst_boundcheck): implement.
2000-01-31 Michael Meeks <mmeeks@gnu.org>
* ms-obj.c (ms_read_TXO): re-implement to swallow CONTINUEs &
make safer.
* ms-biff.c (ms_biff_query_next_merge): hack do_merge = FALSE
for now; big clean possible later.
* ms-escher.c (ms_escher_read_Blip): always use image-generic;
it works, disable writing image files unless debugging.
(write_file): conditional compile out.
(ms_escher_get_data): add BIFF_CONTINUE.
2000-01-30 Michael Meeks <michael@mejm2.dow.cam.ac.uk>
* ms-excel-read.c (ms_excel_read_sheet): kill blank_sheet_pos.
2000-05-30 Michael Meeks <michael@helixcode.com>
* Makefile.am (INCLUDES): kill explicit libole2 include.
......
......@@ -87,7 +87,6 @@ ms_biff_query_new (MsOleStream *ptr)
bq->opcode = 0;
bq->length = 0;
bq->data_malloced = 0;
bq->num_merges = 0;
bq->pos = ptr;
#if BIFF_DEBUG > 0
dump_biff(bq);
......@@ -95,123 +94,40 @@ ms_biff_query_new (MsOleStream *ptr)
return bq;
}
/**
* I know this is ugly but its not so much my fault !
**/
static int
ms_biff_merge_continues (BiffQuery *bq, guint32 len)
{
GArray *contin;
guint8 tmp[4];
guint32 lp, total_len;
guint8 *d;
typedef struct {
guint8 *data;
guint32 length;
} chunk_t;
chunk_t chunk;
contin = g_array_new (0, 1, sizeof(chunk_t));
/* First block: already got */
chunk.length = bq->length;
if (bq->data_malloced)
chunk.data = bq->data;
else {
chunk.data = g_new (guint8, bq->length);
memcpy (chunk.data, bq->data, bq->length);
}
total_len = chunk.length;
g_array_append_val (contin, chunk);
/* Subsequent continue blocks */
chunk.length = len;
do {
if (bq->pos->position >= bq->pos->size)
return 0;
chunk.data = g_new (guint8, chunk.length);
if (!bq->pos->read_copy (bq->pos, chunk.data, chunk.length))
return 0;
#if BIFF_DEBUG > 8
printf ("Read raw : 0x%x -> 0x%x\n", chunk.data[0],
chunk.data[chunk.length-1]);
#endif
tmp[0] = 0; tmp[1] = 0; tmp[2] = 0; tmp[3] = 0;
bq->pos->read_copy (bq->pos, tmp, 4);
total_len += chunk.length;
g_array_append_val (contin, chunk);
chunk.length = MS_OLE_GET_GUINT16 (tmp+2);
bq->num_merges++;
} while ((MS_OLE_GET_GUINT16(tmp) & 0xff) == BIFF_CONTINUE);
bq->pos->lseek (bq->pos, -4, MsOleSeekCur); /* back back off */
bq->data = g_malloc (total_len);
if (!bq->data)
return 0;
bq->length = total_len;
d = bq->data;
bq->data_malloced = 1;
for (lp=0;lp<contin->len;lp++) {
chunk = g_array_index (contin, chunk_t, lp);
#if BIFF_DEBUG > 8
printf ("Copying block stats with 0x%x ends with 0x%x len 0x%x\n",
chunk.data[0], chunk.data[chunk.length-1], chunk.length);
g_assert ((d-bq->data)+chunk.length<=total_len);
#endif
if (lp) {
memcpy (d, chunk.data, chunk.length);
d+=chunk.length;
} else {
memcpy (d, chunk.data, chunk.length);
d+=chunk.length;
}
g_free (chunk.data);
}
g_array_free (contin, 1);
#if BIFF_DEBUG > 2
printf ("MERGE %d CONTINUES... len 0x%x\n", contin->len, len);
printf ("Biff read code 0x%x, length %d\n", bq->opcode, bq->length);
dump_biff (bq);
#endif
return 1;
}
int
gboolean
ms_biff_query_peek_next (BiffQuery *bq, guint16 *opcode)
{
guint8 data[4];
g_return_val_if_fail (opcode != NULL, 0);
if (!bq || (bq->pos->position + 4 > bq->pos->size))
return 0;
return FALSE;
if (!bq->pos->read_copy (bq->pos, data, 4))
return 0;
return FALSE;
bq->pos->lseek (bq->pos, -4, MsOleSeekCur); /* back back off */
*opcode = MS_OLE_GET_GUINT16 (data);
return 1;
return TRUE;
}
/**
* Returns 0 if has hit end
**/
int
ms_biff_query_next_merge (BiffQuery *bq, gboolean do_merge)
ms_biff_query_next (BiffQuery *bq)
{
guint8 tmp[4];
int ans=1;
if (!bq || bq->pos->position >= bq->pos->size)
return 0;
if (bq->data_malloced) { /* always true for merged records*/
if (bq->data_malloced) {
g_free (bq->data);
bq->num_merges = 0;
bq->data_malloced = 0;
}
g_assert (bq->num_merges == 0);
bq->streamPos = bq->pos->position;
if (!bq->pos->read_copy (bq->pos, tmp, 4))
......@@ -231,15 +147,6 @@ ms_biff_query_next_merge (BiffQuery *bq, gboolean do_merge)
} else
bq->data_malloced = 1;
}
if (ans && do_merge &&
bq->pos->read_copy (bq->pos, tmp, 4)) {
if ((MS_OLE_GET_GUINT16(tmp) & 0xff) == BIFF_CONTINUE)
return ms_biff_merge_continues (bq, MS_OLE_GET_GUINT16(tmp+2));
bq->pos->lseek (bq->pos, -4, MsOleSeekCur); /* back back off */
#if BIFF_DEBUG > 4
printf ("Backed off\n");
#endif
}
#if BIFF_DEBUG > 2
printf ("Biff read code 0x%x, length %d\n", bq->opcode, bq->length);
......@@ -253,16 +160,6 @@ ms_biff_query_next_merge (BiffQuery *bq, gboolean do_merge)
return (ans);
}
void
ms_biff_query_unmerge (BiffQuery *bq)
{
if (!bq || !bq->num_merges)
return;
bq->pos->lseek (bq->pos, -(4 * (bq->num_merges + 1)
+ bq->length), MsOleSeekCur);
ms_biff_query_next_merge (bq, FALSE);
}
void
ms_biff_query_destroy (BiffQuery *bq)
{
......@@ -292,7 +189,6 @@ ms_biff_put_new (MsOleStream *s)
bp->length = 0;
bp->length = 0;
bp->streamPos = s->tell (s);
bp->num_merges = 0;
bp->data_malloced = 0;
bp->len_fixed = 0;
bp->pos = s;
......@@ -320,7 +216,6 @@ ms_biff_put_len_next (BiffPut *bp, guint16 opcode, guint32 len)
bp->ms_op = (opcode >> 8);
bp->ls_op = (opcode & 0xff);
bp->length = len;
bp->num_merges = 0;
bp->streamPos = bp->pos->tell (bp->pos);
if (len > 0)
bp->data = g_new (guint8, len);
......@@ -339,7 +234,6 @@ ms_biff_put_var_next (BiffPut *bp, guint16 opcode)
bp->len_fixed = 0;
bp->ms_op = (opcode >> 8);
bp->ls_op = (opcode & 0xff);
bp->num_merges = 0;
bp->curpos = 0;
bp->length = 0;
bp->data = 0;
......
......@@ -11,8 +11,8 @@
#include <libole2/ms-ole.h>
extern double biff_getdouble (const guint8 *p);
extern void biff_setdouble (guint8 *p, double d);
double biff_getdouble (const guint8 *p);
void biff_setdouble (guint8 *p, double d);
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
/* MW: I have reservations about this. We are assuming not only little
......@@ -39,25 +39,22 @@ struct _BiffQuery {
guint8 ms_op;
guint8 ls_op;
guint16 opcode;
guint32 length; /* NB. can be extended by a continue opcode */
guint8 *data;
int data_malloced;
guint32 length;
guint32 streamPos;
guint16 num_merges;
/* gint16 padding;*/
int data_malloced; /* is *data a copy ? */
MsOleStream *pos;
};
/* Sets up a query on a stream */
extern BiffQuery *ms_biff_query_new (MsOleStream *);
BiffQuery *ms_biff_query_new (MsOleStream *);
/* Updates the BiffQuery structure with the next BIFF record
* returns: 1 for succes, and 0 for EOS(tream) */
extern int ms_biff_query_next_merge (BiffQuery *, gboolean do_merge);
#define ms_biff_query_next(q) ms_biff_query_next_merge ((q), TRUE)
extern int ms_biff_query_peek_next (BiffQuery *, guint16 *opcode);
/* Converts a merged query to the un-merged equivalent */
extern void ms_biff_query_unmerge (BiffQuery *);
extern void ms_biff_query_destroy (BiffQuery *);
int ms_biff_query_next (BiffQuery *);
gboolean ms_biff_query_peek_next (BiffQuery *, guint16 *opcode);
void ms_biff_query_destroy (BiffQuery *);
/*******************************************************************************/
/* Write Side */
......@@ -65,36 +62,34 @@ extern void ms_biff_query_destroy (BiffQuery *);
typedef struct _BiffPut
{
guint8 ms_op;
guint8 ls_op;
guint32 length; /* NB. can be extended by a continue opcode */
guint8 *data;
MsOlePos streamPos;
MsOlePos curpos; /* Curpos is offset from beggining of header */
guint16 num_merges;
/* gint16 padding;*/
int data_malloced;
int len_fixed;
guint8 ms_op;
guint8 ls_op;
guint32 length; /* NB. can be extended by a continue opcode */
guint8 *data;
MsOlePos streamPos;
MsOlePos curpos; /* Curpos is offset from beggining of header */
int data_malloced;
int len_fixed;
MsOleStream *pos;
} BiffPut;
/* Sets up a record on a stream */
extern BiffPut *ms_biff_put_new (MsOleStream *);
extern void ms_biff_put_destroy (BiffPut *);
BiffPut *ms_biff_put_new (MsOleStream *);
void ms_biff_put_destroy (BiffPut *);
/**
* If between the 'next' and 'commit' ls / ms_op are changed they will be
* written correctly.
**/
/* For known length records shorter than 0x2000 bytes. */
extern guint8 *ms_biff_put_len_next (BiffPut *, guint16 opcode, guint32 len);
guint8 *ms_biff_put_len_next (BiffPut *, guint16 opcode, guint32 len);
/* For unknown length records */
extern void ms_biff_put_var_next (BiffPut *, guint16 opcode);
extern void ms_biff_put_var_write (BiffPut *, guint8 *, guint32 len);
void ms_biff_put_var_next (BiffPut *, guint16 opcode);
void ms_biff_put_var_write (BiffPut *, guint8 *, guint32 len);
/* Seeks to pos bytes after the beggining of the record */
extern void ms_biff_put_var_seekto (BiffPut *, MsOlePos pos);
void ms_biff_put_var_seekto (BiffPut *, MsOlePos pos);
/* Must commit after each record */
extern void ms_biff_put_commit (BiffPut *);
void ms_biff_put_commit (BiffPut *);
void dump_biff (BiffQuery *bq);
#endif
......@@ -52,7 +52,7 @@ typedef struct _MSEscherHeader
#define common_header_len 8
static void
ms_escher_blip_new (guint8 const *data, guint32 len, char const *repoid,
ms_escher_blip_new (const guint8 *data, guint32 len, char const *repoid,
ExcelWorkbook * wb)
{
EscherBlip *blip = g_new (EscherBlip, 1);
......@@ -94,15 +94,15 @@ ms_escher_blip_destroy (EscherBlip *blip)
* drawing record size seems to only count the draw records. When we only add
* those the sizes match perfectly.
*/
static guint8 const *
static const guint8 *
ms_escher_get_data (MSEscherState * state,
gint offset, /* bytes from logical start of the stream */
guint num_bytes, /* how many bytes we want, incl prefix */
guint prefix, /* number of bytes of header to skip */
gboolean * needs_free)
{
guint8 * res;
BiffQuery *q = state->q;
guint8 *res;
g_return_val_if_fail (num_bytes >= prefix, NULL);
offset += prefix;
......@@ -119,7 +119,8 @@ ms_escher_get_data (MSEscherState * state,
if (q->opcode != BIFF_MS_O_DRAWING &&
q->opcode != BIFF_MS_O_DRAWING_GROUP &&
q->opcode != BIFF_MS_O_DRAWING_SELECTION) {
q->opcode != BIFF_MS_O_DRAWING_SELECTION &&
q->opcode != BIFF_CONTINUE) {
printf ("ESCHER : Unexpected record type 0x%x\n", q->opcode);
return NULL;
}
......@@ -140,9 +141,9 @@ ms_escher_get_data (MSEscherState * state,
}
res = q->data + offset - state->start_offset;
if ((*needs_free = ((offset+num_bytes) > state->end_offset))) {
guint8 * buffer = g_malloc (num_bytes);
guint8 * tmp = buffer;
if ((*needs_free = ((offset + num_bytes) > state->end_offset))) {
guint8 *buffer = g_malloc (num_bytes);
guint8 *tmp = buffer;
/* Setup front stub */
int len = q->length - (res - q->data);
......@@ -172,7 +173,8 @@ ms_escher_get_data (MSEscherState * state,
/* We should only see DRAW records now */
if (q->opcode != BIFF_MS_O_DRAWING &&
q->opcode != BIFF_MS_O_DRAWING_GROUP &&
q->opcode != BIFF_MS_O_DRAWING_SELECTION) {
q->opcode != BIFF_MS_O_DRAWING_SELECTION &&
q->opcode != BIFF_CONTINUE) {
printf ("ESCHER : Unexpected record type 0x%x\n", q->opcode);
return NULL;
}
......@@ -183,6 +185,7 @@ ms_escher_get_data (MSEscherState * state,
res = q->data;
len = q->length;
} while ((num_bytes - (tmp - buffer)) > len);
/* Copy back stub */
......@@ -191,7 +194,6 @@ ms_escher_get_data (MSEscherState * state,
if (ms_excel_read_debug > 1)
printf ("record %d) add %d bytes;\n", ++counter, num_bytes - (tmp-buffer));
#endif
return buffer;
}
......@@ -233,7 +235,7 @@ static gboolean
ms_escher_read_SplitMenuColors (MSEscherState * state, MSEscherHeader * h)
{
gboolean needs_free;
guint8 const * data;
const guint8 * data;
g_return_val_if_fail (h->instance == 4, TRUE);
g_return_val_if_fail (h->len == 24, TRUE); /* header + 4*4 */
......@@ -275,8 +277,9 @@ bliptype_name (int const type)
}
}
#ifndef NO_DEBUG_EXCEL
static void
write_file (gchar const * const name, guint8 const * data,
write_file (gchar const * const name, const guint8 * data,
gint len, int stored_type)
{
static int num = 0;
......@@ -290,32 +293,31 @@ write_file (gchar const * const name, guint8 const * data,
if (f) {
fwrite (data, len, 1, f);
fclose (f);
#ifndef NO_DEBUG_EXCEL
if (ms_excel_read_debug > 0)
printf ("written 0x%x bytes to '%s';\n",
len, file_name->str);
#endif
} else
printf ("Can't open '%s';\n",
file_name->str);
g_string_free (file_name, 1);
}
#endif
static gboolean
ms_escher_read_BSE (MSEscherState * state, MSEscherHeader * h)
{
/* read the header */
gboolean needs_free;
guint8 const * data =
const guint8 * data =
ms_escher_get_data (state, h->offset, 34,
common_header_len, &needs_free);
guint8 const win_type = MS_OLE_GET_GUINT8 (data + 0);
guint8 const mac_type = MS_OLE_GET_GUINT8 (data + 1);
const guint8 win_type = MS_OLE_GET_GUINT8 (data + 0);
const guint8 mac_type = MS_OLE_GET_GUINT8 (data + 1);
guint32 const size = MS_OLE_GET_GUINT32(data + 20);
guint32 const ref_count = MS_OLE_GET_GUINT32(data + 24);
gint32 const del_offset = MS_OLE_GET_GUINT32(data + 28);
guint8 const is_texture = MS_OLE_GET_GUINT8 (data + 32);
guint8 const name_len = MS_OLE_GET_GUINT8 (data + 33);
const guint8 is_texture = MS_OLE_GET_GUINT8 (data + 32);
const guint8 name_len = MS_OLE_GET_GUINT8 (data + 33);
guint8 checksum[16]; /* RSA Data Security, Inc. MD4 Message-Digest Algorithm */
char *name = "unknown";
int i;
......@@ -393,20 +395,22 @@ ms_escher_read_Blip (MSEscherState * state, MSEscherHeader * h)
{
int const header = 17 + primary_uid_size + common_header_len;
gboolean needs_free;
guint8 const *data =
const char *repoid;
const guint8 *data =
ms_escher_get_data (state, h->offset, h->len,
header, &needs_free);
const char *reproid = NULL;
reproid = "embeddable:image-generic";
/* if (blip_instance == 0x6e0)
repoid = "bonobo-object:image-x-png";
else
reproid = "embeddable:image-jpeg";*/
#if USING_OAF
repoid = "OAFIID:eog_image-generic:0d77ee99-ce0d-4463-94ec-99969f567f33";
#else
repoid = "embeddable:image-generic";
#endif
ms_escher_blip_new (data, h->len - header, repoid, state->wb);
ms_escher_blip_new (data, h->len - header,
reproid, state->wb);
write_file ("unknown", data, h->len - header, h->fbt - Blip_START);
#ifndef NO_DEBUG_EXCEL
if (ms_excel_read_debug > 1)
write_file ("unknown", data, h->len - header, h->fbt - Blip_START);
#endif
break;
}
......@@ -593,7 +597,7 @@ static gboolean
ms_escher_read_Sp (MSEscherState * state, MSEscherHeader * h)
{
gboolean needs_free;
guint8 const *data =
const guint8 *data =
ms_escher_get_data (state, h->offset, 8,
common_header_len, &needs_free);
......@@ -652,7 +656,7 @@ static gboolean
ms_escher_read_ClientAnchor (MSEscherState * state, MSEscherHeader * h)
{
gboolean needs_free, res = TRUE;
guint8 const *data;
const guint8 *data;
g_return_val_if_fail (!h->anchor_set, TRUE);
......@@ -719,7 +723,7 @@ static gboolean
ms_escher_read_Dg (MSEscherState * state, MSEscherHeader * h)
{
#if 0
guint8 const * data = h->data + common_header_len;
const guint8 * data = h->data + common_header_len;
guint32 num_shapes = MS_OLE_GET_GUINT32(data);
/* spid_cur = last SPID given to an SP in this DG :-) */
guint32 spid_cur = MS_OLE_GET_GUINT32(data+4);
......@@ -749,7 +753,7 @@ ms_escher_read_Dgg (MSEscherState * state, MSEscherHeader * h)
FDGG fd;
guint32 lp;
guint8 const *data = h->data + common_header_len;
const guint8 *data = h->data + common_header_len;
fd.id_clusts = g_array_new (1, 1, sizeof(ID_CLUST));
fd.max_spid = MS_OLE_GET_GUINT32(data+ 0);
fd.num_id_clust = MS_OLE_GET_GUINT32(data+ 4);
......@@ -1046,11 +1050,11 @@ ms_escher_read_OPT (MSEscherState * state, MSEscherHeader * h)
{
int const num_properties = h->instance;
gboolean needs_free;
guint8 const * const data =
const guint8 * const data =
ms_escher_get_data (state, h->offset, h->len,
common_header_len, &needs_free);
guint8 const *fopte = data;
guint8 const *extra = fopte + 6*num_properties;
const guint8 *fopte = data;
const guint8 *extra = fopte + 6*num_properties;
guint prev_pid = 0; /* A debug tool */
char const * name;
int i;
......@@ -1801,25 +1805,25 @@ ms_escher_read_container (MSEscherState * state, MSEscherHeader * container,
do {
guint16 tmp;
char const * fbt_name = NULL;
char const *fbt_name = NULL;
gboolean (*handler)(MSEscherState * state,
MSEscherHeader * container) = NULL;
gboolean needs_free;
guint8 const * data =
const guint8 *data =
ms_escher_get_data (state, h.offset, common_header_len,
0, &needs_free);
if (data == NULL)
if (!data)
return TRUE;
tmp = MS_OLE_GET_GUINT16 (data+0);
h.fbt = MS_OLE_GET_GUINT16 (data+2);
tmp = MS_OLE_GET_GUINT16 (data + 0);
h.fbt = MS_OLE_GET_GUINT16 (data + 2);
/* Include the length of this header in the record size */
h.len = MS_OLE_GET_GUINT32 (data+4) + common_header_len;
h.len = MS_OLE_GET_GUINT32 (data + 4) + common_header_len;
h.ver = tmp & 0x0f;
h.instance = (tmp>>4) & 0xfff;
h.instance = (tmp >> 4) & 0xfff;
#ifndef NO_DEBUG_EXCEL
if (ms_excel_read_debug > 0) {
......
This diff is collapsed.
......@@ -1499,7 +1499,7 @@ pre_blanks (ExcelSheet *sheet)
* Another optimization we do: When writing to file, we need the cell
* pointer and the XF style index for each cell. To avoid having to
* locate the cell pointer and computing the style once more, we cache
* the cell pointer and XF index in en ExcelCell in the cells table.
* the cell pointer and XF index in an ExcelCell in the cells table.
**/
static void
gather_styles (ExcelWorkbook *wb)
......
......@@ -9,6 +9,7 @@
**/
#include <config.h>
#include "ms-obj.h"
#include "ms-chart.h"
#include "ms-escher.h"
......@@ -54,7 +55,8 @@ int ms_excel_object_debug;
*/
static gboolean
object_anchor_to_position (double pixels[4], MSObj*obj, Sheet const * sheet,
eBiff_version const ver)
eBiff_version const ver)
{
float const row_denominator = (ver >= eBiffV8) ? 256. : 1024.;
int i;
......@@ -239,7 +241,7 @@ ms_excel_sheet_destroy_objs (ExcelSheet *sheet)
gboolean
ms_parse_object_anchor (anchor_point anchor[4],
Sheet const * sheet, guint8 const * data)
const Sheet *sheet, const guint8 *data)
{
/* Words 0, 4, 8, 12 : The row/col of the corners */
/* Words 2, 6, 10, 14 : distance from cell edge */
......@@ -271,68 +273,70 @@ ms_parse_object_anchor (anchor_point anchor[4],
* See: S59EOE.HTM
*/
char *
ms_read_TXO (BiffQuery *q, ExcelWorkbook * wb)
ms_read_TXO (BiffQuery *q, ExcelWorkbook *wb)
{
static char const * const orientations[] = {
static char const * const orientations [] = {
"Left to right",
"Top to Bottom",
"Bottom to Top on Side",
"Top to Bottom on Side"
};
static char const * const haligns[] = {
static char const * const haligns [] = {
"At left", "Horizontaly centered",
"At right", "Horizontaly justified"
};
static char const * const valigns[] = {
static char const * const valigns [] = {
"At top", "Verticaly centered",
"At bottom", "Verticaly justified"
};
guint16 const options = MS_OLE_GET_GUINT16 (q->data);
guint16 const orient = MS_OLE_GET_GUINT16 (q->data+2);
guint16 const text_len = MS_OLE_GET_GUINT16 (q->data+10);
guint16 const num_formats = MS_OLE_GET_GUINT16 (q->data+12);
guint16 const options = MS_OLE_GET_GUINT16 (q->data);
guint16 const orient = MS_OLE_GET_GUINT16 (q->data + 2);
guint16 const text_len = MS_OLE_GET_GUINT16 (q->data + 10);
/* guint16 const num_formats = MS_OLE_GET_GUINT16 (q->data + 12);*/
int const halign = (options >> 1) & 0x7;
int const valign = (options >> 4) & 0x7;
char * text = g_new(char, text_len+1);
guint8 const unicode_flag = MS_OLE_GET_GUINT8 (q->data+18);
guchar const * ptr;
int i, increment = 1;
char *text = g_new (char, text_len + 1);
const guint8 unicode_flag = MS_OLE_GET_GUINT8 (q->data + 18);
guint16 peek_op;
g_return_val_if_fail (orient <= 3, NULL);
g_return_val_if_fail (1 <= halign && halign <= 4, NULL);
g_return_val_if_fail (1 <= valign && valign <= 4, NULL);
#if 0
/* TODO : figure this out. There seem to be strings with 0 formats too.
* do they indicate empty strings ? */
if (num_formats < 2) {
g_warning ("EXCEL : docs state that there should be >= 2 formats. "
"This record has %d", num_formats);
return;
}
#endif
/* MS-Documentation error. The offset for the reserved 4 x 0 is 18 */
if (unicode_flag) {
static gboolean first = TRUE;
if (first) {
first = FALSE;
g_warning ("EXCEL : Unicode text is unsupported");
text [0] = '\0';
if (ms_biff_query_peek_next (q, &peek_op) &&
peek_op == BIFF_CONTINUE) {
guint8 *data;
int i, increment = 1;
ms_biff_query_next (q);
data = q->data;
if (unicode_flag) {
increment = 2;
data++;
}
increment = 2;
ptr = q->data + 20;
} else
ptr = q->data + 19;
for (i = 0; i < text_len ; ++i)
text[i] = ptr[i*increment];
text[text_len] = '\0';
/* FIXME : Should I worry about padding between the records ? */
for (i = 0; i < num_formats ; ++i) {
/* TODO TODO finish */
}
/*
* FIXME: Use biff_get_text or something ?
*/
if (q->length < increment * text_len) {
g_free (text);
text = g_strdup ("Broken continue");
} else {
for (i = 0; i < text_len ; ++i)
text [i] = data [i * increment];
text [text_len] = '\0';
}
if (ms_biff_query_peek_next (q, &peek_op) &&
peek_op == BIFF_CONTINUE)
ms_biff_query_next (q);
else
g_warning ("Unusual, TXO text with no formatting");
} else if (text_len > 0)
g_warning ("TXO len of %d but no continue", text_len);
#ifndef NO_DEBUG_EXCEL
if (ms_excel_object_debug > 0) {
......@@ -364,8 +368,8 @@ ms_obj_dump (guint8 const * const data, int const len, char const * const name)
* See: S59DAD.HTM
*/
static gboolean
ms_obj_read_pre_biff8_obj (BiffQuery *q, ExcelWorkbook * wb,
Sheet * sheet, MSObj * obj)
ms_obj_read_pre_biff8_obj (BiffQuery *q, ExcelWorkbook *wb,
Sheet *sheet, MSObj *obj)
{
/* TODO : Lots of docs for these things. Write the parser. */
......@@ -383,7 +387,8 @@ ms_obj_read_pre_biff8_obj (BiffQuery *q, ExcelWorkbook * wb,