aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/poi
diff options
context:
space:
mode:
authorNick Burch <nick@apache.org>2008-11-12 18:25:33 +0000
committerNick Burch <nick@apache.org>2008-11-12 18:25:33 +0000
commit1b24850c7cd4251a35ad39a41195da134b194416 (patch)
treeaa0e32123465a3d731d7994af58f1ab138123d98 /src/java/org/apache/poi
parent84d10b7ecd5956e5deaa1e9a10903c2921f97f46 (diff)
downloadpoi-1b24850c7cd4251a35ad39a41195da134b194416.tar.gz
poi-1b24850c7cd4251a35ad39a41195da134b194416.zip
Fix bug #45290 - Support odd files where the POIFS header block comes after the data blocks, and is on the data blocks list
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@713447 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/poi')
-rw-r--r--src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java8
-rw-r--r--src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java28
-rw-r--r--src/java/org/apache/poi/poifs/property/PropertyTable.java2
-rw-r--r--src/java/org/apache/poi/poifs/storage/BlockAllocationTableReader.java27
-rw-r--r--src/java/org/apache/poi/poifs/storage/BlockList.java3
-rw-r--r--src/java/org/apache/poi/poifs/storage/BlockListImpl.java10
-rw-r--r--src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java4
7 files changed, 55 insertions, 27 deletions
diff --git a/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java b/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java
index 73911e6b0e..6a1423ea48 100644
--- a/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java
+++ b/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java
@@ -245,13 +245,13 @@ public class POIFSReader
{
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 @@ public class POIFSReader
// 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);
}
}
}
diff --git a/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java b/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java
index 92348ceaff..6ea37ea387 100644
--- a/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java
+++ b/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java
@@ -173,11 +173,16 @@ public class POIFSFileSystem
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 @@ public class POIFSFileSystem
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 @@ public class POIFSFileSystem
processProperties(
small_blocks, big_blocks,
- (( DirectoryProperty ) property).getChildren(), new_dir);
+ (( DirectoryProperty ) property).getChildren(),
+ new_dir, headerPropertiesStartAt);
}
else
{
@@ -522,14 +529,15 @@ public class POIFSFileSystem
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);
diff --git a/src/java/org/apache/poi/poifs/property/PropertyTable.java b/src/java/org/apache/poi/poifs/property/PropertyTable.java
index 11c56e886d..00b306b792 100644
--- a/src/java/org/apache/poi/poifs/property/PropertyTable.java
+++ b/src/java/org/apache/poi/poifs/property/PropertyTable.java
@@ -78,7 +78,7 @@ public class PropertyTable
_blocks = null;
_properties =
PropertyFactory
- .convertToProperties(blockList.fetchBlocks(startBlock));
+ .convertToProperties(blockList.fetchBlocks(startBlock, -1));
populatePropertyTree(( DirectoryProperty ) _properties.get(0));
}
diff --git a/src/java/org/apache/poi/poifs/storage/BlockAllocationTableReader.java b/src/java/org/apache/poi/poifs/storage/BlockAllocationTableReader.java
index b167d2fca1..1016db9c46 100644
--- a/src/java/org/apache/poi/poifs/storage/BlockAllocationTableReader.java
+++ b/src/java/org/apache/poi/poifs/storage/BlockAllocationTableReader.java
@@ -179,17 +179,34 @@ public class BlockAllocationTableReader
*/
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 ]);
}
diff --git a/src/java/org/apache/poi/poifs/storage/BlockList.java b/src/java/org/apache/poi/poifs/storage/BlockList.java
index 2352d3a2c1..a5eb7df217 100644
--- a/src/java/org/apache/poi/poifs/storage/BlockList.java
+++ b/src/java/org/apache/poi/poifs/storage/BlockList.java
@@ -59,13 +59,14 @@ public interface BlockList
* 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;
/**
diff --git a/src/java/org/apache/poi/poifs/storage/BlockListImpl.java b/src/java/org/apache/poi/poifs/storage/BlockListImpl.java
index 7e44fda3f3..f315b5d515 100644
--- a/src/java/org/apache/poi/poifs/storage/BlockListImpl.java
+++ b/src/java/org/apache/poi/poifs/storage/BlockListImpl.java
@@ -94,8 +94,10 @@ class BlockListImpl
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 @@ class BlockListImpl
* @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 @@ class BlockListImpl
throw new IOException(
"Improperly initialized list: no block allocation table provided");
}
- return _bat.fetchBlocks(startBlock, this);
+ return _bat.fetchBlocks(startBlock, headerPropertiesStartBlock, this);
}
/**
diff --git a/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java b/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java
index e70774aa16..4da79e71f1 100644
--- a/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java
+++ b/src/java/org/apache/poi/poifs/storage/SmallBlockTableReader.java
@@ -56,9 +56,9 @@ public class SmallBlockTableReader
{
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;
}