Skip to content

Commit 5390c30

Browse files
Add and use FileFormatException
1 parent 850fbdc commit 5390c30

14 files changed

+61
-46
lines changed

OpenMcdf.Tests/BinaryReaderTests.cs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,31 +39,26 @@ public void ReadHeader(string fileName)
3939

4040
stream.CopyAllTo(memoryStream);
4141
memoryStream.WriteByte(1); // Corrupt signature
42-
Assert.ThrowsException<FormatException>(() => reader.ReadHeader());
42+
Assert.ThrowsException<FileFormatException>(() => reader.ReadHeader());
4343

4444
stream.CopyAllTo(memoryStream);
4545
memoryStream.Position = 24;
4646
memoryStream.WriteByte(1); // Corrupt CLSID
47-
Assert.ThrowsException<FormatException>(() => reader.ReadHeader());
47+
Assert.ThrowsException<FileFormatException>(() => reader.ReadHeader());
4848

4949
stream.CopyAllTo(memoryStream);
5050
memoryStream.Position = 26;
5151
memoryStream.WriteByte(1); // Corrupt Major version
52-
Assert.ThrowsException<FormatException>(() => reader.ReadHeader());
52+
Assert.ThrowsException<FileFormatException>(() => reader.ReadHeader());
5353

5454
stream.CopyAllTo(memoryStream);
5555
memoryStream.Position = 28;
5656
memoryStream.WriteByte(1); // Corrupt byte order
57-
Assert.ThrowsException<FormatException>(() => reader.ReadHeader());
57+
Assert.ThrowsException<FileFormatException>(() => reader.ReadHeader());
5858

5959
stream.CopyAllTo(memoryStream);
6060
memoryStream.Position = 32;
6161
memoryStream.WriteByte(1); // Corrupt mini sector shift
62-
Assert.ThrowsException<FormatException>(() => reader.ReadHeader());
63-
64-
stream.CopyAllTo(memoryStream);
65-
memoryStream.Position = 32;
66-
memoryStream.WriteByte(1); // Corrupt mini sector shift
67-
Assert.ThrowsException<FormatException>(() => reader.ReadHeader());
62+
Assert.ThrowsException<FileFormatException>(() => reader.ReadHeader());
6863
}
6964
}

OpenMcdf/CfbBinaryReader.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,19 +73,19 @@ public Header ReadHeader()
7373
ReadExactly(buffer, 0, Header.Signature.Length);
7474
Span<byte> signature = buffer.AsSpan(0, Header.Signature.Length);
7575
if (!signature.SequenceEqual(Header.Signature))
76-
throw new FormatException("Invalid header signature.");
76+
throw new FileFormatException("Invalid header signature.");
7777
header.CLSID = ReadGuid();
7878
if (header.CLSID != Guid.Empty)
79-
throw new FormatException($"Invalid header CLSID: {header.CLSID}.");
79+
throw new FileFormatException($"Invalid header CLSID: {header.CLSID}.");
8080
header.MinorVersion = ReadUInt16();
8181
header.MajorVersion = ReadUInt16();
8282
if (header.MajorVersion is not (ushort)Version.V3 and not (ushort)Version.V4)
83-
throw new FormatException($"Unsupported major version: {header.MajorVersion}.");
83+
throw new FileFormatException($"Unsupported major version: {header.MajorVersion}.");
8484
else if (header.MinorVersion is not Header.ExpectedMinorVersion)
8585
Trace.WriteLine($"Unexpected minor version: {header.MinorVersion}.");
8686
ushort byteOrder = ReadUInt16();
8787
if (byteOrder != Header.LittleEndian)
88-
throw new FormatException($"Unsupported byte order: {byteOrder:X4}. Only little-endian is supported ({Header.LittleEndian:X4}).");
88+
throw new FileFormatException($"Unsupported byte order: {byteOrder:X4}. Only little-endian is supported ({Header.LittleEndian:X4}).");
8989
header.SectorShift = ReadUInt16();
9090
header.MiniSectorShift = ReadUInt16();
9191
FillBuffer(6);
@@ -95,7 +95,7 @@ public Header ReadHeader()
9595
FillBuffer(4);
9696
uint miniStreamCutoffSize = ReadUInt32();
9797
if (miniStreamCutoffSize != Header.MiniStreamCutoffSize)
98-
throw new FormatException($"Mini stream cutoff size must be {Header.MiniStreamCutoffSize} bytes.");
98+
throw new FileFormatException($"Mini stream cutoff size must be {Header.MiniStreamCutoffSize} bytes.");
9999
header.FirstMiniFatSectorId = ReadUInt32();
100100
header.MiniFatSectorCount = ReadUInt32();
101101
header.FirstDifatSectorId = ReadUInt32();
@@ -113,15 +113,15 @@ public StorageType ReadStorageType()
113113
{
114114
var type = (StorageType)ReadByte();
115115
if (type is not StorageType.Storage and not StorageType.Stream and not StorageType.Root and not StorageType.Unallocated)
116-
throw new FormatException($"Invalid storage type: {type}.");
116+
throw new FileFormatException($"Invalid storage type: {type}.");
117117
return type;
118118
}
119119

120120
public NodeColor ReadColor()
121121
{
122122
var color = (NodeColor)ReadByte();
123123
if (color is not NodeColor.Black and not NodeColor.Red)
124-
throw new FormatException($"Invalid node color: {color}.");
124+
throw new FileFormatException($"Invalid node color: {color}.");
125125
return color;
126126
}
127127

@@ -154,7 +154,7 @@ public DirectoryEntry ReadDirectoryEntry(Version version, uint sid)
154154
{
155155
entry.StreamLength = ReadUInt32();
156156
if (entry.StreamLength > DirectoryEntry.MaxV3StreamLength)
157-
throw new FormatException($"Stream length {entry.StreamLength} exceeds maximum value {DirectoryEntry.MaxV3StreamLength}.");
157+
throw new FileFormatException($"Stream length {entry.StreamLength} exceeds maximum value {DirectoryEntry.MaxV3StreamLength}.");
158158
ReadUInt32(); // Skip unused 4 bytes
159159
}
160160
else if (version == Version.V4)

OpenMcdf/DifatSectorEnumerator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public void Add()
105105
{
106106
bool ok = MoveTo(header.DifatSectorCount - 1);
107107
if (!ok)
108-
throw new InvalidOperationException("Failed to move to last DIFAT sector.");
108+
throw new FileFormatException("The DIFAT sector count is invalid.");
109109

110110
writer.Position = current.EndPosition - sizeof(uint);
111111
writer.Write(newDifatSector.Id);

OpenMcdf/DirectoryEntries.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public bool TryGetDictionaryEntry(uint streamId, out DirectoryEntry? entry)
4040
}
4141

4242
if (streamId > StreamId.Maximum)
43-
throw new ArgumentException($"Invalid directory entry stream ID: ${streamId:X8}.", nameof(streamId));
43+
throw new FileFormatException($"Invalid directory entry stream ID: ${streamId:X8}.");
4444

4545
uint chainIndex = GetChainIndexAndEntryIndex(streamId, out long entryIndex);
4646
if (!fatChainEnumerator.MoveTo(chainIndex))

OpenMcdf/DirectoryEntry.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ public void Recycle(StorageType storageType, string name)
224224
StorageType.Stream => EntryType.Stream,
225225
StorageType.Storage => EntryType.Storage,
226226
StorageType.Root => EntryType.Storage,
227-
_ => throw new InvalidOperationException("Invalid storage type.")
227+
_ => throw new FileFormatException($"Invalid storage type: {Type}.")
228228
};
229229

230230
public EntryInfo ToEntryInfo(string path) => new(EntryType, path, NameString, StreamLength, CLSID, CreationTime, ModifiedTime);

OpenMcdf/DirectoryTree.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public bool TryGetDirectoryEntry(string name, out DirectoryEntry? entry)
4343
{
4444
compare = DirectoryEntryComparer.Compare(leftChild.NameCharSpan, child.NameCharSpan);
4545
if (compare >= 0)
46-
throw new FormatException("Directory tree is not sorted.");
46+
throw new FileFormatException("Directory tree is not sorted.");
4747
}
4848

4949
child = leftChild;
@@ -55,7 +55,7 @@ public bool TryGetDirectoryEntry(string name, out DirectoryEntry? entry)
5555
{
5656
compare = DirectoryEntryComparer.Compare(rightChild.NameCharSpan, child.NameCharSpan);
5757
if (compare <= 0)
58-
throw new FormatException("Directory tree is not sorted.");
58+
throw new FileFormatException("Directory tree is not sorted.");
5959
}
6060

6161
child = rightChild;

OpenMcdf/Fat.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,17 +190,17 @@ internal void Validate()
190190
{
191191
Sector sector = new(entry.Index, Context.SectorSize);
192192
if (entry.Value <= SectorType.Maximum && sector.EndPosition > Context.Length)
193-
throw new FormatException($"FAT entry {entry} is beyond the end of the stream.");
193+
throw new FileFormatException($"FAT entry {entry} is beyond the end of the stream.");
194194
if (entry.Value == SectorType.Fat)
195195
fatSectorCount++;
196196
if (entry.Value == SectorType.Difat)
197197
difatSectorCount++;
198198
}
199199

200200
if (Context.Header.FatSectorCount != fatSectorCount)
201-
throw new FormatException($"FAT sector count mismatch. Expected: {Context.Header.FatSectorCount} Actual: {fatSectorCount}.");
201+
throw new FileFormatException($"FAT sector count mismatch. Expected: {Context.Header.FatSectorCount} Actual: {fatSectorCount}.");
202202
if (Context.Header.DifatSectorCount != difatSectorCount)
203-
throw new FormatException($"DIFAT sector count mismatch: Expected: {Context.Header.DifatSectorCount} Actual: {difatSectorCount}.");
203+
throw new FileFormatException($"DIFAT sector count mismatch: Expected: {Context.Header.DifatSectorCount} Actual: {difatSectorCount}.");
204204
}
205205

206206
[ExcludeFromCodeCoverage]

OpenMcdf/FatStream.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public override int Read(byte[] buffer, int offset, int count)
8989

9090
uint chainIndex = GetFatChainIndexAndSectorOffset(position, out long sectorOffset);
9191
if (!chain.MoveTo(chainIndex))
92-
throw new FormatException($"The FAT chain was shorter than the stream length.");
92+
throw new FileFormatException($"The FAT chain was shorter than the stream length.");
9393

9494
int realCount = Math.Min(count, maxCount);
9595
int readCount = 0;
@@ -109,7 +109,7 @@ public override int Read(byte[] buffer, int offset, int count)
109109
if (readCount >= realCount)
110110
return readCount;
111111
if (!chain.MoveNext())
112-
throw new FormatException($"The FAT chain was shorter than the stream length.");
112+
throw new FileFormatException($"The FAT chain was shorter than the stream length.");
113113
};
114114
}
115115

@@ -215,7 +215,7 @@ public override int Read(Span<byte> buffer)
215215

216216
uint chainIndex = GetFatChainIndexAndSectorOffset(position, out long sectorOffset);
217217
if (!chain.MoveTo(chainIndex))
218-
throw new FormatException($"The FAT chain was shorter than the stream length.");
218+
throw new FileFormatException($"The FAT chain was shorter than the stream length.");
219219

220220
int realCount = Math.Min(buffer.Length, maxCount);
221221
int readCount = 0;
@@ -236,7 +236,7 @@ public override int Read(Span<byte> buffer)
236236
if (readCount >= realCount)
237237
return readCount;
238238
if (!chain.MoveNext())
239-
throw new FormatException($"The FAT chain was shorter than the stream length.");
239+
throw new FileFormatException($"The FAT chain was shorter than the stream length.");
240240
}
241241
}
242242

OpenMcdf/FileFormatException.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
namespace OpenMcdf;
2+
3+
/// <summary>
4+
/// The exception that is thrown when an compound file data stream contains invalid data.
5+
/// </summary>
6+
public class FileFormatException : FormatException
7+
{
8+
public FileFormatException()
9+
{
10+
}
11+
12+
public FileFormatException(string message) : base(message)
13+
{
14+
}
15+
16+
public FileFormatException(string message, Exception innerException) : base(message, innerException)
17+
{
18+
}
19+
}

OpenMcdf/Header.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public ushort MajorVersion
4444
get => majorVersion; set
4545
{
4646
if (value is not 3 and not 4)
47-
throw new FormatException($"Unsupported major version: {value}. Only 3 and 4 are supported");
47+
throw new FileFormatException($"Unsupported major version: {value}. Only 3 and 4 are supported");
4848
majorVersion = value;
4949
}
5050
}
@@ -57,9 +57,9 @@ public ushort SectorShift
5757
get => sectorShift; set
5858
{
5959
if (MajorVersion == 3 && value != SectorShiftV3)
60-
throw new FormatException($"Unsupported sector shift {value:X4}. Only {SectorShiftV3:X4} is supported for Major Version 3.");
60+
throw new FileFormatException($"Unsupported sector shift {value:X4}. Only {SectorShiftV3:X4} is supported for Major Version 3.");
6161
if (MajorVersion == 4 && value != SectorShiftV4)
62-
throw new FormatException($"Unsupported sector shift {value:X4}. Only {SectorShiftV4:X4} is supported for Major Version 4.");
62+
throw new FileFormatException($"Unsupported sector shift {value:X4}. Only {SectorShiftV4:X4} is supported for Major Version 4.");
6363

6464
sectorShift = value;
6565
}
@@ -71,7 +71,7 @@ public ushort MiniSectorShift
7171
set
7272
{
7373
if (value != ExpectedMiniSectorShift)
74-
throw new FormatException($"Unsupported sector shift {value:X4}. Only {ExpectedMiniSectorShift:X4} is supported.");
74+
throw new FileFormatException($"Unsupported sector shift {value:X4}. Only {ExpectedMiniSectorShift:X4} is supported.");
7575

7676
miniSectorShift = value;
7777
}
@@ -130,7 +130,7 @@ public Header(Version version = Version.V3)
130130
{
131131
Version.V3 => SectorShiftV3,
132132
Version.V4 => SectorShiftV4,
133-
_ => throw new FormatException($"Unsupported version: {version}.")
133+
_ => throw new FileFormatException($"Unsupported version: {version}.")
134134
};
135135
FirstDirectorySectorId = SectorType.EndOfChain;
136136
DirectorySectorCount = 0; // Not used in v3

0 commit comments

Comments
 (0)