More int/long sizing fixes for >2gb NPOIFS files, see bug #56447
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1589783 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
e7dff43065
commit
fbd86d5084
@ -271,12 +271,17 @@ public class NPOIFSFileSystem extends BlockStore
|
||||
// We need to buffer the whole file into memory when
|
||||
// working with an InputStream.
|
||||
// The max possible size is when each BAT block entry is used
|
||||
int maxSize = BATBlock.calculateMaximumSize(_header);
|
||||
ByteBuffer data = ByteBuffer.allocate(maxSize);
|
||||
long maxSize = BATBlock.calculateMaximumSize(_header);
|
||||
if (maxSize > Integer.MAX_VALUE) {
|
||||
throw new IllegalArgumentException("Unable read a >2gb file via an InputStream");
|
||||
}
|
||||
ByteBuffer data = ByteBuffer.allocate((int)maxSize);
|
||||
|
||||
// Copy in the header
|
||||
headerBuffer.position(0);
|
||||
data.put(headerBuffer);
|
||||
data.position(headerBuffer.capacity());
|
||||
|
||||
// Now read the rest of the stream
|
||||
IOUtils.readFully(channel, data);
|
||||
success = true;
|
||||
@ -424,7 +429,8 @@ public class NPOIFSFileSystem extends BlockStore
|
||||
@Override
|
||||
protected ByteBuffer getBlockAt(final int offset) throws IOException {
|
||||
// The header block doesn't count, so add one
|
||||
long startAt = (offset+1) * bigBlockSize.getBigBlockSize();
|
||||
long blockWanted = offset + 1;
|
||||
long startAt = blockWanted * bigBlockSize.getBigBlockSize();
|
||||
return _data.read(bigBlockSize.getBigBlockSize(), startAt);
|
||||
}
|
||||
|
||||
|
@ -242,9 +242,9 @@ public final class BATBlock extends BigBlock {
|
||||
* For 512 byte block sizes, this means we may over-estimate by up to 65kb.
|
||||
* For 4096 byte block sizes, this means we may over-estimate by up to 4mb
|
||||
*/
|
||||
public static int calculateMaximumSize(final POIFSBigBlockSize bigBlockSize,
|
||||
public static long calculateMaximumSize(final POIFSBigBlockSize bigBlockSize,
|
||||
final int numBATs) {
|
||||
int size = 1; // Header isn't FAT addressed
|
||||
long size = 1; // Header isn't FAT addressed
|
||||
|
||||
// The header has up to 109 BATs, and extra ones are referenced
|
||||
// from XBATs
|
||||
@ -254,7 +254,7 @@ public final class BATBlock extends BigBlock {
|
||||
// So far we've been in sector counts, turn into bytes
|
||||
return size * bigBlockSize.getBigBlockSize();
|
||||
}
|
||||
public static int calculateMaximumSize(final HeaderBlock header)
|
||||
public static long calculateMaximumSize(final HeaderBlock header)
|
||||
{
|
||||
return calculateMaximumSize(header.getBigBlockSize(), header.getBATCount());
|
||||
}
|
||||
|
@ -24,10 +24,10 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.poi.poifs.common.POIFSConstants;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.poi.poifs.common.POIFSConstants;
|
||||
|
||||
/**
|
||||
* Class to test BATBlock functionality
|
||||
*
|
||||
@ -271,6 +271,16 @@ public final class TestBATBlock extends TestCase {
|
||||
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)
|
||||
);
|
||||
}
|
||||
|
||||
public void testGetBATBlockAndIndex() throws Exception {
|
||||
|
Loading…
Reference in New Issue
Block a user