Stop writing after the last file of a cabinet folder (#107)

* Stop writing after the last file of a cabinet folder

When the last data block of a folder held the end of two or more files,
WriteData still wrote the rest of the block after EndFile had closed the
last file, which threw an ObjectDisposedException. It now returns there,
as it already does when the first file in a block ends the folder.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Simplify the console check in the cabinet extraction test

Extract catches the ObjectDisposedException and only writes it to
Console.Error, so the test still reads the console, but without the
try/finally. It now fails with the whole exception as its message.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
gmipf
2026-10-26 14:46:10 +01:00
committed by GitHub
parent 373cf2d752
commit 11f9bf9fd9
3 changed files with 29 additions and 1 deletions

View File

@@ -1,3 +1,4 @@
using System;
using System.IO;
using System.Linq;
using Xunit;
@@ -56,5 +57,32 @@ namespace SabreTools.Wrappers.Test
var actual = MicrosoftCabinet.Create(data);
Assert.Null(actual);
}
#region Extract
[Fact]
public void Extract_LastBlockEndsTwoFiles()
{
// One MS-ZIP block that holds both files
string path = Path.Combine(Environment.CurrentDirectory, "TestData", "MicrosoftCabinet", "mszip.cab");
var cabinet = MicrosoftCabinet.Create(File.ReadAllBytes(path), 0);
Assert.NotNull(cabinet);
// Extract catches the exception and only writes it to the console
string outputDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
var originalError = Console.Error;
var error = new StringWriter();
Console.SetError(error);
cabinet.Extract(outputDirectory, includeDebug: true);
Console.SetError(originalError);
// Assert.True shows the whole exception, Assert.Empty cuts it off
Assert.True(error.ToString().Length == 0, error.ToString());
Assert.Equal("Hello, ", File.ReadAllText(Path.Combine(outputDirectory, "a.txt")));
Assert.Equal("World!", File.ReadAllText(Path.Combine(outputDirectory, "b.txt")));
Directory.Delete(outputDirectory, recursive: true);
}
#endregion
}
}

View File

@@ -548,7 +548,7 @@ namespace SabreTools.Wrappers
_fileStream.Write(data, (int)tempBytesLeft, (int)_bytesLeft);
tempBytesLeft += _bytesLeft;
if (EndFile(outputDirectory))
break;
return;
}
_fileStream.Write(data, (int)tempBytesLeft, data.Length - (int)tempBytesLeft);