fix(mcp): strip a leading UTF-8 BOM before frontmatter fence detection
CI / Lint / Test / Vet (pull_request) Successful in 42s
CI / Mirror to GitHub (pull_request) Skipped

Round-5 review found a sixth bypass, same mechanism as round 4's CRLF gap,
one layer earlier: a leading UTF-8 BOM (EF BB BF) defeats
strings.HasPrefix(doc, "---\n") before CRLF normalization even applies.
Judged live-plausible rather than exotic — Notepad's default "UTF-8" save
and PowerShell's pre-v6 Out-File/Set-Content both emit a BOM — so fixed
inline at the same cost as the CRLF fix rather than deferred wholesale to
hyperguild#138.

Strip the BOM before the CRLF normalization in frontmatterBlock, so every
caller (fence-presence detection and frontmatterScalars) agrees regardless
of encoding.

Drawing the line here: further encoding variants in this family (NEL line
separators, UTF-16 BOM, lone-CR classic-Mac endings) are judged not
live-plausible in a git-tracked UTF-8 markdown corpus and are tracked
wholesale under hyperguild#138's parser consolidation rather than chased as
individual rounds on this PR.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-23 10:44:54 +02:00
co-authored by Claude Sonnet 5
parent 4f75279ceb
commit 1d67e16c0d
2 changed files with 33 additions and 2 deletions
+7 -2
View File
@@ -313,9 +313,14 @@ func frontmatterBlock(doc string) (block string, ok bool) {
// Round 4 found a note with CRLF fence lines ("---\r\n") silently
// defeats HasPrefix(doc, "---\n") on the precondition read — not an
// adversarial old_str/new_str, just an encoding difference — which
// makes checkClaimEnvelope no-op entirely. Normalize once, here, so
// makes checkClaimEnvelope no-op entirely. Round 5 found the same
// mechanism one layer earlier: a leading UTF-8 BOM (a live, plausible
// byte sequence — Notepad's default "UTF-8" save and PowerShell's
// pre-v6 Out-File/Set-Content both emit one) defeats the same prefix
// check before CRLF normalization even applies. Strip both, here, so
// every caller (hadFence/hasFence detection and frontmatterScalars)
// agrees regardless of line ending.
// agrees regardless of encoding.
doc = strings.TrimPrefix(doc, "\xef\xbb\xbf")
doc = strings.ReplaceAll(doc, "\r\n", "\n")
if !strings.HasPrefix(doc, "---\n") {
return "", false