[libgsf] ole: fix problem with error handling when writing.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgsf] ole: fix problem with error handling when writing.
- Date: Wed, 11 May 2022 22:02:11 +0000 (UTC)
commit ba3cee59b33f46c0512f675d5f876793be9c1467
Author: Morten Welinder <terra gnome org>
Date: Wed May 11 18:01:12 2022 -0400
ole: fix problem with error handling when writing.
Things could get into a really bad state and cause a loop.
NEWS | 3 +++
gsf/gsf-outfile-msole.c | 65 +++++++++++++++++++++++++++++++++----------------
2 files changed, 47 insertions(+), 21 deletions(-)
---
diff --git a/NEWS b/NEWS
index 82afb07a..cb831484 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,8 @@
libgsf 1.14.50
+Morten:
+ * Fix error handling problem when writing ole files. [#27]
+
--------------------------------------------------------------------------
libgsf 1.14.49
diff --git a/gsf/gsf-outfile-msole.c b/gsf/gsf-outfile-msole.c
index 6490e740..266151dc 100644
--- a/gsf/gsf-outfile-msole.c
+++ b/gsf/gsf-outfile-msole.c
@@ -300,9 +300,9 @@ ole_pad_bat_unused (GsfOutfileMSOle *ole, unsigned residual)
(ole_bytes_left_in_block (ole) / BAT_INDEX_SIZE) - residual);
}
-/* write the metadata (dirents, small block, xbats) and close the sink */
+/* write the metadata (dirents, small block, xbats) */
static gboolean
-gsf_outfile_msole_close_root (GsfOutfileMSOle *ole)
+gsf_outfile_msole_write_directory (GsfOutfileMSOle *ole)
{
GsfOutfile *tmp;
guint8 buf [OLE_HEADER_SIZE];
@@ -454,22 +454,29 @@ gsf_outfile_msole_close_root (GsfOutfileMSOle *ole)
*/
num_bat = 0;
num_xbat = 0;
-recalc_bat_bat :
- i = ((ole->sink->cur_size
- + BAT_INDEX_SIZE * (num_bat + num_xbat)
- - OLE_HEADER_SIZE - 1) >> ole->bb.shift) + 1;
- i -= bat_start;
- if (num_bat != i) {
- num_bat = i;
- goto recalc_bat_bat;
- }
- i = 0;
- if (num_bat > OLE_HEADER_METABAT_SIZE)
- i = 1 + ((num_bat - OLE_HEADER_METABAT_SIZE - 1)
- / metabat_size);
- if (num_xbat != i) {
- num_xbat = i;
- goto recalc_bat_bat;
+ while (gsf_output_error (ole->sink) == NULL) {
+ // If we have an error, then the actual size as reported
+ // by _tell and ->cur_size may be out of sync. We don't
+ // want to loop forever here.
+
+ unsigned i = ((ole->sink->cur_size
+ + BAT_INDEX_SIZE * (num_bat + num_xbat)
+ - OLE_HEADER_SIZE - 1) >> ole->bb.shift) + 1;
+ i -= bat_start;
+ if (num_bat != i) {
+ num_bat = i;
+ continue;
+ }
+ i = 0;
+ if (num_bat > OLE_HEADER_METABAT_SIZE)
+ i = 1 + ((num_bat - OLE_HEADER_METABAT_SIZE - 1)
+ / metabat_size);
+ if (num_xbat != i) {
+ num_xbat = i;
+ continue;
+ }
+
+ break;
}
ole_write_const (ole->sink, BAT_MAGIC_BAT, num_bat);
@@ -541,16 +548,32 @@ recalc_bat_bat :
g_ptr_array_free (elem, TRUE);
ole->content.dir.root_order = NULL;
- return gsf_output_close (ole->sink);
+ return TRUE;
}
+static void
+gsf_outfile_msole_hoist_error (GsfOutfileMSOle *ole)
+{
+ GsfOutput *oole = GSF_OUTPUT (ole);
+ if (gsf_output_error (oole) == NULL &&
+ gsf_output_error (ole->sink)) {
+ oole->err = g_error_copy (ole->sink->err);
+ }
+}
+
+
static gboolean
gsf_outfile_msole_close (GsfOutput *output)
{
GsfOutfileMSOle *ole = (GsfOutfileMSOle *)output;
- if (gsf_output_container (output) == NULL) /* The root dir */
- return gsf_outfile_msole_close_root (ole);
+ if (gsf_output_container (output) == NULL) { /* The root dir */
+ gboolean ok = gsf_outfile_msole_write_directory (ole);
+ gsf_outfile_msole_hoist_error (ole);
+ if (!gsf_output_close (ole->sink))
+ ok = FALSE;
+ return ok;
+ }
if (ole->type == MSOLE_BIG_BLOCK) {
gsf_outfile_msole_seek (output, 0, G_SEEK_END);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]