Skip to content

Commit

Permalink
Handle changed hidBlockIndex structure in OST 2013 files
Browse files Browse the repository at this point in the history
  • Loading branch information
Jmcleodfoss committed Jul 22, 2020
1 parent 9b954a0 commit 336b799
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ static class UnknownFileFormatVersionException extends RuntimeException
} else {
throw new UnknownFileFormatVersionException(wVer);
}
HeapOnNode.HID.setOst2013(index);
}

/** Obtain a string describing this file format.
Expand Down
31 changes: 28 additions & 3 deletions pst/src/main/java/io/github/jmcleodfoss/pst/HeapOnNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,26 @@ public class HeapOnNode implements javax.swing.ListModel<Object>
{
/** The HID class is describes an index into the heap-on-node structure or a node (this is actually an HNID class).
* @see <a href="https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-pst/85b9e985-ea53-447f-b70c-eb82bfbdcbc9">MS-PST Section 2.3.1.1: HID</a>
* @see <a href="https://blog.mythicsoft.com/ost-2013-file-format-the-missing-documentation/">OST 2013 file format the missing documentation blog entry</a>
*/
static class HID extends NID
{
/** The HID for the root of a B-Tree-on-Heap */
/** Whether the file being processed is a OST-2013 file or not. */
static boolean fOst2013 = false;

/** How far right to shift the block index for ANSI and Unicode files.
* @see <a href="https://blog.mythicsoft.com/ost-2013-file-format-the-missing-documentation/">OST 2013 file format the missing documentation blog entry</a>
*/
static final int BLOCK_INDEX_RSHIFT = 0;

/** How far right to shift the block index for OST-2013 files.
* @see <a href="https://blog.mythicsoft.com/ost-2013-file-format-the-missing-documentation/">OST 2013 file format the missing documentation blog entry</a>
*/
static final int BLOCK_INDEX_RSHIFT_OST_2013 = 3;

/** The HID for the root of a B-Tree-on-Heap
* It's okay to call #factory before fOst2013 has been set since 0 is unaffected by shifting right.
*/
static final HID BTreeOnHeapRoot = factory(0, 0);

/** The size of an HID or HNID element, in bytes. */
Expand All @@ -34,7 +50,7 @@ static class HID extends NID
private HID(int blockIndex, int index)
{
super(NID.HID, (index << 16) | (blockIndex << 5));
this.blockIndex = blockIndex;
this.blockIndex = blockIndex >> (fOst2013 ? BLOCK_INDEX_RSHIFT_OST_2013 : BLOCK_INDEX_RSHIFT);
this.index = index + 1;
}

Expand All @@ -45,7 +61,7 @@ private HID(int blockIndex, int index)
{
super(rawData);
if (type == NID.HID) {
blockIndex = (short)(rawData >> 16) & 0xffff;
blockIndex = ((short)(rawData >> 16) & 0xffff) >> (fOst2013 ? 3 : 0);
index = (short)(rawData & 0xffff) >> 5;
} else {
index = 0;
Expand Down Expand Up @@ -80,6 +96,14 @@ boolean isHID()
return type == NID.HID && index != 0;
}

/** Set the flag indicating an OST 2013 file
* @param fileFormatIndex The index for the file format read in from the header.
*/
static void setOst2013(FileFormat.Index fileFormatIndex)
{
fOst2013 = fileFormatIndex == FileFormat.Index.OST_2013;
}

/** Obtain a description of this HID (typically used for debugging).
* @return A description of this HID.
*/
Expand Down Expand Up @@ -195,6 +219,7 @@ private Header(java.nio.ByteBuffer stream)
DataContainer dc = new DataContainer();
dc.read(stream, fields);
ibHnpm = 0xffff & (Short)dc.get(nm_ibHnpm);

byte blockSignature = (Byte)dc.get(nm_bSig);
if (blockSignature != HN_SIGNATURE && Options.strictHeapNodes)
throw new NotHeapNodeException(blockSignature);
Expand Down

0 comments on commit 336b799

Please sign in to comment.