diff --git a/ChangeLog-1999-07-09 b/ChangeLog-1999-07-09 index d8914e2e1a33f98102688329dc177cf5b5293401..0667554ced86dd2cfd23bff4525ef003ca05458b 100644 --- a/ChangeLog-1999-07-09 +++ b/ChangeLog-1999-07-09 @@ -1,3 +1,14 @@ +1998-11-28 Michael Meeks + + * plugins/excel/ms-formula.c(ms_excel_parse_formula): Fixed serious + memory leaks on return values from cellref_name + + * plugins/excel/ms-formula.c(getRefV7): Now sets CellRef->sheet properly + (getRefV8): same. + + * plugins/excel/ms-ole.c: Several minor changes, moving seperate + structures back into the raw datastream with macros. + 1998-11-28 Miguel de Icaza * src/gnumeric-util.c (gnumeric_notice): Do not use diff --git a/ChangeLog-2000-02-23 b/ChangeLog-2000-02-23 index d8914e2e1a33f98102688329dc177cf5b5293401..0667554ced86dd2cfd23bff4525ef003ca05458b 100644 --- a/ChangeLog-2000-02-23 +++ b/ChangeLog-2000-02-23 @@ -1,3 +1,14 @@ +1998-11-28 Michael Meeks + + * plugins/excel/ms-formula.c(ms_excel_parse_formula): Fixed serious + memory leaks on return values from cellref_name + + * plugins/excel/ms-formula.c(getRefV7): Now sets CellRef->sheet properly + (getRefV8): same. + + * plugins/excel/ms-ole.c: Several minor changes, moving seperate + structures back into the raw datastream with macros. + 1998-11-28 Miguel de Icaza * src/gnumeric-util.c (gnumeric_notice): Do not use diff --git a/OChangeLog-1999-07-09 b/OChangeLog-1999-07-09 index d8914e2e1a33f98102688329dc177cf5b5293401..0667554ced86dd2cfd23bff4525ef003ca05458b 100644 --- a/OChangeLog-1999-07-09 +++ b/OChangeLog-1999-07-09 @@ -1,3 +1,14 @@ +1998-11-28 Michael Meeks + + * plugins/excel/ms-formula.c(ms_excel_parse_formula): Fixed serious + memory leaks on return values from cellref_name + + * plugins/excel/ms-formula.c(getRefV7): Now sets CellRef->sheet properly + (getRefV8): same. + + * plugins/excel/ms-ole.c: Several minor changes, moving seperate + structures back into the raw datastream with macros. + 1998-11-28 Miguel de Icaza * src/gnumeric-util.c (gnumeric_notice): Do not use diff --git a/OChangeLog-2000-02-23 b/OChangeLog-2000-02-23 index d8914e2e1a33f98102688329dc177cf5b5293401..0667554ced86dd2cfd23bff4525ef003ca05458b 100644 --- a/OChangeLog-2000-02-23 +++ b/OChangeLog-2000-02-23 @@ -1,3 +1,14 @@ +1998-11-28 Michael Meeks + + * plugins/excel/ms-formula.c(ms_excel_parse_formula): Fixed serious + memory leaks on return values from cellref_name + + * plugins/excel/ms-formula.c(getRefV7): Now sets CellRef->sheet properly + (getRefV8): same. + + * plugins/excel/ms-ole.c: Several minor changes, moving seperate + structures back into the raw datastream with macros. + 1998-11-28 Miguel de Icaza * src/gnumeric-util.c (gnumeric_notice): Do not use diff --git a/plugins/excel/ms-excel-read.c b/plugins/excel/ms-excel-read.c index 5f6086eea8c48202b4fc26e4358cb0881b142401..f2b9ffd892396816f78195238b9281cf8e1f5742 100644 --- a/plugins/excel/ms-excel-read.c +++ b/plugins/excel/ms-excel-read.c @@ -400,15 +400,15 @@ ms_excel_set_cell_font (MS_EXCEL_SHEET * sheet, Cell * cell, BIFF_XF_DATA * xf) fd->fontname[i] = tolower (fd->fontname[i]); fd->fontname[i] = '\x0'; cell_set_font (cell, font_change_component (cell->style->font->font_name, 1, fd->fontname)); - printf ("FoNt [-]: %s\n", cell->style->font->font_name); +// printf ("FoNt [-]: %s\n", cell->style->font->font_name); if (fd->italic) { cell_set_font (cell, font_get_italic_name (cell->style->font->font_name)); - printf ("FoNt [i]: %s\n", cell->style->font->font_name); +// printf ("FoNt [i]: %s\n", cell->style->font->font_name); cell->style->font->hint_is_italic = 1; } if (fd->boldness == 0x2bc) { cell_set_font (cell, font_get_bold_name (cell->style->font->font_name)); - printf ("FoNt [b]: %s\n", cell->style->font->font_name); +// printf ("FoNt [b]: %s\n", cell->style->font->font_name); cell->style->font->hint_is_bold = 1; } /* @@ -430,6 +430,9 @@ ms_excel_set_cell_xf (MS_EXCEL_SHEET * sheet, Cell * cell, int xfidx) { GList *ptr; int cnt; + BIFF_XF_DATA *xf ; + static int cache_xfidx = 0 ; + static BIFF_XF_DATA *cache_ptr = 0 ; if (xfidx == 0) { printf ("Normal cell formatting\n"); @@ -439,36 +442,50 @@ ms_excel_set_cell_xf (MS_EXCEL_SHEET * sheet, Cell * cell, int xfidx) printf ("Default cell formatting\n"); return; } - /* - * if (!cell->text) Crash if formatting and no text... - * cell_set_text_simple(cell, "") ; - */ - ptr = g_list_first (sheet->wb->XF_records); - /* - * printf ("Looking for %d\n", xfidx) ; - */ - cnt = 16 + 4; /* - * Magic number ... :-) FIXME - dodgy - */ - while (ptr) { - BIFF_XF_DATA *xf = ptr->data; + xf = cache_ptr ; - if (xf->xftype != eBiffXCell) { - ptr = ptr->next; - continue; - } - if (cnt == xfidx) { /* - * Well set it up then ! FIXME: hack ! + if (cache_xfidx != xfidx || !cache_ptr) + { + cache_xfidx = xfidx ; + cache_ptr = 0 ; + /* + * if (!cell->text) Crash if formatting and no text... + * cell_set_text_simple(cell, "") ; + */ + ptr = g_list_first (sheet->wb->XF_records); + /* + * printf ("Looking for %d\n", xfidx) ; + */ + cnt = 16 + 4; /* + * Magic number ... :-) FIXME - dodgy */ - cell_set_alignment (cell, xf->halign, xf->valign, ORIENT_HORIZ, 1); - ms_excel_set_cell_colors (sheet, cell, xf); - ms_excel_set_cell_font (sheet, cell, xf); - return; + while (ptr) { + xf = ptr->data ; + + if (xf->xftype != eBiffXCell) { + ptr = ptr->next; + continue; + } + if (cnt == xfidx) { + cache_ptr = xf ; + break ; + } + cnt++; + ptr = ptr->next; + if (!ptr) + { + printf ("No XF record for %d out of %d found :-(\n", xfidx, cnt); + return ; + } } - cnt++; - ptr = ptr->next; } - printf ("No XF record for %d out of %d found :-(\n", xfidx, cnt); + + /* + * Well set it up then ! FIXME: hack ! + */ + cell_set_alignment (cell, xf->halign, xf->valign, ORIENT_HORIZ, 1); + ms_excel_set_cell_colors (sheet, cell, xf); + ms_excel_set_cell_font (sheet, cell, xf); } /** diff --git a/plugins/excel/ms-excel.c b/plugins/excel/ms-excel.c index 5f6086eea8c48202b4fc26e4358cb0881b142401..f2b9ffd892396816f78195238b9281cf8e1f5742 100644 --- a/plugins/excel/ms-excel.c +++ b/plugins/excel/ms-excel.c @@ -400,15 +400,15 @@ ms_excel_set_cell_font (MS_EXCEL_SHEET * sheet, Cell * cell, BIFF_XF_DATA * xf) fd->fontname[i] = tolower (fd->fontname[i]); fd->fontname[i] = '\x0'; cell_set_font (cell, font_change_component (cell->style->font->font_name, 1, fd->fontname)); - printf ("FoNt [-]: %s\n", cell->style->font->font_name); +// printf ("FoNt [-]: %s\n", cell->style->font->font_name); if (fd->italic) { cell_set_font (cell, font_get_italic_name (cell->style->font->font_name)); - printf ("FoNt [i]: %s\n", cell->style->font->font_name); +// printf ("FoNt [i]: %s\n", cell->style->font->font_name); cell->style->font->hint_is_italic = 1; } if (fd->boldness == 0x2bc) { cell_set_font (cell, font_get_bold_name (cell->style->font->font_name)); - printf ("FoNt [b]: %s\n", cell->style->font->font_name); +// printf ("FoNt [b]: %s\n", cell->style->font->font_name); cell->style->font->hint_is_bold = 1; } /* @@ -430,6 +430,9 @@ ms_excel_set_cell_xf (MS_EXCEL_SHEET * sheet, Cell * cell, int xfidx) { GList *ptr; int cnt; + BIFF_XF_DATA *xf ; + static int cache_xfidx = 0 ; + static BIFF_XF_DATA *cache_ptr = 0 ; if (xfidx == 0) { printf ("Normal cell formatting\n"); @@ -439,36 +442,50 @@ ms_excel_set_cell_xf (MS_EXCEL_SHEET * sheet, Cell * cell, int xfidx) printf ("Default cell formatting\n"); return; } - /* - * if (!cell->text) Crash if formatting and no text... - * cell_set_text_simple(cell, "") ; - */ - ptr = g_list_first (sheet->wb->XF_records); - /* - * printf ("Looking for %d\n", xfidx) ; - */ - cnt = 16 + 4; /* - * Magic number ... :-) FIXME - dodgy - */ - while (ptr) { - BIFF_XF_DATA *xf = ptr->data; + xf = cache_ptr ; - if (xf->xftype != eBiffXCell) { - ptr = ptr->next; - continue; - } - if (cnt == xfidx) { /* - * Well set it up then ! FIXME: hack ! + if (cache_xfidx != xfidx || !cache_ptr) + { + cache_xfidx = xfidx ; + cache_ptr = 0 ; + /* + * if (!cell->text) Crash if formatting and no text... + * cell_set_text_simple(cell, "") ; + */ + ptr = g_list_first (sheet->wb->XF_records); + /* + * printf ("Looking for %d\n", xfidx) ; + */ + cnt = 16 + 4; /* + * Magic number ... :-) FIXME - dodgy */ - cell_set_alignment (cell, xf->halign, xf->valign, ORIENT_HORIZ, 1); - ms_excel_set_cell_colors (sheet, cell, xf); - ms_excel_set_cell_font (sheet, cell, xf); - return; + while (ptr) { + xf = ptr->data ; + + if (xf->xftype != eBiffXCell) { + ptr = ptr->next; + continue; + } + if (cnt == xfidx) { + cache_ptr = xf ; + break ; + } + cnt++; + ptr = ptr->next; + if (!ptr) + { + printf ("No XF record for %d out of %d found :-(\n", xfidx, cnt); + return ; + } } - cnt++; - ptr = ptr->next; } - printf ("No XF record for %d out of %d found :-(\n", xfidx, cnt); + + /* + * Well set it up then ! FIXME: hack ! + */ + cell_set_alignment (cell, xf->halign, xf->valign, ORIENT_HORIZ, 1); + ms_excel_set_cell_colors (sheet, cell, xf); + ms_excel_set_cell_font (sheet, cell, xf); } /** diff --git a/plugins/excel/ms-formula-read.c b/plugins/excel/ms-formula-read.c index 6d053917b5d67ab743cc171b60b0cd0f287d47ed..b1037c1bef3219b9b40a0d616748ae30e777a483 100644 --- a/plugins/excel/ms-formula-read.c +++ b/plugins/excel/ms-formula-read.c @@ -51,7 +51,7 @@ FORMULA_FUNC_DATA formula_func_data[] = * A useful routine for extracting data from a common * storage structure. **/ -static CellRef *getRefV7(BYTE col, WORD gbitrw, int curcol, int currow) +static CellRef *getRefV7(MS_EXCEL_SHEET *sheet, BYTE col, WORD gbitrw, int curcol, int currow) { CellRef *cr = (CellRef *)malloc(sizeof(CellRef)) ; cr->col = col ; @@ -62,6 +62,7 @@ static CellRef *getRefV7(BYTE col, WORD gbitrw, int curcol, int currow) cr->row-= currow ; if (cr->col_relative) cr->col-= curcol ; + cr->sheet = sheet->gnum_sheet ; /* printf ("7Out : %d, %d at %d, %d\n", cr->col, cr->row, curcol, currow) ; */ return cr ; } @@ -69,7 +70,7 @@ static CellRef *getRefV7(BYTE col, WORD gbitrw, int curcol, int currow) * A useful routine for extracting data from a common * storage structure. **/ -static CellRef *getRefV8(WORD row, WORD gbitcl, int curcol, int currow) +static CellRef *getRefV8(MS_EXCEL_SHEET *sheet, WORD row, WORD gbitcl, int curcol, int currow) { CellRef *cr = (CellRef *)malloc(sizeof(CellRef)) ; cr->row = row ; @@ -80,6 +81,7 @@ static CellRef *getRefV8(WORD row, WORD gbitcl, int curcol, int currow) cr->row-= currow ; if (cr->col_relative) cr->col-= curcol ; + cr->sheet = sheet->gnum_sheet ; /* printf ("8Out : %d, %d at %d, %d\n", cr->col, cr->row, curcol, currow) ; */ return cr ; } @@ -121,6 +123,7 @@ static PARSE_LIST *parse_list_new () static void parse_list_push (PARSE_LIST *list, PARSE_DATA *pd) { + /* printf ("Pushing '%s'\n", pd->name) ; */ list->data = g_list_append (list->data, pd) ; list->length++ ; } @@ -306,16 +309,16 @@ void ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q, char *buffer ; if (sheet->ver == eBiffV8) { - ref = getRefV8 (BIFF_GETWORD(cur), BIFF_GETWORD(cur + 2), fn_col, fn_row) ; + ref = getRefV8 (sheet, BIFF_GETWORD(cur), BIFF_GETWORD(cur + 2), fn_col, fn_row) ; ptg_length = 4 ; } else { - ref = getRefV7 (BIFF_GETBYTE(cur+2), BIFF_GETWORD(cur), fn_col, fn_row) ; + ref = getRefV7 (sheet, BIFF_GETBYTE(cur+2), BIFF_GETWORD(cur), fn_col, fn_row) ; ptg_length = 3 ; } buffer = cellref_name (ref, sheet->gnum_sheet, fn_col, fn_row) ; - parse_list_push_raw(stack, strdup (buffer), NO_PRECEDENCE) ; + parse_list_push_raw(stack, buffer, NO_PRECEDENCE) ; printf ("%s\n", buffer) ; free (ref) ; } @@ -323,22 +326,25 @@ void ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q, case FORMULA_PTG_AREA: { CellRef *first, *last ; - char buffer[128] ; + char buffer[64] ; + char *ptr ; if (sheet->ver == eBiffV8) { - first = getRefV8(BIFF_GETBYTE(cur+0), BIFF_GETWORD(cur+4), fn_col, fn_row) ; - last = getRefV8(BIFF_GETBYTE(cur+2), BIFF_GETWORD(cur+6), fn_col, fn_row) ; + first = getRefV8(sheet, BIFF_GETBYTE(cur+0), BIFF_GETWORD(cur+4), fn_col, fn_row) ; + last = getRefV8(sheet, BIFF_GETBYTE(cur+2), BIFF_GETWORD(cur+6), fn_col, fn_row) ; ptg_length = 8 ; } else { - first = getRefV7(BIFF_GETBYTE(cur+4), BIFF_GETWORD(cur+0), fn_col, fn_row) ; - last = getRefV7(BIFF_GETBYTE(cur+5), BIFF_GETWORD(cur+2), fn_col, fn_row) ; + first = getRefV7(sheet, BIFF_GETBYTE(cur+4), BIFF_GETWORD(cur+0), fn_col, fn_row) ; + last = getRefV7(sheet, BIFF_GETBYTE(cur+5), BIFF_GETWORD(cur+2), fn_col, fn_row) ; ptg_length = 6 ; } - strcpy (buffer, cellref_name (first, sheet->gnum_sheet, fn_col, fn_row)) ; + strcpy (buffer, (ptr = cellref_name (first, sheet->gnum_sheet, fn_col, fn_row))) ; + free (ptr) ; strcat (buffer, ":") ; - strcat (buffer, cellref_name (last, sheet->gnum_sheet, fn_col, fn_row)) ; + strcat (buffer, (ptr=cellref_name (last, sheet->gnum_sheet, fn_col, fn_row))) ; + free (ptr) ; parse_list_push_raw(stack, strdup (buffer), NO_PRECEDENCE) ; printf ("%s\n", buffer) ; free (first) ; diff --git a/plugins/excel/ms-formula.c b/plugins/excel/ms-formula.c index 6d053917b5d67ab743cc171b60b0cd0f287d47ed..b1037c1bef3219b9b40a0d616748ae30e777a483 100644 --- a/plugins/excel/ms-formula.c +++ b/plugins/excel/ms-formula.c @@ -51,7 +51,7 @@ FORMULA_FUNC_DATA formula_func_data[] = * A useful routine for extracting data from a common * storage structure. **/ -static CellRef *getRefV7(BYTE col, WORD gbitrw, int curcol, int currow) +static CellRef *getRefV7(MS_EXCEL_SHEET *sheet, BYTE col, WORD gbitrw, int curcol, int currow) { CellRef *cr = (CellRef *)malloc(sizeof(CellRef)) ; cr->col = col ; @@ -62,6 +62,7 @@ static CellRef *getRefV7(BYTE col, WORD gbitrw, int curcol, int currow) cr->row-= currow ; if (cr->col_relative) cr->col-= curcol ; + cr->sheet = sheet->gnum_sheet ; /* printf ("7Out : %d, %d at %d, %d\n", cr->col, cr->row, curcol, currow) ; */ return cr ; } @@ -69,7 +70,7 @@ static CellRef *getRefV7(BYTE col, WORD gbitrw, int curcol, int currow) * A useful routine for extracting data from a common * storage structure. **/ -static CellRef *getRefV8(WORD row, WORD gbitcl, int curcol, int currow) +static CellRef *getRefV8(MS_EXCEL_SHEET *sheet, WORD row, WORD gbitcl, int curcol, int currow) { CellRef *cr = (CellRef *)malloc(sizeof(CellRef)) ; cr->row = row ; @@ -80,6 +81,7 @@ static CellRef *getRefV8(WORD row, WORD gbitcl, int curcol, int currow) cr->row-= currow ; if (cr->col_relative) cr->col-= curcol ; + cr->sheet = sheet->gnum_sheet ; /* printf ("8Out : %d, %d at %d, %d\n", cr->col, cr->row, curcol, currow) ; */ return cr ; } @@ -121,6 +123,7 @@ static PARSE_LIST *parse_list_new () static void parse_list_push (PARSE_LIST *list, PARSE_DATA *pd) { + /* printf ("Pushing '%s'\n", pd->name) ; */ list->data = g_list_append (list->data, pd) ; list->length++ ; } @@ -306,16 +309,16 @@ void ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q, char *buffer ; if (sheet->ver == eBiffV8) { - ref = getRefV8 (BIFF_GETWORD(cur), BIFF_GETWORD(cur + 2), fn_col, fn_row) ; + ref = getRefV8 (sheet, BIFF_GETWORD(cur), BIFF_GETWORD(cur + 2), fn_col, fn_row) ; ptg_length = 4 ; } else { - ref = getRefV7 (BIFF_GETBYTE(cur+2), BIFF_GETWORD(cur), fn_col, fn_row) ; + ref = getRefV7 (sheet, BIFF_GETBYTE(cur+2), BIFF_GETWORD(cur), fn_col, fn_row) ; ptg_length = 3 ; } buffer = cellref_name (ref, sheet->gnum_sheet, fn_col, fn_row) ; - parse_list_push_raw(stack, strdup (buffer), NO_PRECEDENCE) ; + parse_list_push_raw(stack, buffer, NO_PRECEDENCE) ; printf ("%s\n", buffer) ; free (ref) ; } @@ -323,22 +326,25 @@ void ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q, case FORMULA_PTG_AREA: { CellRef *first, *last ; - char buffer[128] ; + char buffer[64] ; + char *ptr ; if (sheet->ver == eBiffV8) { - first = getRefV8(BIFF_GETBYTE(cur+0), BIFF_GETWORD(cur+4), fn_col, fn_row) ; - last = getRefV8(BIFF_GETBYTE(cur+2), BIFF_GETWORD(cur+6), fn_col, fn_row) ; + first = getRefV8(sheet, BIFF_GETBYTE(cur+0), BIFF_GETWORD(cur+4), fn_col, fn_row) ; + last = getRefV8(sheet, BIFF_GETBYTE(cur+2), BIFF_GETWORD(cur+6), fn_col, fn_row) ; ptg_length = 8 ; } else { - first = getRefV7(BIFF_GETBYTE(cur+4), BIFF_GETWORD(cur+0), fn_col, fn_row) ; - last = getRefV7(BIFF_GETBYTE(cur+5), BIFF_GETWORD(cur+2), fn_col, fn_row) ; + first = getRefV7(sheet, BIFF_GETBYTE(cur+4), BIFF_GETWORD(cur+0), fn_col, fn_row) ; + last = getRefV7(sheet, BIFF_GETBYTE(cur+5), BIFF_GETWORD(cur+2), fn_col, fn_row) ; ptg_length = 6 ; } - strcpy (buffer, cellref_name (first, sheet->gnum_sheet, fn_col, fn_row)) ; + strcpy (buffer, (ptr = cellref_name (first, sheet->gnum_sheet, fn_col, fn_row))) ; + free (ptr) ; strcat (buffer, ":") ; - strcat (buffer, cellref_name (last, sheet->gnum_sheet, fn_col, fn_row)) ; + strcat (buffer, (ptr=cellref_name (last, sheet->gnum_sheet, fn_col, fn_row))) ; + free (ptr) ; parse_list_push_raw(stack, strdup (buffer), NO_PRECEDENCE) ; printf ("%s\n", buffer) ; free (first) ; diff --git a/plugins/excel/ms-ole.c b/plugins/excel/ms-ole.c index 42855c3b01f645dce2efdea66d5a955d897a6691..27d406fc25db03e5d76de9a862e3f37d15681b64 100644 --- a/plugins/excel/ms-ole.c +++ b/plugins/excel/ms-ole.c @@ -27,6 +27,15 @@ (*(p+2)<<16)+ \ (*(p+3)<<24)) +#define PUT_GUINT8(p,n) (*(p+0)=n) +#define PUT_GUINT16(p,n) ((*(p+0)=(n&0xff)), \ + (*(p+1)=(n>>8)&0xff)) +#define PUT_GUINT32(p,n) ((*(p+0)=n&0xff), \ + (*(p+1)=(n>>8)&0xff), \ + (*(p+2)=(n>>16)&0xff), \ + (*(p+3)=(n>>24)&0xff)) + + #define MS_OLE_SPECIAL_BLOCK 0xfffffffd #define MS_OLE_END_OF_CHAIN 0xfffffffe #define MS_OLE_UNUSED_BLOCK 0xffffffff @@ -37,23 +46,31 @@ /** * These look _ugly_ but reduce to a few shifts, bit masks and adds * Under optimisation these are _really_ quick ! - * NB. Parameters are always: 'MS_OLE *', followed by a guint32 block. + * NB. Parameters are always: 'MS_OLE *', followed by a guint32 block or index **/ +/* This is a list of big blocks which contain a flat description of all blocks in the file. + Effectively inside these blocks is a FAT of chains of other BBs, so the theoretical max + size = 128 BB Fat blocks, thus = 128*512*512/4 blocks ~= 8.4MBytes */ +/* The number of Big Block Descriptor (fat) Blocks */ +#define NUMBER_OF_BBD_BLOCKS(f) (GET_GUINT32((f)->mem + 0x2c)) +/* The block locations of the Big Block Descriptor Blocks */ +#define BBD_LIST(f,i) (GET_GUINT32((f)->mem + 0x4c + (i)*4)) + /* Find the position of the start in memory of a big block */ -#define MS_OLE_GET_BB_START_PTR(f,n) ((guint8 *)(f->mem+(n+1)*MS_OLE_BB_BLOCK_SIZE)) +#define GET_BB_START_PTR(f,n) ((guint8 *)(f->mem+(n+1)*MS_OLE_BB_BLOCK_SIZE)) /* Find the position of the start in memory of a small block */ -#define MS_OLE_GET_SB_START_PTR(f,n) ( MS_OLE_GET_BB_START_PTR((f), (f)->header.sbf_list[((MS_OLE_SB_BLOCK_SIZE*(n))/MS_OLE_BB_BLOCK_SIZE)]) + \ - (MS_OLE_SB_BLOCK_SIZE*(n)%MS_OLE_BB_BLOCK_SIZE) ) +#define GET_SB_START_PTR(f,n) ( GET_BB_START_PTR((f), (f)->header.sbf_list[((MS_OLE_SB_BLOCK_SIZE*(n))/MS_OLE_BB_BLOCK_SIZE)]) + \ + (MS_OLE_SB_BLOCK_SIZE*(n)%MS_OLE_BB_BLOCK_SIZE) ) /* Gives the position in memory, as a GUINT8 *, of the BB entry ( in a chain ) */ -#define GET_BB_CHAIN_PTR(f,n) (MS_OLE_GET_BB_START_PTR((f), (f)->header.bbd_list[(((n)*sizeof(BBPtr))/MS_OLE_BB_BLOCK_SIZE)]) + \ +#define GET_BB_CHAIN_PTR(f,n) (GET_BB_START_PTR((f), (BBD_LIST(f, ( ((n)*sizeof(BBPtr)) / MS_OLE_BB_BLOCK_SIZE)))) + \ (((n)*sizeof(BBPtr))%MS_OLE_BB_BLOCK_SIZE)) /* Gives the position in memory, as a GUINT8 *, of the SB entry ( in a chain ) */ -#define GET_SB_CHAIN_PTR(f,n) (MS_OLE_GET_BB_START_PTR(f, f->header.sbd_list[(((n)*sizeof(SBPtr))/MS_OLE_BB_BLOCK_SIZE)]) + \ +#define GET_SB_CHAIN_PTR(f,n) (GET_BB_START_PTR(f, f->header.sbd_list[(((n)*sizeof(SBPtr))/MS_OLE_BB_BLOCK_SIZE)]) + \ (((n)*sizeof(SBPtr))%MS_OLE_BB_BLOCK_SIZE)) /* Returns the next BB after this one in the chain */ @@ -125,11 +142,11 @@ dump_header (MS_OLE *f) MS_OLE_HEADER *h = &f->header ; printf ("--------------------------MS_OLE HEADER-------------------------\n") ; printf ("Num BBD Blocks : %d Root %d, SBD %d\n", - h->number_of_bbd_blocks, + NUMBER_OF_BBD_BLOCKS(f), (int)h->root_startblock, (int)h->sbd_startblock) ; - for (lp=0;lpnumber_of_bbd_blocks;lp++) - printf ("bbd_list[%d] = %d\n", lp, (int)h->bbd_list[lp]) ; + for (lp=0;lpnumber_of_root_blocks) ; for (lp=0;lpnumber_of_root_blocks;lp++) @@ -148,35 +165,26 @@ read_header (MS_OLE *f) MS_OLE_HEADER *header = &f->header ; /* Magic numbers */ - header->number_of_bbd_blocks = GET_GUINT32(ptr + 0x2c) ; header->root_startblock = GET_GUINT32(ptr + 0x30) ; header->sbd_startblock = GET_GUINT32(ptr + 0x3c) ; - /* So: the Big Block Description (bbd) is read, it is a chain of BBs containing - effectively a FAT of chains of other BBs, so the theoretical max size = 128 BB Fat blocks - Thus = 128*512*512/4 blocks ~= 8.4MBytes */ - { - int lp ; - header->bbd_list = g_new (BBPtr, header->number_of_bbd_blocks) ; - for (lp=0;lpnumber_of_bbd_blocks;lp++) - header->bbd_list[lp] = GET_GUINT32(ptr + 0x4c + lp*4) ; - } return 1 ; } static void dump_allocation (MS_OLE *f) { - int blk, dep ; + int blk, dep, lp ; printf ("Big block allocation\n") ; dep = 0 ; - while (depheader.number_of_bbd_blocks) + blk = 0 ; + while (depheader.bbd_list[dep]) + blk*sizeof(BBPtr)) ; + type = GET_GUINT32(GET_BB_CHAIN_PTR(f, blk)) ; if ((blk + dep*(MS_OLE_BB_BLOCK_SIZE/sizeof(BBPtr)))*MS_OLE_BB_BLOCK_SIZE > f->length) printf ("*") ; else if (type == MS_OLE_SPECIAL_BLOCK) @@ -187,6 +195,7 @@ dump_allocation (MS_OLE *f) printf ("X") ; else printf ("O") ; + blk++ ; if (blk%16==15) printf (" - %d\n", blk) ; } @@ -195,13 +204,14 @@ dump_allocation (MS_OLE *f) printf ("Small block allocation\n") ; dep = 0 ; + blk = 0 ; while (depheader.number_of_sbd_blocks) { printf ("SB block %d ( = BB block %d )\n", dep, f->header.sbd_list[dep]) ; - for (blk=0;blkheader.sbd_list[dep]) + blk*sizeof(SBPtr)) ; + type = GET_GUINT32(GET_SB_CHAIN_PTR(f, blk)) ; if (type == MS_OLE_SPECIAL_BLOCK) printf ("S") ; else if (type == MS_OLE_UNUSED_BLOCK) @@ -210,6 +220,7 @@ dump_allocation (MS_OLE *f) printf ("X") ; else printf ("O") ; + blk++ ; if (blk%16==15) printf (" - %d\n", blk) ; } @@ -280,7 +291,7 @@ PPSPtr_to_guint8 (MS_OLE *f, PPSPtr ptr) guint8 *ans ; assert (ppsblockheader.number_of_root_blocks) ; - ans = MS_OLE_GET_BB_START_PTR(f,f->header.root_list[ppsblock]) + idx ; + ans = GET_BB_START_PTR(f,f->header.root_list[ppsblock]) + idx ; // printf ("PPSPtr %d -> block %d : BB root_list[%d] = %d & idx = %d\n", ptr, ppsblock, ppsblock, // f->header.root_list[ppsblock], idx) ; return ans ; @@ -510,7 +521,7 @@ ms_ole_read_ptr_bb (MS_OLE_STREAM *s, guint32 length) block_left = MS_OLE_BB_BLOCK_SIZE - s->offset ; if (length<=block_left) /* Just return the pointer then */ - return (MS_OLE_GET_BB_START_PTR(s->file, s->block) + s->offset) ; + return (GET_BB_START_PTR(s->file, s->block) + s->offset) ; /* Is it contiguous ? */ { @@ -541,7 +552,7 @@ ms_ole_read_ptr_bb (MS_OLE_STREAM *s, guint32 length) } } /* Straight map, simply return a pointer */ - return MS_OLE_GET_BB_START_PTR(s->file, s->block) + s->offset ; + return GET_BB_START_PTR(s->file, s->block) + s->offset ; } } @@ -562,7 +573,7 @@ ms_ole_read_ptr_sb (MS_OLE_STREAM *s, guint32 length) block_left = MS_OLE_SB_BLOCK_SIZE - s->offset ; if (length<=block_left) /* Just return the pointer then */ - return (MS_OLE_GET_SB_START_PTR(s->file, s->block) + s->offset) ; + return (GET_SB_START_PTR(s->file, s->block) + s->offset) ; /* Is it contiguous ? */ { @@ -593,7 +604,7 @@ ms_ole_read_ptr_sb (MS_OLE_STREAM *s, guint32 length) } } /* Straight map, simply return a pointer */ - return MS_OLE_GET_SB_START_PTR(s->file, s->block) + s->offset ; + return GET_SB_START_PTR(s->file, s->block) + s->offset ; } } @@ -615,7 +626,7 @@ ms_ole_read_copy_bb (MS_OLE_STREAM *s, guint8 *ptr, guint32 length) length - block_left) ; return 0 ; } - memcpy (ptr, MS_OLE_GET_BB_START_PTR(s->file, s->block) + s->offset, length) ; + memcpy (ptr, GET_BB_START_PTR(s->file, s->block) + s->offset, length) ; return 1 ; } @@ -634,7 +645,7 @@ ms_ole_read_copy_bb (MS_OLE_STREAM *s, guint8 *ptr, guint32 length) int cpylen = MS_OLE_BB_BLOCK_SIZE - offset ; if (cpylen>bytes) cpylen = bytes ; - src = MS_OLE_GET_BB_START_PTR(s->file, block) + offset ; + src = GET_BB_START_PTR(s->file, block) + offset ; if (block == s->pps->end_block && cpylen > s->pps->pps_size%MS_OLE_BB_BLOCK_SIZE) { @@ -666,7 +677,7 @@ ms_ole_read_copy_sb (MS_OLE_STREAM *s, guint8 *ptr, guint32 length) length - block_left) ; return 0 ; } - memcpy (ptr, MS_OLE_GET_SB_START_PTR(s->file, s->block) + s->offset, length) ; + memcpy (ptr, GET_SB_START_PTR(s->file, s->block) + s->offset, length) ; return 1 ; } @@ -685,7 +696,7 @@ ms_ole_read_copy_sb (MS_OLE_STREAM *s, guint8 *ptr, guint32 length) int cpylen = MS_OLE_SB_BLOCK_SIZE - offset ; if (cpylen>bytes) cpylen = bytes ; - src = MS_OLE_GET_SB_START_PTR(s->file, block) + offset ; + src = GET_SB_START_PTR(s->file, block) + offset ; if (block == s->pps->end_block && cpylen > s->pps->pps_size%MS_OLE_SB_BLOCK_SIZE) { @@ -763,15 +774,50 @@ find_stream (MS_OLE *f, char *name) return 0; } +static guint32 +next_free_bb (MS_OLE *f) +{ + guint32 dep, blk, sblk ; + + dep = 0 ; + blk = 0 ; + while (dep f->length) + { + printf ("Extend & remap file ...\n") ; + return 0 ; + } + printf ("Unused block at %d\n", blk) ; + return blk ; + } + } + dep++ ; + } + + printf ("Out of unused BB space !\n") ; + return 0 ; +} /** * Creates an extra block on the end of a BB file + * Leaving the pps record in an unusual state, to be + * fixed by all users. **/ static void ms_ole_addblock_bb (MS_OLE_STREAM *s) { - /* guint32 lastblk = s->pps->end_block ; - guint32 newblk = next_free_block (s->file) ; */ + guint32 lastblk = s->pps->end_block ; + guint32 newblk = next_free_bb (s->file) ; + PUT_GUINT32(GET_BB_CHAIN_PTR(s->file, lastblk), newblk) ; + PUT_GUINT32(GET_BB_CHAIN_PTR(s->file, newblk), MS_OLE_END_OF_CHAIN) ; + s->pps->end_block = newblk ; } static void diff --git a/plugins/excel/ms-ole.h b/plugins/excel/ms-ole.h index 8b56c51935af71610fc0923c3d22bebdc3737881..3d72be7ff6cc40859c5ee68af712963fe9b99b2c 100644 --- a/plugins/excel/ms-ole.h +++ b/plugins/excel/ms-ole.h @@ -15,7 +15,6 @@ typedef guint32 SBPtr ; typedef struct _MS_OLE_HEADER { /* Header Data */ - guint32 number_of_bbd_blocks ; /* bbd = Big Block Depot */ BBPtr *bbd_list ; /* [number_of_bbd_blocks] very often 1 */ /* sbd = Small Block Depot ( made up of BB's BTW ) */