From ab28948744f0114e5053d3b0321f0e37990db7c1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 2 Nov 2021 13:17:21 +0900 Subject: [PATCH 1/3] Default legacy decoder to `General` section, rather than none This is mainly to reach parity with how stable handles such cases for skins specifically. It was brought to our attention after finding a skin with a malformed `\[General]` tag which did not break further parsing of the file on stable, but did on lazer. Note that stable defaults to an "unknown" section for beatmaps, but functionally I can't think of a regression case from changing this to a "general" default. --- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index 56525ddb14..f17366a1b3 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -27,7 +27,7 @@ namespace osu.Game.Beatmaps.Formats protected override void ParseStreamInto(LineBufferedReader stream, T output) { - Section section = Section.None; + Section section = Section.General; string line; From 15c770e155c8396c4a4b2413be3acc1362471193 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 2 Nov 2021 14:01:41 +0900 Subject: [PATCH 2/3] Remove no longer used `Section.None` --- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index f17366a1b3..0276abc3ff 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -47,10 +47,7 @@ namespace osu.Game.Beatmaps.Formats if (line.StartsWith('[') && line.EndsWith(']')) { if (!Enum.TryParse(line[1..^1], out section)) - { Logger.Log($"Unknown section \"{line}\" in \"{output}\""); - section = Section.None; - } OnBeginNewSection(section); continue; @@ -148,7 +145,6 @@ namespace osu.Game.Beatmaps.Formats protected enum Section { - None, General, Editor, Metadata, From d4be6fc79761a984f812221a754e29c2afb97651 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 2 Nov 2021 14:04:25 +0900 Subject: [PATCH 3/3] Add test coverage of skin with missing section header --- osu.Game.Tests/Skins/IO/ImportSkinTest.cs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Skins/IO/ImportSkinTest.cs b/osu.Game.Tests/Skins/IO/ImportSkinTest.cs index c75714032e..ecc9c92025 100644 --- a/osu.Game.Tests/Skins/IO/ImportSkinTest.cs +++ b/osu.Game.Tests/Skins/IO/ImportSkinTest.cs @@ -38,6 +38,15 @@ namespace osu.Game.Tests.Skins.IO assertCorrectMetadata(import1, "test skin [skin]", "skinner", osu); }); + [Test] + public Task TestSingleImportMissingSectionHeader() => runSkinTest(async osu => + { + var import1 = await loadSkinIntoOsu(osu, new ZipArchiveReader(createOskWithIni("test skin", "skinner", includeSectionHeader: false), "skin.osk")); + + // When the import filename doesn't match, it should be appended (and update the skin.ini). + assertCorrectMetadata(import1, "test skin [skin]", "skinner", osu); + }); + [Test] public Task TestSingleImportMatchingFilename() => runSkinTest(async osu => { @@ -199,21 +208,23 @@ namespace osu.Game.Tests.Skins.IO return zipStream; } - private MemoryStream createOskWithIni(string name, string author, bool makeUnique = false, string iniFilename = @"skin.ini") + private MemoryStream createOskWithIni(string name, string author, bool makeUnique = false, string iniFilename = @"skin.ini", bool includeSectionHeader = true) { var zipStream = new MemoryStream(); using var zip = ZipArchive.Create(); - zip.AddEntry(iniFilename, generateSkinIni(name, author, makeUnique)); + zip.AddEntry(iniFilename, generateSkinIni(name, author, makeUnique, includeSectionHeader)); zip.SaveTo(zipStream); return zipStream; } - private MemoryStream generateSkinIni(string name, string author, bool makeUnique = true) + private MemoryStream generateSkinIni(string name, string author, bool makeUnique = true, bool includeSectionHeader = true) { var stream = new MemoryStream(); var writer = new StreamWriter(stream); - writer.WriteLine("[General]"); + if (includeSectionHeader) + writer.WriteLine("[General]"); + writer.WriteLine($"Name: {name}"); writer.WriteLine($"Author: {author}");