diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hwpf/HWPFDocument.java b/poi-scratchpad/src/main/java/org/apache/poi/hwpf/HWPFDocument.java index a4fd555a910..67fc4b4414c 100644 --- a/poi-scratchpad/src/main/java/org/apache/poi/hwpf/HWPFDocument.java +++ b/poi-scratchpad/src/main/java/org/apache/poi/hwpf/HWPFDocument.java @@ -223,6 +223,23 @@ public HWPFDocument(InputStream istream) throws IOException { this(verifyAndBuildPOIFS(istream)); } + /** + * This constructor loads a Word document from an InputStream. + * + * @param istream The InputStream that contains the Word document. + * @param password in char array format (can be null) + * @throws IOException If there is an unexpected IOException from the passed + * in InputStream. + * @throws org.apache.poi.EmptyFileException If the given stream is empty + * @throws IllegalStateException a number of other runtime exceptions can be thrown, especially if there are problems with the + * input format + * @since 6.0.0 + */ + public HWPFDocument(InputStream istream, final char[] password) throws IOException { + //do Ole stuff + this(verifyAndBuildPOIFS(istream), password); + } + /** * This constructor loads a Word document from a POIFSFileSystem * @@ -236,6 +253,21 @@ public HWPFDocument(POIFSFileSystem pfilesystem) throws IOException { this(pfilesystem.getRoot()); } + /** + * This constructor loads a Word document from a POIFSFileSystem + * + * @param pfilesystem The POIFSFileSystem that contains the Word document. + * @throws IOException If there is an unexpected IOException from the passed + * in POIFSFileSystem. + * @param password in char array format (can be null) + * @throws IllegalStateException a number of runtime exceptions can be thrown, especially if there are problems with the + * input format + * @since 6.0.0 + */ + public HWPFDocument(POIFSFileSystem pfilesystem, final char[] password) throws IOException { + this(pfilesystem.getRoot(), password); + } + /** * This constructor loads a Word document from a specific point * in a POIFSFileSystem, probably not the default. @@ -248,9 +280,26 @@ public HWPFDocument(POIFSFileSystem pfilesystem) throws IOException { * input format */ public HWPFDocument(DirectoryNode directory) throws IOException { + this(directory, null); + } + + /** + * This constructor loads a Word document from a specific point + * in a POIFSFileSystem, probably not the default. + * Used typically to open embedded documents. + * + * @param directory The DirectoryNode that contains the Word document. + * @param password in char array format (can be null) + * @throws IOException If there is an unexpected IOException from the passed + * in POIFSFileSystem. + * @throws IllegalStateException a number of runtime exceptions can be thrown, especially if there are problems with the + * input format + * @since 6.0.0 + */ + public HWPFDocument(DirectoryNode directory, final char[] password) throws IOException { // Load the main stream and FIB // Also handles HPSF bits - super(directory); + super(directory, password); // Is this document too old for us? if (_fib.getFibBase().getNFib() < 106) { diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hwpf/HWPFDocumentCore.java b/poi-scratchpad/src/main/java/org/apache/poi/hwpf/HWPFDocumentCore.java index be8328280e6..2ea12246331 100644 --- a/poi-scratchpad/src/main/java/org/apache/poi/hwpf/HWPFDocumentCore.java +++ b/poi-scratchpad/src/main/java/org/apache/poi/hwpf/HWPFDocumentCore.java @@ -124,6 +124,8 @@ public static int getMaxRecordLength() { /** main document stream buffer*/ protected byte[] _mainStream; + private char[] _password; + private EncryptionInfo _encryptionInfo; protected HWPFDocumentCore() { @@ -160,6 +162,20 @@ public HWPFDocumentCore(InputStream istream) throws IOException { this( verifyAndBuildPOIFS(istream) ); } + /** + * This constructor loads a Word document from an InputStream. + * + * @param istream The InputStream that contains the Word document. + * @param password in char array format (can be null) + * @throws IOException If there is an unexpected IOException from the passed + * in InputStream. + * @since 6.0.0 + */ + public HWPFDocumentCore(InputStream istream, final char[] password) throws IOException { + //do Ole stuff + this( verifyAndBuildPOIFS(istream), password ); + } + /** * This constructor loads a Word document from a POIFSFileSystem * @@ -171,6 +187,19 @@ public HWPFDocumentCore(POIFSFileSystem pfilesystem) throws IOException { this(pfilesystem.getRoot()); } + /** + * This constructor loads a Word document from a POIFSFileSystem + * + * @param pfilesystem The POIFSFileSystem that contains the Word document. + * @param password in char array format (can be null) + * @throws IOException If there is an unexpected IOException from the passed + * in POIFSFileSystem. + * @since 6.0.0 + */ + public HWPFDocumentCore(POIFSFileSystem pfilesystem, final char[] password) throws IOException { + this(pfilesystem.getRoot(), password); + } + /** * This constructor loads a Word document from a specific point * in a POIFSFileSystem, probably not the default. @@ -181,8 +210,24 @@ public HWPFDocumentCore(POIFSFileSystem pfilesystem) throws IOException { * in POIFSFileSystem. */ public HWPFDocumentCore(DirectoryNode directory) throws IOException { + this(directory, null); + } + + /** + * This constructor loads a Word document from a specific point + * in a POIFSFileSystem, probably not the default. + * Used typically to open embedded documents. + * + * @param directory The DirectoryNode that contains the Word document. + * @param password in char array format (can be null) + * @throws IOException If there is an unexpected IOException from the passed + * in POIFSFileSystem. + * @since 6.0.0 + */ + public HWPFDocumentCore(DirectoryNode directory, final char[] password) throws IOException { // Sort out the hpsf properties super(directory); + _password = password; // read in the main stream. _mainStream = getDocumentEntryBytes(STREAM_WORD_DOCUMENT, FIB_BASE_LEN, Integer.MAX_VALUE); @@ -198,6 +243,7 @@ public HWPFDocumentCore(DirectoryNode directory) throws IOException { } _objectPool = new ObjectPoolImpl(objectPoolEntry); } + /** * Returns the range which covers the whole of the document, but excludes * any headers and footers. @@ -292,12 +338,13 @@ public EncryptionInfo getEncryptionInfo() throws IOException { } dec.setChunkSize(RC4_REKEYING_INTERVAL); try { - String pass = Biff8EncryptionKey.getCurrentUserPassword(); + String pass = _password == null + ? Biff8EncryptionKey.getCurrentUserPassword() : new String(_password); if (pass == null) { pass = Decryptor.DEFAULT_PASSWORD; } if (!dec.verifyPassword(pass)) { - throw new EncryptedDocumentException("document is encrypted, password is invalid - use Biff8EncryptionKey.setCurrentUserPasswort() to set password before opening"); + throw new EncryptedDocumentException("document is encrypted, password is invalid - use constructor to set the password"); } } catch (GeneralSecurityException e) { throw new IOException(e.getMessage(), e); @@ -310,7 +357,8 @@ protected void updateEncryptionInfo() { // make sure, that we've read all the streams ... readProperties(); // now check for the password - String password = Biff8EncryptionKey.getCurrentUserPassword(); + String password = _password == null + ? Biff8EncryptionKey.getCurrentUserPassword() : new String(_password); FibBase fBase = _fib.getFibBase(); if (password == null) { fBase.setLKey(0);