From 97a48fc73d00109a48e8e3238f490b2db653f34b Mon Sep 17 00:00:00 2001 From: Virgil Date: Fri, 3 Apr 2026 17:14:10 +0000 Subject: [PATCH] fix(html): validate block path decoding Co-Authored-By: Virgil --- path.go | 16 ++++++++++++---- path_test.go | 3 +++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/path.go b/path.go index e33307b..bcb2e1f 100644 --- a/path.go +++ b/path.go @@ -3,21 +3,29 @@ package html import "strings" // ParseBlockID extracts the slot sequence from a data-block ID. -// "L-0-C-0" → ['L', 'C'] +// Example: ParseBlockID("L-0-C-0") returns []byte{'L', 'C'}. func ParseBlockID(id string) []byte { if id == "" { return nil } - // Split on "-" and take every other element (the slot letters). - // Format: "X-0" or "X-0-Y-0-Z-0" + // Split on "-" and require the exact structural pattern: + // slot, 0, slot, 0, ... var slots []byte i := 0 for part := range strings.SplitSeq(id, "-") { - if i%2 == 0 && len(part) == 1 { + if i%2 == 0 { + if len(part) != 1 { + return nil + } slots = append(slots, part[0]) + } else if part != "0" { + return nil } i++ } + if i == 0 || i%2 != 0 { + return nil + } return slots } diff --git a/path_test.go b/path_test.go index 791be57..fda5338 100644 --- a/path_test.go +++ b/path_test.go @@ -152,6 +152,9 @@ func TestParseBlockID(t *testing.T) { {"H-0", []byte{'H'}}, {"C-0-C-0-C-0", []byte{'C', 'C', 'C'}}, {"", nil}, + {"L-1-C-0", nil}, + {"L-0-C", nil}, + {"LL-0", nil}, } for _, tt := range tests {