diff options
author | PJ Fanning <fanningpj@apache.org> | 2020-06-10 17:30:28 +0000 |
---|---|---|
committer | PJ Fanning <fanningpj@apache.org> | 2020-06-10 17:30:28 +0000 |
commit | 0181d2abd90142edc4572ca3acdc88cefeb6a3a4 (patch) | |
tree | 12d49105122eb36e49fd9966f95c99444b02f068 /src/testcases/org/apache/poi | |
parent | ff67cdf1166a05d6d4a81096a77116da49629c19 (diff) | |
download | poi-0181d2abd90142edc4572ca3acdc88cefeb6a3a4.tar.gz poi-0181d2abd90142edc4572ca3acdc88cefeb6a3a4.zip |
[github-182] Fix root property size calculation. Thanks to netmackan. This closes #182
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1878721 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/testcases/org/apache/poi')
-rw-r--r-- | src/testcases/org/apache/poi/poifs/storage/TestBATBlock.java | 433 |
1 files changed, 247 insertions, 186 deletions
diff --git a/src/testcases/org/apache/poi/poifs/storage/TestBATBlock.java b/src/testcases/org/apache/poi/poifs/storage/TestBATBlock.java index 72afb0346b..10689b2e21 100644 --- a/src/testcases/org/apache/poi/poifs/storage/TestBATBlock.java +++ b/src/testcases/org/apache/poi/poifs/storage/TestBATBlock.java @@ -37,7 +37,7 @@ public final class TestBATBlock { @Test public void testEntriesPerBlock() { - assertEquals(128, POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS.getBATEntriesPerBlock()); + assertEquals(128, POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS.getBATEntriesPerBlock()); } @Test @@ -52,81 +52,81 @@ public final class TestBATBlock { @Test public void testCalculateMaximumSize() { - // Zero fat blocks isn't technically valid, but it'd be header only - assertEquals( - 512, - BATBlock.calculateMaximumSize(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, 0) - ); - assertEquals( - 4096, - BATBlock.calculateMaximumSize(POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS, 0) - ); - - // A single FAT block can address 128/1024 blocks - assertEquals( - 512 + 512*128, - BATBlock.calculateMaximumSize(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, 1) - ); - assertEquals( - 4096 + 4096*1024, - BATBlock.calculateMaximumSize(POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS, 1) - ); - - assertEquals( - 512 + 4*512*128, - BATBlock.calculateMaximumSize(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, 4) - ); - assertEquals( - 4096 + 4*4096*1024, - BATBlock.calculateMaximumSize(POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS, 4) - ); - - // One XBAT block holds 127/1023 individual BAT blocks, so they can address - // a fairly hefty amount of space themselves - // However, the BATs continue as before - assertEquals( - 512 + 109*512*128, - BATBlock.calculateMaximumSize(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, 109) - ); - assertEquals( - 4096 + 109*4096*1024, - BATBlock.calculateMaximumSize(POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS, 109) - ); - - assertEquals( - 512 + 110*512*128, - BATBlock.calculateMaximumSize(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, 110) - ); - assertEquals( - 4096 + 110*4096*1024, - BATBlock.calculateMaximumSize(POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS, 110) - ); - - assertEquals( - 512 + 112*512*128, - BATBlock.calculateMaximumSize(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, 112) - ); - assertEquals( - 4096 + 112*4096*1024, - BATBlock.calculateMaximumSize(POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS, 112) - ); - - // Check for >2gb, which we only support via a File - assertEquals( - 512 + 8030L *512*128, - BATBlock.calculateMaximumSize(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, 8030) - ); - assertEquals( - 4096 + 8030L *4096*1024, - BATBlock.calculateMaximumSize(POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS, 8030) - ); + // Zero fat blocks isn't technically valid, but it'd be header only + assertEquals( + 512, + BATBlock.calculateMaximumSize(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, 0) + ); + assertEquals( + 4096, + BATBlock.calculateMaximumSize(POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS, 0) + ); + + // A single FAT block can address 128/1024 blocks + assertEquals( + 512 + 512 * 128, + BATBlock.calculateMaximumSize(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, 1) + ); + assertEquals( + 4096 + 4096 * 1024, + BATBlock.calculateMaximumSize(POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS, 1) + ); + + assertEquals( + 512 + 4 * 512 * 128, + BATBlock.calculateMaximumSize(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, 4) + ); + assertEquals( + 4096 + 4 * 4096 * 1024, + BATBlock.calculateMaximumSize(POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS, 4) + ); + + // One XBAT block holds 127/1023 individual BAT blocks, so they can address + // a fairly hefty amount of space themselves + // However, the BATs continue as before + assertEquals( + 512 + 109 * 512 * 128, + BATBlock.calculateMaximumSize(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, 109) + ); + assertEquals( + 4096 + 109 * 4096 * 1024, + BATBlock.calculateMaximumSize(POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS, 109) + ); + + assertEquals( + 512 + 110 * 512 * 128, + BATBlock.calculateMaximumSize(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, 110) + ); + assertEquals( + 4096 + 110 * 4096 * 1024, + BATBlock.calculateMaximumSize(POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS, 110) + ); + + assertEquals( + 512 + 112 * 512 * 128, + BATBlock.calculateMaximumSize(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, 112) + ); + assertEquals( + 4096 + 112 * 4096 * 1024, + BATBlock.calculateMaximumSize(POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS, 112) + ); + + // Check for >2gb, which we only support via a File + assertEquals( + 512 + 8030L * 512 * 128, + BATBlock.calculateMaximumSize(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, 8030) + ); + assertEquals( + 4096 + 8030L * 4096 * 1024, + BATBlock.calculateMaximumSize(POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS, 8030) + ); } @Test public void testUsedSectors() { POIFSBigBlockSize b512 = POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS; POIFSBigBlockSize b4096 = POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS; - + // Try first with 512 block sizes, which can hold 128 entries BATBlock block512 = BATBlock.createEmptyBATBlock(b512, false); assertTrue(block512.hasFreeSectors()); @@ -138,36 +138,36 @@ public final class TestBATBlock { block512.setValueAt(20, 42); assertTrue(block512.hasFreeSectors()); assertEquals(3, block512.getUsedSectors(false)); - + // Allocate all - for (int i=0; i<b512.getBATEntriesPerBlock(); i++) { + for (int i = 0; i < b512.getBATEntriesPerBlock(); i++) { block512.setValueAt(i, 82); } // Check assertFalse(block512.hasFreeSectors()); assertEquals(128, block512.getUsedSectors(false)); assertEquals(127, block512.getUsedSectors(true)); - + // Release one block512.setValueAt(10, POIFSConstants.UNUSED_BLOCK); assertTrue(block512.hasFreeSectors()); assertEquals(127, block512.getUsedSectors(false)); assertEquals(126, block512.getUsedSectors(true)); - - + + // Now repeat with 4096 block sizes BATBlock block4096 = BATBlock.createEmptyBATBlock(b4096, false); assertTrue(block4096.hasFreeSectors()); assertEquals(0, block4096.getUsedSectors(false)); - + block4096.setValueAt(0, 42); block4096.setValueAt(10, 42); block4096.setValueAt(20, 42); assertTrue(block4096.hasFreeSectors()); assertEquals(3, block4096.getUsedSectors(false)); - + // Allocate all - for (int i=0; i<b4096.getBATEntriesPerBlock(); i++) { + for (int i = 0; i < b4096.getBATEntriesPerBlock(); i++) { block4096.setValueAt(i, 82); } // Check @@ -177,114 +177,175 @@ public final class TestBATBlock { } @Test + public void testOccupiedSize() { + POIFSBigBlockSize b512 = POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS; + POIFSBigBlockSize b4096 = POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS; + + // Try first with 512 block sizes, which can hold 128 entries + BATBlock block512 = BATBlock.createEmptyBATBlock(b512, false); + assertTrue(block512.hasFreeSectors()); + assertEquals(0, block512.getUsedSectors(false)); + + // Allocate a few + block512.setValueAt(0, 42); + block512.setValueAt(10, 42); + block512.setValueAt(20, 42); + assertTrue(block512.hasFreeSectors()); + assertEquals(21, block512.getOccupiedSize()); + + // Release one in the middle should not lower size + block512.setValueAt(10, POIFSConstants.UNUSED_BLOCK); + assertTrue(block512.hasFreeSectors()); + assertEquals(21, block512.getOccupiedSize()); + + // Release the last one should lower the size + block512.setValueAt(20, POIFSConstants.UNUSED_BLOCK); + assertTrue(block512.hasFreeSectors()); + assertEquals(1, block512.getOccupiedSize()); + + // Release first one should lower the size + block512.setValueAt(0, POIFSConstants.UNUSED_BLOCK); + assertTrue(block512.hasFreeSectors()); + assertEquals(0, block512.getOccupiedSize()); + + // Set the last one + block512.setValueAt(127, 42); + assertTrue(block512.hasFreeSectors()); + assertEquals(128, block512.getOccupiedSize()); + + block512.setValueAt(126, 42); + assertTrue(block512.hasFreeSectors()); + assertEquals(128, block512.getOccupiedSize()); + + block512.setValueAt(127, POIFSConstants.UNUSED_BLOCK); + assertTrue(block512.hasFreeSectors()); + assertEquals(127, block512.getOccupiedSize()); + + // Allocate all + for (int i = 0; i < b512.getBATEntriesPerBlock(); i++) { + block512.setValueAt(i, 82); + } + // Check + assertFalse(block512.hasFreeSectors()); + assertEquals(128, block512.getOccupiedSize()); + + // Release some in the beginning should not lower size + block512.setValueAt(0, POIFSConstants.UNUSED_BLOCK); + block512.setValueAt(1, POIFSConstants.UNUSED_BLOCK); + block512.setValueAt(13, POIFSConstants.UNUSED_BLOCK); + assertTrue(block512.hasFreeSectors()); + assertEquals(128, block512.getOccupiedSize()); + } + + @Test public void testGetBATBlockAndIndex() { - HeaderBlock header = new HeaderBlock(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); - List<BATBlock> blocks = new ArrayList<>(); - int offset; - - - // First, try a one BAT block file - header.setBATCount(1); - blocks.add( - BATBlock.createBATBlock(header.getBigBlockSize(), ByteBuffer.allocate(512)) - ); - - offset = 0; - assertEquals(0, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); - assertEquals(0, blocks.indexOf( BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock() )); - - offset = 1; - assertEquals(1, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); - assertEquals(0, blocks.indexOf( BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock() )); - - offset = 127; - assertEquals(127, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); - assertEquals(0, blocks.indexOf( BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock() )); - - - // Now go for one with multiple BAT blocks - header.setBATCount(2); - blocks.add( - BATBlock.createBATBlock(header.getBigBlockSize(), ByteBuffer.allocate(512)) - ); - - offset = 0; - assertEquals(0, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); - assertEquals(0, blocks.indexOf( BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock() )); - - offset = 127; - assertEquals(127, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); - assertEquals(0, blocks.indexOf( BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock() )); - - offset = 128; - assertEquals(0, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); - assertEquals(1, blocks.indexOf( BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock() )); - - offset = 129; - assertEquals(1, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); - assertEquals(1, blocks.indexOf( BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock() )); - - - // The XBAT count makes no difference, as we flatten in memory - header.setBATCount(1); - header.setXBATCount(1); - offset = 0; - assertEquals(0, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); - assertEquals(0, blocks.indexOf( BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock() )); - - offset = 126; - assertEquals(126, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); - assertEquals(0, blocks.indexOf( BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock() )); - - offset = 127; - assertEquals(127, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); - assertEquals(0, blocks.indexOf( BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock() )); - - offset = 128; - assertEquals(0, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); - assertEquals(1, blocks.indexOf( BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock() )); - - offset = 129; - assertEquals(1, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); - assertEquals(1, blocks.indexOf( BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock() )); - - - // Check with the bigger block size too - header = new HeaderBlock(POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS); - - offset = 0; - assertEquals(0, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); - assertEquals(0, blocks.indexOf( BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock() )); - - offset = 1022; - assertEquals(1022, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); - assertEquals(0, blocks.indexOf( BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock() )); - - offset = 1023; - assertEquals(1023, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); - assertEquals(0, blocks.indexOf( BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock() )); - - offset = 1024; - assertEquals(0, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); - assertEquals(1, blocks.indexOf( BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock() )); - - // Biggr block size, back to real BATs - header.setBATCount(2); - - offset = 0; - assertEquals(0, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); - assertEquals(0, blocks.indexOf( BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock() )); - - offset = 1022; - assertEquals(1022, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); - assertEquals(0, blocks.indexOf( BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock() )); - - offset = 1023; - assertEquals(1023, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); - assertEquals(0, blocks.indexOf( BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock() )); - - offset = 1024; - assertEquals(0, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); - assertEquals(1, blocks.indexOf( BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock() )); + HeaderBlock header = new HeaderBlock(POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS); + List<BATBlock> blocks = new ArrayList<>(); + int offset; + + + // First, try a one BAT block file + header.setBATCount(1); + blocks.add( + BATBlock.createBATBlock(header.getBigBlockSize(), ByteBuffer.allocate(512)) + ); + + offset = 0; + assertEquals(0, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); + assertEquals(0, blocks.indexOf(BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock())); + + offset = 1; + assertEquals(1, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); + assertEquals(0, blocks.indexOf(BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock())); + + offset = 127; + assertEquals(127, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); + assertEquals(0, blocks.indexOf(BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock())); + + + // Now go for one with multiple BAT blocks + header.setBATCount(2); + blocks.add( + BATBlock.createBATBlock(header.getBigBlockSize(), ByteBuffer.allocate(512)) + ); + + offset = 0; + assertEquals(0, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); + assertEquals(0, blocks.indexOf(BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock())); + + offset = 127; + assertEquals(127, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); + assertEquals(0, blocks.indexOf(BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock())); + + offset = 128; + assertEquals(0, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); + assertEquals(1, blocks.indexOf(BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock())); + + offset = 129; + assertEquals(1, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); + assertEquals(1, blocks.indexOf(BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock())); + + + // The XBAT count makes no difference, as we flatten in memory + header.setBATCount(1); + header.setXBATCount(1); + offset = 0; + assertEquals(0, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); + assertEquals(0, blocks.indexOf(BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock())); + + offset = 126; + assertEquals(126, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); + assertEquals(0, blocks.indexOf(BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock())); + + offset = 127; + assertEquals(127, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); + assertEquals(0, blocks.indexOf(BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock())); + + offset = 128; + assertEquals(0, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); + assertEquals(1, blocks.indexOf(BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock())); + + offset = 129; + assertEquals(1, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); + assertEquals(1, blocks.indexOf(BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock())); + + + // Check with the bigger block size too + header = new HeaderBlock(POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS); + + offset = 0; + assertEquals(0, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); + assertEquals(0, blocks.indexOf(BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock())); + + offset = 1022; + assertEquals(1022, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); + assertEquals(0, blocks.indexOf(BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock())); + + offset = 1023; + assertEquals(1023, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); + assertEquals(0, blocks.indexOf(BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock())); + + offset = 1024; + assertEquals(0, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); + assertEquals(1, blocks.indexOf(BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock())); + + // Biggr block size, back to real BATs + header.setBATCount(2); + + offset = 0; + assertEquals(0, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); + assertEquals(0, blocks.indexOf(BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock())); + + offset = 1022; + assertEquals(1022, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); + assertEquals(0, blocks.indexOf(BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock())); + + offset = 1023; + assertEquals(1023, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); + assertEquals(0, blocks.indexOf(BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock())); + + offset = 1024; + assertEquals(0, BATBlock.getBATBlockAndIndex(offset, header, blocks).getIndex()); + assertEquals(1, blocks.indexOf(BATBlock.getBATBlockAndIndex(offset, header, blocks).getBlock())); } } |