use of org.apache.poi.poifs.filesystem.DocumentInputStream in project poi by apache.
the class TreeReaderListener method processPOIFSReaderEvent.
/**
* <p>A document in the POI filesystem has been opened for
* reading. This method retrieves properties of the document and
* adds them to a tree model.</p>
*/
@Override
public void processPOIFSReaderEvent(final POIFSReaderEvent event) {
DocumentDescriptor d;
final DocumentInputStream is = event.getStream();
if (!is.markSupported()) {
throw new UnsupportedOperationException(is.getClass().getName() + " does not support mark().");
}
/* Try do handle this document as a property set. We receive
* an exception if is no property set and handle it as a
* document of some other format. We are not concerned about
* that document's details. */
try {
d = new PropertySetDescriptor(event.getName(), event.getPath(), is, nrOfBytes);
} catch (HPSFException ex) {
d = new DocumentDescriptor(event.getName(), event.getPath(), is, nrOfBytes);
} catch (Exception t) {
throw new RuntimeException("Unexpected exception while processing " + event.getName() + " in " + event.getPath(), t);
}
is.close();
final MutableTreeNode parentNode = getNode(d.path, filename, rootNode);
final MutableTreeNode nameNode = new DefaultMutableTreeNode(d.name);
parentNode.insert(nameNode, 0);
final MutableTreeNode dNode = new DefaultMutableTreeNode(d);
nameNode.insert(dNode, 0);
}
use of org.apache.poi.poifs.filesystem.DocumentInputStream in project poi by apache.
the class POIFSChunkParser method process.
/**
* Creates a chunk, and gives it to its parent group
*/
protected static void process(Entry entry, ChunkGroup grouping) {
String entryName = entry.getName();
Chunk chunk = null;
// Is it a properties chunk? (They have special names)
if (entryName.equals(PropertiesChunk.NAME)) {
if (grouping instanceof Chunks) {
// These should be the properties for the message itself
chunk = new MessagePropertiesChunk(grouping);
} else {
// Will be properties on an attachment or recipient
chunk = new StoragePropertiesChunk(grouping);
}
} else {
// Check it's a regular chunk
if (entryName.length() < 9) {
// Name in the wrong format
return;
}
if (!entryName.contains("_")) {
// Name in the wrong format
return;
}
// Split it into its parts
int splitAt = entryName.lastIndexOf('_');
String namePrefix = entryName.substring(0, splitAt + 1);
String ids = entryName.substring(splitAt + 1);
// the form __<name>_<id><type>
if (namePrefix.equals("Olk10SideProps") || namePrefix.equals("Olk10SideProps_")) {
// This is some odd Outlook 2002 thing, skip
return;
} else if (splitAt <= entryName.length() - 8) {
// In the right form for a normal chunk
// We'll process this further in a little bit
} else {
// Underscores not the right place, something's wrong
throw new IllegalArgumentException("Invalid chunk name " + entryName);
}
// Now try to turn it into id + type
try {
int chunkId = Integer.parseInt(ids.substring(0, 4), 16);
int typeId = Integer.parseInt(ids.substring(4, 8), 16);
MAPIType type = Types.getById(typeId);
if (type == null) {
type = Types.createCustom(typeId);
}
// Special cases based on the ID
if (chunkId == MAPIProperty.MESSAGE_SUBMISSION_ID.id) {
chunk = new MessageSubmissionChunk(namePrefix, chunkId, type);
} else {
// So, do the usual thing which is by type
if (type == Types.BINARY) {
chunk = new ByteChunk(namePrefix, chunkId, type);
} else if (type == Types.DIRECTORY) {
if (entry instanceof DirectoryNode) {
chunk = new DirectoryChunk((DirectoryNode) entry, namePrefix, chunkId, type);
}
} else if (type == Types.ASCII_STRING || type == Types.UNICODE_STRING) {
chunk = new StringChunk(namePrefix, chunkId, type);
} else {
// Type of an unsupported type! Skipping...
}
}
} catch (NumberFormatException e) {
// Name in the wrong format
return;
}
}
if (chunk != null) {
if (entry instanceof DocumentNode) {
DocumentInputStream inp = null;
try {
inp = new DocumentInputStream((DocumentNode) entry);
chunk.readValue(inp);
grouping.record(chunk);
} catch (IOException e) {
logger.log(POILogger.ERROR, "Error reading from part " + entry.getName() + " - " + e);
} finally {
if (inp != null)
inp.close();
}
} else {
grouping.record(chunk);
}
}
}
use of org.apache.poi.poifs.filesystem.DocumentInputStream in project poi by apache.
the class HSLFSlideShowImpl method readPictures.
/**
* Find and read in pictures contained in this presentation.
* This is lazily called as and when we want to touch pictures.
*/
private void readPictures() throws IOException {
_pictures = new ArrayList<HSLFPictureData>();
// if the presentation doesn't contain pictures - will use a null set instead
if (!getDirectory().hasEntry("Pictures")) {
return;
}
DocumentEntry entry = (DocumentEntry) getDirectory().getEntry("Pictures");
DocumentInputStream is = getDirectory().createDocumentInputStream(entry);
byte[] pictstream = IOUtils.toByteArray(is, entry.getSize());
is.close();
HSLFSlideShowEncrypted decryptData = new HSLFSlideShowEncrypted(getDocumentEncryptionAtom());
try {
int pos = 0;
// An empty picture record (length 0) will take up 8 bytes
while (pos <= (pictstream.length - 8)) {
int offset = pos;
decryptData.decryptPicture(pictstream, offset);
// Image signature
int signature = LittleEndian.getUShort(pictstream, pos);
pos += LittleEndianConsts.SHORT_SIZE;
// Image type + 0xF018
int type = LittleEndian.getUShort(pictstream, pos);
pos += LittleEndianConsts.SHORT_SIZE;
// Image size (excluding the 8 byte header)
int imgsize = LittleEndian.getInt(pictstream, pos);
pos += LittleEndianConsts.INT_SIZE;
// should terminate if the type isn't 0xf007 or 0xf018->0xf117
if (!((type == 0xf007) || (type >= 0xf018 && type <= 0xf117))) {
break;
}
// time, so we won't get stuck)
if (imgsize < 0) {
throw new CorruptPowerPointFileException("The file contains a picture, at position " + _pictures.size() + ", which has a negatively sized data length, so we can't trust any of the picture data");
}
// If they type (including the bonus 0xF018) is 0, skip it
PictureType pt = PictureType.forNativeID(type - 0xF018);
if (pt == null) {
logger.log(POILogger.ERROR, "Problem reading picture: Invalid image type 0, on picture with length " + imgsize + ".\nYou document will probably become corrupted if you save it!");
logger.log(POILogger.ERROR, "" + pos);
} else {
//that are not used in any slide -- BUG-60305
if (pos + imgsize > pictstream.length) {
logger.log(POILogger.WARN, "\"Pictures\" stream may have ended early. In some circumstances, this is not a problem; " + "in others, this could indicate a corrupt file");
break;
}
// Build the PictureData object from the data
try {
HSLFPictureData pict = HSLFPictureData.create(pt);
pict.setSignature(signature);
// Copy the data, ready to pass to PictureData
byte[] imgdata = new byte[imgsize];
System.arraycopy(pictstream, pos, imgdata, 0, imgdata.length);
pict.setRawData(imgdata);
pict.setOffset(offset);
pict.setIndex(_pictures.size());
_pictures.add(pict);
} catch (IllegalArgumentException e) {
logger.log(POILogger.ERROR, "Problem reading picture: " + e + "\nYou document will probably become corrupted if you save it!");
}
}
pos += imgsize;
}
} finally {
decryptData.close();
}
}
use of org.apache.poi.poifs.filesystem.DocumentInputStream in project poi by apache.
the class POIDocument method getPropertySet.
/**
* For a given named property entry, either return it or null if
* if it wasn't found
*
* @param setName The property to read
* @param encryptionInfo the encryption descriptor in case of cryptoAPI encryption
* @return The value of the given property or null if it wasn't found.
*/
protected PropertySet getPropertySet(String setName, EncryptionInfo encryptionInfo) {
DirectoryNode dirNode = directory;
NPOIFSFileSystem encPoifs = null;
String step = "getting";
try {
if (encryptionInfo != null) {
step = "getting encrypted";
String encryptedStream = null;
for (String s : encryptedStreamNames) {
if (dirNode.hasEntry(s)) {
encryptedStream = s;
}
}
if (encryptedStream == null) {
throw new EncryptedDocumentException("can't find matching encrypted property stream");
}
CryptoAPIDecryptor dec = (CryptoAPIDecryptor) encryptionInfo.getDecryptor();
encPoifs = dec.getSummaryEntries(dirNode, encryptedStream);
dirNode = encPoifs.getRoot();
}
//directory can be null when creating new documents
if (dirNode == null || !dirNode.hasEntry(setName)) {
return null;
}
// Find the entry, and get an input stream for it
step = "getting";
DocumentInputStream dis = dirNode.createDocumentInputStream(dirNode.getEntry(setName));
try {
// Create the Property Set
step = "creating";
return PropertySetFactory.create(dis);
} finally {
dis.close();
}
} catch (Exception e) {
logger.log(POILogger.WARN, "Error " + step + " property set with name " + setName, e);
return null;
} finally {
if (encPoifs != null) {
try {
encPoifs.close();
} catch (IOException e) {
logger.log(POILogger.WARN, "Error closing encrypted property poifs", e);
}
}
}
}
use of org.apache.poi.poifs.filesystem.DocumentInputStream in project poi by apache.
the class CryptoAPIDecryptor method getSummaryEntries.
/**
* Decrypt the Document-/SummaryInformation and other optionally streams.
* Opposed to other crypto modes, cryptoapi is record based and can't be used
* to stream-decrypt a whole file
*
* @see <a href="http://msdn.microsoft.com/en-us/library/dd943321(v=office.12).aspx">2.3.5.4 RC4 CryptoAPI Encrypted Summary Stream</a>
*/
public POIFSFileSystem getSummaryEntries(DirectoryNode root, String encryptedStream) throws IOException, GeneralSecurityException {
// HSLF: encryptedStream
// HSSF: encryption
DocumentNode es = (DocumentNode) root.getEntry(encryptedStream);
DocumentInputStream dis = root.createDocumentInputStream(es);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
IOUtils.copy(dis, bos);
dis.close();
CryptoAPIDocumentInputStream sbis = new CryptoAPIDocumentInputStream(this, bos.toByteArray());
LittleEndianInputStream leis = new LittleEndianInputStream(sbis);
POIFSFileSystem fsOut = null;
try {
int streamDescriptorArrayOffset = (int) leis.readUInt();
/* int streamDescriptorArraySize = (int) */
leis.readUInt();
long skipN = streamDescriptorArrayOffset - 8L;
if (sbis.skip(skipN) < skipN) {
throw new EOFException("buffer underrun");
}
sbis.setBlock(0);
int encryptedStreamDescriptorCount = (int) leis.readUInt();
StreamDescriptorEntry[] entries = new StreamDescriptorEntry[encryptedStreamDescriptorCount];
for (int i = 0; i < encryptedStreamDescriptorCount; i++) {
StreamDescriptorEntry entry = new StreamDescriptorEntry();
entries[i] = entry;
entry.streamOffset = (int) leis.readUInt();
entry.streamSize = (int) leis.readUInt();
entry.block = leis.readUShort();
int nameSize = leis.readUByte();
entry.flags = leis.readUByte();
// boolean isStream = StreamDescriptorEntry.flagStream.isSet(entry.flags);
entry.reserved2 = leis.readInt();
entry.streamName = StringUtil.readUnicodeLE(leis, nameSize);
leis.readShort();
assert (entry.streamName.length() == nameSize);
}
// NOSONAR
fsOut = new POIFSFileSystem();
for (StreamDescriptorEntry entry : entries) {
sbis.seek(entry.streamOffset);
sbis.setBlock(entry.block);
InputStream is = new BoundedInputStream(sbis, entry.streamSize);
fsOut.createDocument(is, entry.streamName);
is.close();
}
} catch (Exception e) {
IOUtils.closeQuietly(fsOut);
if (e instanceof GeneralSecurityException) {
throw (GeneralSecurityException) e;
} else if (e instanceof IOException) {
throw (IOException) e;
} else {
throw new IOException("summary entries can't be read", e);
}
} finally {
IOUtils.closeQuietly(leis);
IOUtils.closeQuietly(sbis);
}
return fsOut;
}
Aggregations