You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ni...@apache.org on 2008/11/12 19:25:37 UTC

svn commit: r713447 - in /poi/trunk/src: documentation/content/xdocs/ java/org/apache/poi/poifs/eventfilesystem/ java/org/apache/poi/poifs/filesystem/ java/org/apache/poi/poifs/property/ java/org/apache/poi/poifs/storage/ testcases/org/apache/poi/hssf/...

Author: nick
Date: Wed Nov 12 10:25:33 2008
New Revision: 713447

URL: http://svn.apache.org/viewvc?rev=713447&view=rev
Log:
Fix bug #45290 - Support odd files where the POIFS header block comes after the data blocks, and is on the data blocks list

Added:
    poi/trunk/src/testcases/org/apache/poi/hssf/data/45290.xls   (with props)
Modified:
    poi/trunk/src/documentation/content/xdocs/changes.xml
    poi/trunk/src/documentation/content/xdocs/status.xml
    poi/trunk/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java
    poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java
    poi/trunk/src/java/org/apache/poi/poifs/property/PropertyTable.java
    poi/trunk/src/java/org/apache/poi/poifs/storage/BlockAllocationTableReader.java
    poi/trunk/src/java/org/apache/poi/poifs/storage/BlockList.java
    poi/trunk/src/java/org/apache/poi/poifs/storage/BlockListImpl.java
    poi/trunk/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java
    poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java
    poi/trunk/src/testcases/org/apache/poi/poifs/storage/TestBlockAllocationTableReader.java
    poi/trunk/src/testcases/org/apache/poi/poifs/storage/TestBlockListImpl.java

Modified: poi/trunk/src/documentation/content/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/changes.xml?rev=713447&r1=713446&r2=713447&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/changes.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/changes.xml Wed Nov 12 10:25:33 2008
@@ -37,6 +37,7 @@
 
 		<!-- Don't forget to update status.xml too! -->
         <release version="3.5-beta4" date="2008-??-??">
+           <action dev="POI-DEVELOPERS" type="fix">45290 - Support odd files where the POIFS header block comes after the data blocks, and is on the data blocks list</header>
            <action dev="POI-DEVELOPERS" type="fix">46184 - More odd escaped date formats</action>
            <action dev="POI-DEVELOPERS" type="add">Include the sheet number in the output of XLS2CSVmra</action>
            <action dev="POI-DEVELOPERS" type="fix">46043 - correctly write out HPSF properties with HWPF</action>

Modified: poi/trunk/src/documentation/content/xdocs/status.xml
URL: http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/status.xml?rev=713447&r1=713446&r2=713447&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/status.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/status.xml Wed Nov 12 10:25:33 2008
@@ -34,6 +34,7 @@
 	<!-- Don't forget to update changes.xml too! -->
     <changes>
         <release version="3.5-beta4" date="2008-??-??">
+           <action dev="POI-DEVELOPERS" type="fix">45290 - Support odd files where the POIFS header block comes after the data blocks, and is on the data blocks list</header>
            <action dev="POI-DEVELOPERS" type="fix">46184 - More odd escaped date formats</action>
            <action dev="POI-DEVELOPERS" type="add">Include the sheet number in the output of XLS2CSVmra</action>
            <action dev="POI-DEVELOPERS" type="fix">46043 - correctly write out HPSF properties with HWPF</action>

Modified: poi/trunk/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java?rev=713447&r1=713446&r2=713447&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java Wed Nov 12 10:25:33 2008
@@ -245,13 +245,13 @@
                     {
                         document =
                             new POIFSDocument(name, small_blocks
-                                .fetchBlocks(startBlock), size);
+                                .fetchBlocks(startBlock, -1), size);
                     }
                     else
                     {
                         document =
                             new POIFSDocument(name, big_blocks
-                                .fetchBlocks(startBlock), size);
+                                .fetchBlocks(startBlock, -1), size);
                     }
                     while (listeners.hasNext())
                     {
@@ -270,11 +270,11 @@
                     // consume the document's data and discard it
                     if (property.shouldUseSmallBlocks())
                     {
-                        small_blocks.fetchBlocks(startBlock);
+                        small_blocks.fetchBlocks(startBlock, -1);
                     }
                     else
                     {
-                        big_blocks.fetchBlocks(startBlock);
+                        big_blocks.fetchBlocks(startBlock, -1);
                     }
                 }
             }

Modified: poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java?rev=713447&r1=713446&r2=713447&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java Wed Nov 12 10:25:33 2008
@@ -173,11 +173,16 @@
                               data_blocks);
 
         // init documents
-        processProperties(SmallBlockTableReader
-            .getSmallDocumentBlocks(data_blocks, properties
-                .getRoot(), header_block_reader
-                    .getSBATStart()), data_blocks, properties.getRoot()
-                        .getChildren(), null);
+        processProperties(
+        		SmallBlockTableReader.getSmallDocumentBlocks(
+        				data_blocks, properties.getRoot(), 
+        				header_block_reader.getSBATStart()
+        		), 
+        		data_blocks, 
+        		properties.getRoot().getChildren(), 
+        		null,
+        		header_block_reader.getPropertyStart()
+        );
     }
     /**
      * @param stream the stream to be closed
@@ -491,7 +496,8 @@
     private void processProperties(final BlockList small_blocks,
                                    final BlockList big_blocks,
                                    final Iterator properties,
-                                   final DirectoryNode dir)
+                                   final DirectoryNode dir,
+                                   final int headerPropertiesStartAt)
         throws IOException
     {
         while (properties.hasNext())
@@ -511,7 +517,8 @@
 
                 processProperties(
                     small_blocks, big_blocks,
-                    (( DirectoryProperty ) property).getChildren(), new_dir);
+                    (( DirectoryProperty ) property).getChildren(), 
+                    new_dir, headerPropertiesStartAt);
             }
             else
             {
@@ -522,14 +529,15 @@
                 if (property.shouldUseSmallBlocks())
                 {
                     document =
-                        new POIFSDocument(name, small_blocks
-                            .fetchBlocks(startBlock), size);
+                        new POIFSDocument(name, 
+                                          small_blocks.fetchBlocks(startBlock, headerPropertiesStartAt), 
+                                          size);
                 }
                 else
                 {
                     document =
                         new POIFSDocument(name,
-                                          big_blocks.fetchBlocks(startBlock),
+                                          big_blocks.fetchBlocks(startBlock, headerPropertiesStartAt),
                                           size);
                 }
                 parent.createDocument(document);

Modified: poi/trunk/src/java/org/apache/poi/poifs/property/PropertyTable.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/property/PropertyTable.java?rev=713447&r1=713446&r2=713447&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/property/PropertyTable.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/property/PropertyTable.java Wed Nov 12 10:25:33 2008
@@ -78,7 +78,7 @@
         _blocks      = null;
         _properties  =
             PropertyFactory
-                .convertToProperties(blockList.fetchBlocks(startBlock));
+                .convertToProperties(blockList.fetchBlocks(startBlock, -1));
         populatePropertyTree(( DirectoryProperty ) _properties.get(0));
     }
 

Modified: poi/trunk/src/java/org/apache/poi/poifs/storage/BlockAllocationTableReader.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/storage/BlockAllocationTableReader.java?rev=713447&r1=713446&r2=713447&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/storage/BlockAllocationTableReader.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/storage/BlockAllocationTableReader.java Wed Nov 12 10:25:33 2008
@@ -179,17 +179,34 @@
      */
 
     ListManagedBlock [] fetchBlocks(final int startBlock,
+                                    final int headerPropertiesStartBlock,
                                     final BlockList blockList)
         throws IOException
     {
         List blocks       = new ArrayList();
         int  currentBlock = startBlock;
-
-        while (currentBlock != POIFSConstants.END_OF_CHAIN)
-        {
-            blocks.add(blockList.remove(currentBlock));
-            currentBlock = _entries.get(currentBlock);
+        boolean firstPass = true;
+        
+        // Process the chain from the start to the end
+        // Normally we have header, data, end
+        // Sometimes we have data, header, end
+        // For those cases, stop at the header, not the end
+        while (currentBlock != POIFSConstants.END_OF_CHAIN) {
+        	try {
+        		blocks.add(blockList.remove(currentBlock));
+                currentBlock = _entries.get(currentBlock);
+        	} catch(IOException e) {
+        		if(currentBlock == headerPropertiesStartBlock) {
+        			// Special case where things are in the wrong order
+        			System.err.println("Warning, header block comes after data blocks in POIFS block listing");
+        			currentBlock = POIFSConstants.END_OF_CHAIN;
+        		} else {
+        			// Ripple up
+        			throw e;
+        		}
+        	}
         }
+        
         return ( ListManagedBlock [] ) blocks
             .toArray(new ListManagedBlock[ 0 ]);
     }

Modified: poi/trunk/src/java/org/apache/poi/poifs/storage/BlockList.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/storage/BlockList.java?rev=713447&r1=713446&r2=713447&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/storage/BlockList.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/storage/BlockList.java Wed Nov 12 10:25:33 2008
@@ -59,13 +59,14 @@
      * blocks are removed from the list.
      *
      * @param startBlock the index of the first block in the stream
+     * @param headerPropertiesStartBlock the index of the first header block in the stream
      *
      * @return the stream as an array of correctly ordered blocks
      *
      * @exception IOException if blocks are missing
      */
 
-    public ListManagedBlock [] fetchBlocks(final int startBlock)
+    public ListManagedBlock [] fetchBlocks(final int startBlock, final int headerPropertiesStartBlock)
         throws IOException;
 
     /**

Modified: poi/trunk/src/java/org/apache/poi/poifs/storage/BlockListImpl.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/storage/BlockListImpl.java?rev=713447&r1=713446&r2=713447&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/storage/BlockListImpl.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/storage/BlockListImpl.java Wed Nov 12 10:25:33 2008
@@ -94,8 +94,10 @@
             result = _blocks[ index ];
             if (result == null)
             {
-                throw new IOException("block[ " + index
-                                      + " ] already removed");
+                throw new IOException(
+                		"block[ " + index + " ] already removed - " +
+                		"does your POIFS have circular or duplicate block references?"
+                );
             }
             _blocks[ index ] = null;
         }
@@ -119,7 +121,7 @@
      * @exception IOException if blocks are missing
      */
 
-    public ListManagedBlock [] fetchBlocks(final int startBlock)
+    public ListManagedBlock [] fetchBlocks(final int startBlock, final int headerPropertiesStartBlock)
         throws IOException
     {
         if (_bat == null)
@@ -127,7 +129,7 @@
             throw new IOException(
                 "Improperly initialized list: no block allocation table provided");
         }
-        return _bat.fetchBlocks(startBlock, this);
+        return _bat.fetchBlocks(startBlock, headerPropertiesStartBlock, this);
     }
 
     /**

Modified: poi/trunk/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java?rev=713447&r1=713446&r2=713447&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java Wed Nov 12 10:25:33 2008
@@ -56,9 +56,9 @@
     {
         BlockList list =
             new SmallDocumentBlockList(SmallDocumentBlock
-                .extract(blockList.fetchBlocks(root.getStartBlock())));
+                .extract(blockList.fetchBlocks(root.getStartBlock(), -1)));
 
-        new BlockAllocationTableReader(blockList.fetchBlocks(sbatStart),
+        new BlockAllocationTableReader(blockList.fetchBlocks(sbatStart, -1),
                                        list);
         return list;
     }

Added: poi/trunk/src/testcases/org/apache/poi/hssf/data/45290.xls
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/data/45290.xls?rev=713447&view=auto
==============================================================================
Binary file - no diff available.

Propchange: poi/trunk/src/testcases/org/apache/poi/hssf/data/45290.xls
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java?rev=713447&r1=713446&r2=713447&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java Wed Nov 12 10:25:33 2008
@@ -27,9 +27,6 @@
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 
-import org.apache.poi.ss.util.Region;
-import org.apache.poi.ss.util.CellRangeAddress;
-
 import org.apache.poi.hssf.HSSFTestDataSamples;
 import org.apache.poi.hssf.model.Workbook;
 import org.apache.poi.hssf.record.CellValueRecordInterface;
@@ -38,6 +35,7 @@
 import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
 import org.apache.poi.hssf.record.formula.DeletedArea3DPtg;
 import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.util.TempFile;
 
 /**
@@ -1533,4 +1531,13 @@
         assertEquals(7, wb.getNumberOfSheets());
         wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
     }
+    
+    /**
+     * Odd POIFS blocks issue:
+     * block[ 44 ] already removed from org.apache.poi.poifs.storage.BlockListImpl.remove
+     */
+    public void test45290() {
+        HSSFWorkbook wb = openSample("45290.xls");
+        assertEquals(1, wb.getNumberOfSheets());
+    }
 }

Modified: poi/trunk/src/testcases/org/apache/poi/poifs/storage/TestBlockAllocationTableReader.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/poifs/storage/TestBlockAllocationTableReader.java?rev=713447&r1=713446&r2=713447&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/poifs/storage/TestBlockAllocationTableReader.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/poifs/storage/TestBlockAllocationTableReader.java Wed Nov 12 10:25:33 2008
@@ -1325,7 +1325,7 @@
             try
             {
                 ListManagedBlock[] dataBlocks =
-                    table.fetchBlocks(start_blocks[ j ], list);
+                    table.fetchBlocks(start_blocks[ j ], -1, list);
 
                 if (expected_length[ j ] == -1)
                 {

Modified: poi/trunk/src/testcases/org/apache/poi/poifs/storage/TestBlockListImpl.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/poifs/storage/TestBlockListImpl.java?rev=713447&r1=713446&r2=713447&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/poifs/storage/TestBlockListImpl.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/poifs/storage/TestBlockListImpl.java Wed Nov 12 10:25:33 2008
@@ -285,7 +285,7 @@
             try
             {
                 ListManagedBlock[] dataBlocks =
-                    list.fetchBlocks(start_blocks[ j ]);
+                    list.fetchBlocks(start_blocks[ j ], -1);
 
                 if (expected_length[ j ] == -1)
                 {



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org