AquaLower names lowered .dsp files through StoreFileName; pin Windows forms; note limits
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
30b926c776
commit
5a77dc8e83
3 changed files with 35 additions and 2 deletions
|
|
@ -13,6 +13,11 @@ namespace AquaSynth.Dsl;
|
|||
/// rewritten names always do, so the two sets cannot meet; distinct ids stay distinct up to a 64-bit
|
||||
/// hash. The result is never a path: no separators, never "." or "..".
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Not handled: symlinks and junctions already inside a store are followed, and Windows 8.3 short names
|
||||
/// were not verified. An id with an uppercase letter is rewritten, so a batch directory named for such
|
||||
/// an id gains a hash suffix.
|
||||
/// </remarks>
|
||||
public static class StoreFileName
|
||||
{
|
||||
private const int MaxStem = 100;
|
||||
|
|
|
|||
|
|
@ -160,6 +160,33 @@ public sealed class StoreFileNameTests
|
|||
Assert.Equal(Path.GetFullPath(root), Path.GetDirectoryName(full));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("\\\\host\\share\\x")]
|
||||
[InlineData("C:x")]
|
||||
[InlineData("a:b")]
|
||||
[InlineData("x.")]
|
||||
[InlineData("x ")]
|
||||
[InlineData("x. ")]
|
||||
public void WindowsAbsoluteAndTrailingDotOrSpaceIdsStayContainedAndPlain(string id)
|
||||
{
|
||||
var root = Path.Combine(Path.GetTempPath(), "artifact-root-probe", "artifacts");
|
||||
var name = StoreFileName.From(id);
|
||||
Assert.Matches("^[A-Za-z0-9._-]+$", name);
|
||||
Assert.False(name.EndsWith('.') || name.EndsWith(' '));
|
||||
Assert.Equal(Path.GetFullPath(root), Path.GetDirectoryName(Path.GetFullPath(StoreFileName.Combine(root, id))));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("../x")]
|
||||
[InlineData("a/b")]
|
||||
[InlineData("name:with:colons")]
|
||||
public void LoweredDspFileNameStaysInTheOutputDirectory(string name)
|
||||
{
|
||||
var outDir = Path.Combine(Path.GetTempPath(), "aqualower-probe", "out");
|
||||
var file = StoreFileName.From(name) + ".dsp";
|
||||
Assert.Equal(Path.GetFullPath(outDir), Path.GetDirectoryName(Path.GetFullPath(Path.Combine(outDir, file))));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BareDotDotBatchIdIsRefused() =>
|
||||
Assert.Throws<ArgumentException>(() => StoreFileName.Combine(Path.GetTempPath(), ".."));
|
||||
|
|
|
|||
|
|
@ -47,8 +47,9 @@ foreach (var spec in args.Skip(2))
|
|||
warnings.AddRange(export.Warnings);
|
||||
}
|
||||
else source = text;
|
||||
File.WriteAllText(Path.Combine(outDir, name + ".dsp"), source);
|
||||
entries.Add(new { name, origin = rel.Replace('\\', '/'), kind = path.EndsWith(".aqua", StringComparison.Ordinal) ? "aqua" : "faust", dsp = name + ".dsp", warnings });
|
||||
var dspFile = StoreFileName.From(name) + ".dsp";
|
||||
File.WriteAllText(Path.Combine(outDir, dspFile), source);
|
||||
entries.Add(new { name, origin = rel.Replace('\\', '/'), kind = path.EndsWith(".aqua", StringComparison.Ordinal) ? "aqua" : "faust", dsp = dspFile, warnings });
|
||||
Console.WriteLine($"{name}: {source.Length} chars from {rel}, {warnings.Count} warnings");
|
||||
}
|
||||
File.WriteAllText(Path.Combine(outDir, "catalog.json"), JsonSerializer.Serialize(entries, new JsonSerializerOptions { WriteIndented = true }));
|
||||
|
|
|
|||
Loading…
Reference in a new issue