Fix a couple of NPOIFS bugs relating to empty files, empty documents and non-padded stream data
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1085493 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
a7e39ad6c2
commit
eb812a0e8c
@ -24,6 +24,7 @@ import java.io.InputStream;
|
|||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.poi.poifs.common.POIFSConstants;
|
import org.apache.poi.poifs.common.POIFSConstants;
|
||||||
import org.apache.poi.poifs.dev.POIFSViewable;
|
import org.apache.poi.poifs.dev.POIFSViewable;
|
||||||
@ -106,7 +107,12 @@ public final class NPOIFSDocument implements POIFSViewable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Iterator<ByteBuffer> getBlockIterator() {
|
Iterator<ByteBuffer> getBlockIterator() {
|
||||||
return _stream.getBlockIterator();
|
if(getSize() > 0) {
|
||||||
|
return _stream.getBlockIterator();
|
||||||
|
} else {
|
||||||
|
List<ByteBuffer> empty = Collections.emptyList();
|
||||||
|
return empty.iterator();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -103,6 +103,9 @@ public class NPOIFSFileSystem extends BlockStore
|
|||||||
_xbat_blocks = new ArrayList<BATBlock>();
|
_xbat_blocks = new ArrayList<BATBlock>();
|
||||||
_bat_blocks = new ArrayList<BATBlock>();
|
_bat_blocks = new ArrayList<BATBlock>();
|
||||||
_root = null;
|
_root = null;
|
||||||
|
|
||||||
|
// Data needs to initially hold just the header block
|
||||||
|
_data = new ByteArrayBackedDataSource(new byte[bigBlockSize.getBigBlockSize()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -102,7 +102,7 @@ public class NPOIFSStream implements Iterable<ByteBuffer>
|
|||||||
public void updateContents(byte[] contents) throws IOException {
|
public void updateContents(byte[] contents) throws IOException {
|
||||||
// How many blocks are we going to need?
|
// How many blocks are we going to need?
|
||||||
int blockSize = blockStore.getBlockStoreBlockSize();
|
int blockSize = blockStore.getBlockStoreBlockSize();
|
||||||
int blocks = (int)Math.ceil(contents.length / blockSize);
|
int blocks = (int)Math.ceil( ((double)contents.length) / blockSize );
|
||||||
|
|
||||||
// Make sure we don't encounter a loop whilst overwriting
|
// Make sure we don't encounter a loop whilst overwriting
|
||||||
// the existing blocks
|
// the existing blocks
|
||||||
@ -141,7 +141,9 @@ public class NPOIFSStream implements Iterable<ByteBuffer>
|
|||||||
|
|
||||||
// Write it
|
// Write it
|
||||||
ByteBuffer buffer = blockStore.createBlockIfNeeded(thisBlock);
|
ByteBuffer buffer = blockStore.createBlockIfNeeded(thisBlock);
|
||||||
buffer.put(contents, i*blockSize, blockSize);
|
int startAt = i*blockSize;
|
||||||
|
int endAt = Math.min(contents.length - startAt, blockSize);
|
||||||
|
buffer.put(contents, startAt, endAt);
|
||||||
|
|
||||||
// Update pointers
|
// Update pointers
|
||||||
prevBlock = thisBlock;
|
prevBlock = thisBlock;
|
||||||
|
@ -24,6 +24,7 @@ import junit.framework.TestCase;
|
|||||||
|
|
||||||
import org.apache.poi.POIDataSamples;
|
import org.apache.poi.POIDataSamples;
|
||||||
import org.apache.poi.poifs.common.POIFSConstants;
|
import org.apache.poi.poifs.common.POIFSConstants;
|
||||||
|
import org.apache.poi.poifs.storage.BATBlock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests {@link NPOIFSStream}
|
* Tests {@link NPOIFSStream}
|
||||||
@ -638,4 +639,69 @@ public final class TestNPOIFSStream extends TestCase {
|
|||||||
fail("Loop should have been detected but wasn't!");
|
fail("Loop should have been detected but wasn't!");
|
||||||
} catch(IllegalStateException e) {}
|
} catch(IllegalStateException e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests adding a new stream, writing and reading it.
|
||||||
|
*/
|
||||||
|
public void testReadWriteNewStream() throws Exception {
|
||||||
|
NPOIFSFileSystem fs = new NPOIFSFileSystem();
|
||||||
|
NPOIFSStream stream = new NPOIFSStream(fs);
|
||||||
|
|
||||||
|
// Check our filesystem has a single block
|
||||||
|
// to hold the BAT
|
||||||
|
assertEquals(1, fs.getFreeBlock());
|
||||||
|
BATBlock bat = fs.getBATBlockAndIndex(0).getBlock();
|
||||||
|
assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(0));
|
||||||
|
assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(1));
|
||||||
|
|
||||||
|
// Check the stream as-is
|
||||||
|
assertEquals(POIFSConstants.END_OF_CHAIN, stream.getStartBlock());
|
||||||
|
try {
|
||||||
|
stream.getBlockIterator();
|
||||||
|
fail("Shouldn't be able to get an iterator before writing");
|
||||||
|
} catch(IllegalStateException e) {}
|
||||||
|
|
||||||
|
// Write in two blocks
|
||||||
|
byte[] data = new byte[512+20];
|
||||||
|
for(int i=0; i<512; i++) {
|
||||||
|
data[i] = (byte)(i%256);
|
||||||
|
}
|
||||||
|
for(int i=512; i<data.length; i++) {
|
||||||
|
data[i] = (byte)(i%256 + 100);
|
||||||
|
}
|
||||||
|
stream.updateContents(data);
|
||||||
|
|
||||||
|
// Check now
|
||||||
|
assertEquals(3, fs.getFreeBlock());
|
||||||
|
bat = fs.getBATBlockAndIndex(0).getBlock();
|
||||||
|
assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(0));
|
||||||
|
assertEquals(2, bat.getValueAt(1));
|
||||||
|
assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(2));
|
||||||
|
assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(3));
|
||||||
|
|
||||||
|
|
||||||
|
Iterator<ByteBuffer> it = stream.getBlockIterator();
|
||||||
|
assertEquals(true, it.hasNext());
|
||||||
|
ByteBuffer b = it.next();
|
||||||
|
|
||||||
|
byte[] read = new byte[512];
|
||||||
|
b.get(read);
|
||||||
|
for(int i=0; i<read.length; i++) {
|
||||||
|
assertEquals("Wrong value at " + i, data[i], read[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(true, it.hasNext());
|
||||||
|
b = it.next();
|
||||||
|
|
||||||
|
read = new byte[512];
|
||||||
|
b.get(read);
|
||||||
|
for(int i=0; i<20; i++) {
|
||||||
|
assertEquals(data[i+512], read[i]);
|
||||||
|
}
|
||||||
|
for(int i=20; i<read.length; i++) {
|
||||||
|
assertEquals(0, read[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(false, it.hasNext());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user