diff --git a/OpenMcdf.Tests/OpenMcdf.Tests.csproj b/OpenMcdf.Tests/OpenMcdf.Tests.csproj
index 648240d..105120a 100644
--- a/OpenMcdf.Tests/OpenMcdf.Tests.csproj
+++ b/OpenMcdf.Tests/OpenMcdf.Tests.csproj
@@ -20,6 +20,7 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/OpenMcdf.Tests/RootStorageTests.cs b/OpenMcdf.Tests/RootStorageTests.cs
index 521eca8..f6350ed 100644
--- a/OpenMcdf.Tests/RootStorageTests.cs
+++ b/OpenMcdf.Tests/RootStorageTests.cs
@@ -1,4 +1,6 @@
-namespace OpenMcdf.Tests;
+using Microsoft.IO;
+
+namespace OpenMcdf.Tests;
[TestClass]
public sealed class RootStorageTests
@@ -231,4 +233,23 @@ public void DeleteTrimsBaseStream(bool consolidate)
Assert.IsTrue(originalLength > newLength);
}
+
+ [TestMethod]
+ [DoNotParallelize] // High memory usage
+ public void V3ThrowsIOExceptionAt2GB()
+ {
+ const long MaxStreamLength = 2L * 1024 * 1024 * 1024;
+
+ RecyclableMemoryStreamManager manager = new();
+ using RecyclableMemoryStream baseStream = new(manager);
+ baseStream.Capacity64 = MaxStreamLength;
+
+ using var rootStorage = RootStorage.Create(baseStream, Version.V3);
+ using CfbStream stream = rootStorage.CreateStream("Test");
+ byte[] buffer = TestData.CreateByteArray(1024 * 1024);
+ while (baseStream.Length + buffer.Length <= MaxStreamLength)
+ stream.Write(buffer, 0, buffer.Length);
+
+ Assert.ThrowsException(() => stream.Write(buffer, 0, buffer.Length));
+ }
}
diff --git a/OpenMcdf/RootContext.cs b/OpenMcdf/RootContext.cs
index b066534..0898897 100644
--- a/OpenMcdf/RootContext.cs
+++ b/OpenMcdf/RootContext.cs
@@ -16,6 +16,8 @@ enum IOContextFlags
///
internal sealed class RootContext : ContextBase, IDisposable
{
+ const long MaximumV3StreamLength = 2147483648;
+
readonly IOContextFlags contextFlags;
readonly CfbBinaryWriter? writer;
readonly TransactedStream? transactedStream;
@@ -185,6 +187,9 @@ public void Flush()
public void ExtendStreamLength(long length)
{
+ if (Version is Version.V3 && length > MaximumV3StreamLength)
+ throw new IOException("V3 compound files are limited to 2 GB.");
+
if (Length < length)
Length = length;
}