mirror of
https://github.com/SabreTools/SabreTools.Serialization.git
synced 2026-11-15 17:00:38 +00:00
Look for the Wise overlay header before opening the file again (#103)
ExtractWiseOverlay (and ExtractWise for NE) opened a second stream on the executable for multi-part Wise installers before checking for a Wise overlay header at all. For any other executable that stream was never closed, so the file stayed open until the stream was finalized. On Windows such a file cannot be deleted, so an extraction folder that contains it is left behind in TEMP. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -56,5 +56,32 @@ namespace SabreTools.Wrappers.Test
|
||||
var actual = PortableExecutable.Create(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExtractWiseOverlay_NotWise_FileNotKeptOpen()
|
||||
{
|
||||
// Any executable that is not a Wise installer, here a copy of this test assembly
|
||||
string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
|
||||
string outputDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
|
||||
File.Copy(typeof(PortableExecutableTests).Assembly.Location, path);
|
||||
|
||||
try
|
||||
{
|
||||
using (var stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
{
|
||||
var pe = PortableExecutable.Create(stream);
|
||||
Assert.NotNull(pe);
|
||||
Assert.False(pe.ExtractWiseOverlay(outputDirectory, includeDebug: false));
|
||||
}
|
||||
|
||||
// Opening the file exclusively fails while another handle to it is still open
|
||||
using var exclusive = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None);
|
||||
Assert.True(exclusive.CanRead);
|
||||
}
|
||||
finally
|
||||
{
|
||||
File.Delete(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,6 +208,11 @@ namespace SabreTools.Wrappers
|
||||
/// <returns>True if extraction succeeded, false otherwise</returns>
|
||||
public bool ExtractWise(string outputDirectory, bool includeDebug)
|
||||
{
|
||||
// Try to find the overlay header
|
||||
long offset = FindWiseOverlayHeader();
|
||||
if (offset <= 0 || offset >= Length)
|
||||
return false;
|
||||
|
||||
// Get the source data for reading
|
||||
Stream source = _dataSource;
|
||||
if (Filename is not null)
|
||||
@@ -217,13 +222,7 @@ namespace SabreTools.Wrappers
|
||||
source = temp;
|
||||
}
|
||||
|
||||
// Try to find the overlay header
|
||||
long offset = FindWiseOverlayHeader();
|
||||
if (offset > 0 && offset < Length)
|
||||
return ExtractWiseOverlay(outputDirectory, includeDebug, source, offset);
|
||||
|
||||
// Everything else could not extract
|
||||
return false;
|
||||
return ExtractWiseOverlay(outputDirectory, includeDebug, source, offset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -638,6 +638,11 @@ namespace SabreTools.Wrappers
|
||||
/// <returns>True if extraction succeeded, false otherwise</returns>
|
||||
public bool ExtractWiseOverlay(string outputDirectory, bool includeDebug)
|
||||
{
|
||||
// Try to find the overlay header
|
||||
long offset = FindWiseOverlayHeader();
|
||||
if (offset <= 0 || offset > Length)
|
||||
return false;
|
||||
|
||||
// Get the source data for reading
|
||||
Stream source = _dataSource;
|
||||
if (Filename is not null)
|
||||
@@ -647,11 +652,6 @@ namespace SabreTools.Wrappers
|
||||
source = temp;
|
||||
}
|
||||
|
||||
// Try to find the overlay header
|
||||
long offset = FindWiseOverlayHeader();
|
||||
if (offset <= 0 || offset > Length)
|
||||
return false;
|
||||
|
||||
// Seek to the overlay and parse
|
||||
source.SeekIfPossible(offset, SeekOrigin.Begin);
|
||||
var header = WiseOverlayHeader.Create(source);
|
||||
|
||||
Reference in New Issue
Block a user