Replace invalid filename characters in Wise dialog names (#106)

The file of a custom dialog is named after the dialog name from the
script, which is free text. On Windows, a name like "Install under NT?"
is not a valid filename, so writing the file threw an IOException and
stopped the extraction.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
gmipf
2026-10-26 02:32:34 +01:00
committed by GitHub
parent dc18951d0b
commit 373cf2d752
2 changed files with 46 additions and 0 deletions

View File

@@ -1,5 +1,8 @@
using System.IO;
using System.Linq;
using SabreTools.Data.Models.WiseInstaller;
using SabreTools.Data.Models.WiseInstaller.Actions;
using SabreTools.IO.Compression.Deflate;
using Xunit;
namespace SabreTools.Wrappers.Test
@@ -56,5 +59,42 @@ namespace SabreTools.Wrappers.Test
var actual = WiseOverlayHeader.Create(data);
Assert.Null(actual);
}
#region ExtractFile
[Fact]
public void ExtractFile_CustomDialogSet_InvalidFilenameCharacters()
{
// Deflated "Install under NT?" followed by its CRC-32
byte[] data =
[
0xF3, 0xCC, 0x2B, 0x2E, 0x49, 0xCC, 0xC9, 0x51, 0x28, 0xCD, 0x4B, 0x49,
0x2D, 0x52, 0xF0, 0x0B, 0xB1, 0x07, 0x00, 0x74, 0x09, 0x90, 0x8A,
];
var header = new WiseOverlayHeader(new OverlayHeader(), new MemoryStream(data));
var obj = new CustomDialogSet
{
DeflateStart = 0,
DeflateEnd = (uint)data.Length,
InflatedSize = 17,
DisplayVariable = "DISPLAY",
Name = "Install under NT?",
};
string outputDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
Directory.CreateDirectory(outputDirectory);
try
{
var actual = header.ExtractFile(obj, outputDirectory, includeDebug: false);
Assert.Equal(ExtractionStatus.GOOD, actual);
Assert.Single(Directory.GetFiles(outputDirectory));
}
finally
{
Directory.Delete(outputDirectory, recursive: true);
}
}
#endregion
}
}

View File

@@ -200,6 +200,12 @@ namespace SabreTools.Wrappers
string filename = $"CustomDialogSet_{obj.DisplayVariable}-{obj.Name}";
filename = filename.Replace("%", string.Empty);
// The dialog name is free text, so replace characters that are invalid in a filename
foreach (char invalid in Path.GetInvalidFileNameChars())
{
filename = filename.Replace(invalid, '_');
}
lock (_dataSourceLock)
{
_dataSource.SeekIfPossible(InstallerDataOffset + obj.DeflateStart, SeekOrigin.Begin);