libgsf r957 - in trunk: . gsf



Author: mortenw
Date: Fri Feb  8 00:17:29 2008
New Revision: 957
URL: http://svn.gnome.org/viewvc/libgsf?rev=957&view=rev

Log:
2008-02-07  Morten Welinder  <terra gnome org>

	* gsf/gsf-infile-msole.c (ole_dirent_new): Add new argument to
	keep track of what entries we have seen before.  All callers
	changed.  Check for loops.  Fixes #513831.



Modified:
   trunk/ChangeLog
   trunk/NEWS
   trunk/gsf/gsf-infile-msole.c

Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS	(original)
+++ trunk/NEWS	Fri Feb  8 00:17:29 2008
@@ -8,7 +8,8 @@
 Morten:
 	* Fix criticals for corrupted file.  [#485964]
 	* Improve sanity checks of ole properties.  [#404934]
-	* Enhance gsf (the program) to list all msole properites.
+	* Enhance gsf (the program) to list all document properites.
+	* Fix endless loop with broken ole files.  [#513831]
 
 --------------------------------------------------------------------------
 libgsf 1.14.7

Modified: trunk/gsf/gsf-infile-msole.c
==============================================================================
--- trunk/gsf/gsf-infile-msole.c	(original)
+++ trunk/gsf/gsf-infile-msole.c	Fri Feb  8 00:17:29 2008
@@ -297,7 +297,8 @@
  * Returns: The dirent
  **/
 static MSOleDirent *
-ole_dirent_new (GsfInfileMSOle *ole, guint32 entry, MSOleDirent *parent)
+ole_dirent_new (GsfInfileMSOle *ole, guint32 entry, MSOleDirent *parent,
+		guint8 *seen_before)
 {
 	MSOleDirent *dirent;
 	guint32 block, next, prev, child, size;
@@ -311,6 +312,10 @@
 	block = OLE_BIG_BLOCK (entry * DIRENT_SIZE, ole);
 
 	g_return_val_if_fail (block < ole->bat.num_blocks, NULL);
+
+	g_return_val_if_fail (!seen_before[entry], NULL);
+	seen_before[entry] = TRUE;
+
 	data = ole_get_block (ole, ole->bat.block [block], NULL);
 	if (data == NULL)
 		return NULL;
@@ -386,17 +391,11 @@
 			dirent, (GCompareFunc)ole_dirent_cmp);
 
 	/* NOTE : These links are a tree, not a linked list */
-	if (prev == entry) {
-		g_warning ("Invalid OLE file with a cycle in its directory tree");
-	} else
-		ole_dirent_new (ole, prev, parent); 
-	if (next == entry) {
-		g_warning ("Invalid OLE file with a cycle in its directory tree");
-	} else
-		ole_dirent_new (ole, next, parent); 
+	ole_dirent_new (ole, prev, parent, seen_before); 
+	ole_dirent_new (ole, next, parent, seen_before); 
 
 	if (dirent->is_directory)
-		ole_dirent_new (ole, child, dirent);
+		ole_dirent_new (ole, child, dirent, seen_before);
 	else if (child != DIRENT_MAGIC_END)
 		g_warning ("A non directory stream with children ?");
 
@@ -496,6 +495,7 @@
 {
 	static guint8 const signature[] =
 		{ 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1 };
+	guint8 *seen_before;
 	guint8 const *header, *tmp;
 	guint32 *metabat = NULL;
 	MSOleInfo *info;
@@ -637,7 +637,10 @@
 	}
 
 	/* Read the directory */
-	ole->dirent = info->root_dir = ole_dirent_new (ole, 0, NULL);
+	seen_before = g_malloc0 ((ole->bat.num_blocks << info->bb.shift) * DIRENT_SIZE + 1);
+	ole->dirent = info->root_dir =
+		ole_dirent_new (ole, 0, NULL, seen_before);
+	g_free (seen_before);
 	if (ole->dirent == NULL) {
 		if (err != NULL)
 			*err = g_error_new (gsf_input_error_id (), 0,



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