diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 1d561f8097..d9eb624850 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 49139 - Properly support 4k big block size in POIFS 48936 - Avoid writing malformed CDATA blocks in sharedStrings.xml 49026 - Added implementation for TEXT() 49025 - Added implementation for TRUNC() diff --git a/src/java/org/apache/poi/poifs/common/POIFSBigBlockSize.java b/src/java/org/apache/poi/poifs/common/POIFSBigBlockSize.java index 19b345d716..1e8b1b113a 100644 --- a/src/java/org/apache/poi/poifs/common/POIFSBigBlockSize.java +++ b/src/java/org/apache/poi/poifs/common/POIFSBigBlockSize.java @@ -38,6 +38,12 @@ public final class POIFSBigBlockSize return bigBlockSize; } + /** + * Returns the value that gets written into the + * header. + * Is the power of two that corresponds to the + * size of the block, eg 512 => 9 + */ public short getHeaderValue() { return headerValue; } diff --git a/src/java/org/apache/poi/poifs/dev/POIFSHeaderDumper.java b/src/java/org/apache/poi/poifs/dev/POIFSHeaderDumper.java index 1967daec43..75f69caebf 100644 --- a/src/java/org/apache/poi/poifs/dev/POIFSHeaderDumper.java +++ b/src/java/org/apache/poi/poifs/dev/POIFSHeaderDumper.java @@ -149,6 +149,8 @@ public class POIFSHeaderDumper { bnS = "DI Fat Block"; } else if(bn == POIFSConstants.FAT_SECTOR_BLOCK) { bnS = "Normal Fat Block"; + } else if(bn == POIFSConstants.UNUSED_BLOCK) { + bnS = "Block Not Used (Free)"; } System.out.println(" Block # " + i + " -> " + bnS); diff --git a/src/java/org/apache/poi/poifs/storage/DocumentBlock.java b/src/java/org/apache/poi/poifs/storage/DocumentBlock.java index 3f84fa6e61..a7c5686257 100644 --- a/src/java/org/apache/poi/poifs/storage/DocumentBlock.java +++ b/src/java/org/apache/poi/poifs/storage/DocumentBlock.java @@ -32,10 +32,6 @@ import org.apache.poi.util.IOUtils; * @author Marc Johnson (mjohnson at apache dot org) */ public final class DocumentBlock extends BigBlock { - private static final int BLOCK_SHIFT = 9; - private static final int BLOCK_SIZE = 1 << BLOCK_SHIFT; - private static final int BLOCK_MASK = BLOCK_SIZE-1; - private static final byte _default_value = ( byte ) 0xFF; private byte[] _data; private int _bytes_read; @@ -165,6 +161,17 @@ public final class DocumentBlock extends BigBlock { } public static DataInputBlock getDataInputBlock(DocumentBlock[] blocks, int offset) { + if(blocks == null || blocks.length == 0) { + return null; + } + + // Key things about the size of the block + POIFSBigBlockSize bigBlockSize = blocks[0].bigBlockSize; + int BLOCK_SHIFT = bigBlockSize.getHeaderValue(); + int BLOCK_SIZE = bigBlockSize.getBigBlockSize(); + int BLOCK_MASK = BLOCK_SIZE - 1; + + // Now do the offset lookup int firstBlockIndex = offset >> BLOCK_SHIFT; int firstBlockOffset= offset & BLOCK_MASK; return new DataInputBlock(blocks[firstBlockIndex]._data, firstBlockOffset); diff --git a/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSFileSystem.java b/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSFileSystem.java index 1b370124f6..5ebc168941 100644 --- a/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSFileSystem.java +++ b/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSFileSystem.java @@ -177,9 +177,8 @@ public final class TestPOIFSFileSystem extends TestCase { /** * Most OLE2 files use 512byte blocks. However, a small number * use 4k blocks. Check that we can open these. - * DISABLED until we fix the bug with DocumentBlocks on 4k sizes */ - public void DISABLEDtest4KBlocks() throws Exception { + public void test4KBlocks() throws Exception { POIDataSamples _samples = POIDataSamples.getPOIFSInstance(); InputStream inp = _samples.openResourceAsStream("BlockSize4096.zvi"); @@ -219,7 +218,8 @@ public final class TestPOIFSFileSystem extends TestCase { if(entry instanceof DirectoryEntry) { checkAllDirectoryContents((DirectoryEntry)entry); } else { - DocumentInputStream dis = new DocumentInputStream((DocumentNode) entry); + DocumentNode doc = (DocumentNode) entry; + DocumentInputStream dis = new DocumentInputStream(doc); int numBytes = dis.available(); byte[] data = new byte [numBytes]; dis.read(data);