From 2d2b3b4ae0795594780c0c5a39a554da7aefa4a4 Mon Sep 17 00:00:00 2001 From: Erik Larsson Date: Fri, 9 Jan 2015 06:56:25 +0100 Subject: [PATCH] Check volume header signature when creating HFSVolume derivates. This sanity check prevents us from accidentally loading the wrong HFS type. Helps us to catch errors early. --- .../hfs/original/HFSOriginalVolume.java | 11 ++++++++++- .../org/catacombae/hfs/plus/HFSPlusVolume.java | 17 +++++++++++++++-- src/java/org/catacombae/hfs/x/HFSXVolume.java | 3 ++- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/java/org/catacombae/hfs/original/HFSOriginalVolume.java b/src/java/org/catacombae/hfs/original/HFSOriginalVolume.java index f12fc434..75806a00 100644 --- a/src/java/org/catacombae/hfs/original/HFSOriginalVolume.java +++ b/src/java/org/catacombae/hfs/original/HFSOriginalVolume.java @@ -63,13 +63,22 @@ public HFSOriginalVolume(ReadableRandomAccessStream hfsFile, super(hfsFile, cachingEnabled); + final MasterDirectoryBlock mdb = getHFSMasterDirectoryBlock(); + if(mdb.getDrSigWord() != MasterDirectoryBlock.SIGNATURE_HFS) { + throw new RuntimeException("Invalid volume header signature " + + "(expected: 0x" + + Util.toHexStringBE(MasterDirectoryBlock.SIGNATURE_HFS) + + " actual: 0x" + Util.toHexStringBE(mdb.getDrSigWord()) + + ")."); + } + this.stringCodec = new MutableStringCodec( new CharsetStringCodec(encodingName)); this.allocationFile = createAllocationFile(); } - public MasterDirectoryBlock getHFSMasterDirectoryBlock() { + public final MasterDirectoryBlock getHFSMasterDirectoryBlock() { byte[] currentBlock = new byte[512]; hfsFile.readFrom(1024, currentBlock); return new MasterDirectoryBlock(currentBlock, 0); diff --git a/src/java/org/catacombae/hfs/plus/HFSPlusVolume.java b/src/java/org/catacombae/hfs/plus/HFSPlusVolume.java index 1bb4345c..04e0c87a 100644 --- a/src/java/org/catacombae/hfs/plus/HFSPlusVolume.java +++ b/src/java/org/catacombae/hfs/plus/HFSPlusVolume.java @@ -65,13 +65,26 @@ public class HFSPlusVolume extends HFSVolume { public HFSPlusVolume(ReadableRandomAccessStream hfsFile, boolean cachingEnabled) { + this(hfsFile, cachingEnabled, HFSPlusVolumeHeader.SIGNATURE_HFS_PLUS); + } + protected HFSPlusVolume(ReadableRandomAccessStream hfsFile, + boolean cachingEnabled, short volumeHeaderSignature) + { super(hfsFile, cachingEnabled); + final HFSPlusVolumeHeader volumeHeader = getHFSPlusVolumeHeader(); + if(volumeHeader.getSignature() != volumeHeaderSignature) { + throw new RuntimeException("Invalid volume header signature " + + "(expected: 0x" + + Util.toHexStringBE(volumeHeaderSignature) + " actual: 0x" + + Util.toHexStringBE(volumeHeader.getSignature()) + ")."); + } + this.allocationFile = createAllocationFile(); this.journal = new HFSPlusJournal(this); - if(getHFSPlusVolumeHeader().getAttributesFile().getExtents(). + if(volumeHeader.getAttributesFile().getExtents(). getExtentDescriptors()[0].getBlockCount() == 0) { /* TODO: Is this even valid? */ @@ -86,7 +99,7 @@ SynchronizedReadableRandomAccess getBackingStream() { return hfsFile; } - public HFSPlusVolumeHeader getHFSPlusVolumeHeader() { + public final HFSPlusVolumeHeader getHFSPlusVolumeHeader() { //System.err.println("getHFSPlusVolumeHeader()"); byte[] currentBlock = new byte[512]; //System.err.println(" hfsFile.seek(" + (fsOffset + 1024) + ")"); diff --git a/src/java/org/catacombae/hfs/x/HFSXVolume.java b/src/java/org/catacombae/hfs/x/HFSXVolume.java index 2c9cdfb7..ded80a32 100644 --- a/src/java/org/catacombae/hfs/x/HFSXVolume.java +++ b/src/java/org/catacombae/hfs/x/HFSXVolume.java @@ -30,6 +30,7 @@ import org.catacombae.hfs.types.hfsx.HFSXCatalogKey; import org.catacombae.io.ReadableRandomAccessStream; import org.catacombae.hfs.plus.HFSPlusVolume; +import org.catacombae.hfs.types.hfsplus.HFSPlusVolumeHeader; /** * @author Erik Larsson @@ -40,7 +41,7 @@ public class HFSXVolume extends HFSPlusVolume { public HFSXVolume(ReadableRandomAccessStream hfsFile, boolean cachingEnabled) { - super(hfsFile, cachingEnabled); + super(hfsFile, cachingEnabled, HFSPlusVolumeHeader.SIGNATURE_HFSX); CommonBTHeaderRecord.CompareType keyCompareTypeEnum = getCatalogFile().getCatalogHeaderNode().getHeaderRecord().