[gnumeric] Fix crash on corrupted files. [#702322]



commit 63f0bc1d7c63df80112e4ad0fe215908d768d977
Author: Andreas J Guelzow <aguelzow pyrshep ca>
Date:   Sat Jun 15 14:24:37 2013 -0600

    Fix crash on corrupted files. [#702322]
    
    2013-06-15  Andreas J. Guelzow <aguelzow pyrshep ca>
    
        * openoffice-read.c (odf_destroy_object_offset): new
        (oo_table_end): use odf_destroy_object_offset
        (openoffice_file_open): clean up properly even if the content file was
        malformed.

 NEWS                                 |    3 +-
 plugins/openoffice/ChangeLog         |    7 ++
 plugins/openoffice/openoffice-read.c |  121 +++++++++++++++++++---------------
 3 files changed, 77 insertions(+), 54 deletions(-)
---
diff --git a/NEWS b/NEWS
index d56e826..e5d11dc 100644
--- a/NEWS
+++ b/NEWS
@@ -23,7 +23,8 @@ Andreas:
          export [#702169]
        * Fix ODF crash. [#702197]
        * In ODF import ignored mentioned but not included sheets. [#698388]
-       * Fix crash on corrupted files.  [#702205] [#702219] [#702285] [#702288]
+       * Fix crash on corrupted files.  [#702205] [#702219] [#702285]
+         [#702288] [#702322]
        * Some documentation improvements. [Debian #621735] [Debian #530462] 
 
 Darrell Tangman:
diff --git a/plugins/openoffice/ChangeLog b/plugins/openoffice/ChangeLog
index 20b38b8..9cc2f98 100644
--- a/plugins/openoffice/ChangeLog
+++ b/plugins/openoffice/ChangeLog
@@ -1,5 +1,12 @@
 2013-06-15  Andreas J. Guelzow <aguelzow pyrshep ca>
 
+       * openoffice-read.c (odf_destroy_object_offset): new
+       (oo_table_end): use odf_destroy_object_offset
+       (openoffice_file_open): clean up properly even if the content file was
+       malformed.
+
+2013-06-15  Andreas J. Guelzow <aguelzow pyrshep ca>
+
        * openoffice-read.c (odf_page_layout): always set state->print.cur_pi
        (odf_master_page): ditto
 
diff --git a/plugins/openoffice/openoffice-read.c b/plugins/openoffice/openoffice-read.c
index cd92c80..dbd8287 100644
--- a/plugins/openoffice/openoffice-read.c
+++ b/plugins/openoffice/openoffice-read.c
@@ -2824,6 +2824,16 @@ odf_z_idx_compare (gconstpointer a, gconstpointer b)
 }
 
 static void
+odf_destroy_object_offset (gpointer data)
+{
+       object_offset_t *ob_off = data;
+
+       g_free (ob_off->control);
+       g_object_unref (ob_off->so);
+       g_free (ob_off);
+}
+
+static void
 odf_complete_control_setup (OOParseState *state, object_offset_t const *ob_off)
 {
        OOControl *oc = g_hash_table_lookup (state->controls, ob_off->control);
@@ -3000,9 +3010,7 @@ oo_table_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
                sheet_object_set_sheet (ob_off->so, state->pos.sheet);
                if (ob_off->control)
                        odf_complete_control_setup (state, ob_off);
-               g_free (ob_off->control);
-               g_object_unref (ob_off->so);
-               g_free (ob_off);
+               odf_destroy_object_offset (ob_off);
                l->data = NULL;
        }
 
@@ -11836,6 +11844,7 @@ openoffice_file_open (G_GNUC_UNUSED GOFileOpener const *fo, GOIOContext *io_cont
        OOParseState     state;
        GError          *err = NULL;
        int i;
+       gboolean         content_malformed = FALSE;
 
        zip = gsf_infile_zip_new (input, &err);
        if (zip == NULL) {
@@ -12004,7 +12013,7 @@ openoffice_file_open (G_GNUC_UNUSED GOFileOpener const *fo, GOIOContext *io_cont
                        err = gsf_doc_meta_data_read_from_odf (meta_data, meta_file);
                        if (NULL != err) {
                                go_io_warning (io_context,
-                                       _("Invalid metadata '%s'"), err->message);
+                                              _("Invalid metadata '%s'"), err->message);
                                g_error_free (err);
                        } else
                                go_doc_set_meta_data (GO_DOC (state.pos.wb), meta_data);
@@ -12027,58 +12036,60 @@ openoffice_file_open (G_GNUC_UNUSED GOFileOpener const *fo, GOIOContext *io_cont
                                   ? ooo1_content_dtd
                                   : opendoc_content_dtd,
                                   gsf_odf_get_ns ());
-       if (gsf_xml_in_doc_parse (doc, contents, &state)) {
-               GsfInput *settings;
-               char const *filesaver;
-
-               /* get the sheet in the right order (in case something was
-                * created out of order implictly) */
-               state.sheet_order = g_slist_reverse (state.sheet_order);
-
-               if (g_slist_length (state.sheet_order) < (guint) workbook_sheet_count (state.pos.wb)) {
-                       /* We have seen instances of ODF files generated by   */
-                       /* Libreoffice referring internally to table included */
-                       /* inside charts. Those tables defacto don't exist    */
-                       /* but we have to assume their existence to resolve   */
-                       /* the references. We need to delete tehm now. See    */
-                       /* https://bugzilla.gnome.org/show_bug.cgi?id=698388  */
-                       GSList *to_be_deleted = NULL;
-                       GSList *l;
+       content_malformed = !gsf_xml_in_doc_parse (doc, contents, &state);
+
+       /* get the sheet in the right order (in case something was
+        * created out of order implictly) */
+       state.sheet_order = g_slist_reverse (state.sheet_order);
+
+       if (g_slist_length (state.sheet_order) < (guint) workbook_sheet_count (state.pos.wb)) {
+               /* We have seen instances of ODF files generated by   */
+               /* Libreoffice referring internally to table included */
+               /* inside charts. Those tables defacto don't exist    */
+               /* but we have to assume their existence to resolve   */
+               /* the references. We need to delete them now. See    */
+               /* https://bugzilla.gnome.org/show_bug.cgi?id=698388  */
+               GSList *to_be_deleted = NULL;
+               GSList *l;
 
-                       WORKBOOK_FOREACH_SHEET
-                               (state.pos.wb, sheet,
-                                {
-                                        if (NULL == g_slist_find (state.sheet_order, sheet))
-                                                to_be_deleted = g_slist_prepend (to_be_deleted, sheet);      
   
-                                });
-                       l = to_be_deleted;
-                       while (l) {
-                               workbook_sheet_delete (l->data);
-                               l = l->next;
-                       }
-                       g_slist_free (to_be_deleted);
+               WORKBOOK_FOREACH_SHEET
+                       (state.pos.wb, sheet,
+                        {
+                                if (NULL == g_slist_find (state.sheet_order, sheet))
+                                        to_be_deleted = g_slist_prepend (to_be_deleted, sheet);         
+                        });
+               l = to_be_deleted;
+               while (l) {
+                       workbook_sheet_delete (l->data);
+                       l = l->next;
                }
+               g_slist_free (to_be_deleted);
+       }
 
-               if (state.debug) {
-                       GSList *l, *sheets;
-                       g_printerr ("Order we desire:\n");
-                       for (l = state.sheet_order; l; l = l->next) {
-                               Sheet *sheet = l->data;
-                               g_printerr ("Sheet %s\n", sheet->name_unquoted);
-                       }
-                       g_printerr ("Order we have:\n");
-                       sheets = workbook_sheets (state.pos.wb);
-                       for (l = sheets; l; l = l->next) {
-                               Sheet *sheet = l->data;
-                               g_printerr ("Sheet %s\n", sheet->name_unquoted);
-                       }
-                       g_slist_free (sheets);
+       if (state.debug) {
+               GSList *l, *sheets;
+               g_printerr ("Order we desire:\n");
+               for (l = state.sheet_order; l; l = l->next) {
+                       Sheet *sheet = l->data;
+                       g_printerr ("Sheet %s\n", sheet->name_unquoted);
+               }
+               g_printerr ("Order we have:\n");
+               sheets = workbook_sheets (state.pos.wb);
+               for (l = sheets; l; l = l->next) {
+                       Sheet *sheet = l->data;
+                       g_printerr ("Sheet %s\n", sheet->name_unquoted);
                }
+               g_slist_free (sheets);
+       }
+
+       workbook_sheet_reorder (state.pos.wb, state.sheet_order);
+       g_slist_free (state.sheet_order);
 
-               workbook_sheet_reorder (state.pos.wb, state.sheet_order);
-               g_slist_free (state.sheet_order);
+       odf_fix_expr_names (&state);
 
-               odf_fix_expr_names (&state);
+       if (!content_malformed) {
+               GsfInput *settings;
+               char const *filesaver;
 
                /* look for the view settings */
                state.settings.settings
@@ -12122,8 +12133,8 @@ openoffice_file_open (G_GNUC_UNUSED GOFileOpener const *fo, GOIOContext *io_cont
 
                g_hash_table_destroy (state.settings.settings);
                state.settings.settings = NULL;
-       } else
-               go_io_error_string (io_context, _("XML document not well formed!"));
+       }
+
        gsf_xml_in_doc_free (doc);
        odf_clear_conventions (&state);
 
@@ -12163,9 +12174,10 @@ openoffice_file_open (G_GNUC_UNUSED GOFileOpener const *fo, GOIOContext *io_cont
        g_free (state.chart.cs_modifiers);
        g_free (state.chart.cs_viewbox);
        g_free (state.chart.cs_type);
+       if (state.chart_list)
+               g_slist_free_full (state.chart_list, odf_destroy_object_offset);
        if (state.chart.cs_variables)
                g_hash_table_destroy (state.chart.cs_variables);
-
        g_slist_free_full (state.text_p_for_cell.span_style_stack, g_free);
        if (state.text_p_for_cell.gstr)
                g_string_free (state.text_p_for_cell.gstr, TRUE);
@@ -12174,6 +12186,9 @@ openoffice_file_open (G_GNUC_UNUSED GOFileOpener const *fo, GOIOContext *io_cont
 
        g_object_unref (zip);
 
+       if (content_malformed) 
+               go_io_error_string (io_context, _("XML document not well formed!"));    
+
        i = workbook_sheet_count (state.pos.wb);
        while (i-- > 0)
                sheet_flag_recompute_spans (workbook_sheet_by_index (state.pos.wb, i));


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]