fix(frontmatter): consolidate 3 independent fence-parsers into one #139

Merged
mathias merged 2 commits from fix/138-consolidate-frontmatter-parsers into main 2026-09-23 13:07:32 +00:00
2 changed files with 30 additions and 2 deletions
Showing only changes of commit 625955e944 - Show all commits
+15 -2
View File
@@ -146,9 +146,22 @@ func Split(doc []byte) (block, rest []byte, ok bool) {
}
body := s[len(fence)+1:]
idx := strings.Index(body, "\n"+fence+"\n")
idx := strings.Index(body, "\n"+fence)
if idx < 0 {
return nil, nil, false
}
return []byte(body[:idx+1]), []byte(body[idx+1+len(fence):]), true
// What follows the closing fence must be either a newline (a real body
// follows) or nothing at all (the fence is the literal end of the
// document — no body, not a bypass attempt). Anything else, e.g.
// "\n---extra", is not a valid close: an earlier version of this check
// accepted it, which is exactly the looser match hyperguild#138 closes.
after := idx + 1 + len(fence)
switch {
case after == len(body):
return []byte(body[:idx+1]), nil, true
case body[after] == '\n':
return []byte(body[:idx+1]), []byte(body[after:]), true
default:
return nil, nil, false
}
}
@@ -223,3 +223,18 @@ func TestSplit_RequiresANewlineAfterTheClosingFence(t *testing.T) {
_, _, ok := Split([]byte(doc))
assert.False(t, ok, "a fence line not followed by a newline is not a valid closing fence")
}
// TestSplit_AcceptsAClosingFenceThatIsTheLastBytesOfTheDocument is a
// regression pin found in review of hyperguild#138: the fix for the
// "\n---extra" bypass above must not also reject the legitimate case of a
// closing fence with nothing after it at all (no trailing newline because
// there's no body, not because a bypass is being attempted) -- this
// package's own private split() accepted that shape before the
// consolidation, and cmd/frontmatterlint's Lint/Fix relied on it.
func TestSplit_AcceptsAClosingFenceThatIsTheLastBytesOfTheDocument(t *testing.T) {
doc := "---\ntitle: 'n'\n---"
block, rest, ok := Split([]byte(doc))
require.True(t, ok, "a closing fence at literal end-of-file, with nothing after it, is valid -- there is no body to require a newline before")
assert.Contains(t, string(block), "title: 'n'")
assert.Equal(t, "", string(rest))
}