What's wrong
Section.TryParse (Semantics.Music/Section.cs ~L129) reads the header with Enum.TryParse<SectionType>(header[1..close], …). That call is too permissive for this header:
- It accepts any integer string and returns an undefined enum value.
- It accepts comma-separated names and ORs their values together, flags-style.
- It trims surrounding whitespace.
SectionType is a plain enum, so the first two cases produce wrong or undefined types.
Reproduction
Section.TryParse("[Verse, Chorus]\n4/4 C", out s) -> true, s.Type == Chorus (Verse=1 | Chorus=3 == 3)
Section.TryParse("[42]\n4/4 C", out s) -> true, s.Type == (SectionType)42
Arrangement.Parse goes through the same path. An undefined type then flows into IsSameStructure and Form.
Suggested fix / acceptance criteria
- Accept only a single, defined member name. Two ways to do that:
- require letters only, then call
Enum.TryParse and Enum.IsDefined
- look the name up in
Enum.GetNames
- Keep matching case-sensitive as it is today, since
ToString emits the exact member name.
- Tests:
[Verse, Chorus], [42], [ Verse ] and [-1] are all rejected.
What's wrong
Section.TryParse(Semantics.Music/Section.cs~L129) reads the header withEnum.TryParse<SectionType>(header[1..close], …). That call is too permissive for this header:SectionTypeis a plain enum, so the first two cases produce wrong or undefined types.Reproduction
Arrangement.Parsegoes through the same path. An undefined type then flows intoIsSameStructureandForm.Suggested fix / acceptance criteria
Enum.TryParseandEnum.IsDefinedEnum.GetNamesToStringemits the exact member name.[Verse, Chorus],[42],[ Verse ]and[-1]are all rejected.