diff --git a/path.go b/path.go index dda1d7a..8084c6c 100644 --- a/path.go +++ b/path.go @@ -1,5 +1,7 @@ package html +import "strings" + // ParseBlockID extracts the slot sequence from a data-block ID. // Usage example: slots := ParseBlockID("L-0-C-0") // "L-0-C-0" → ['L', 'C'] @@ -8,21 +10,19 @@ func ParseBlockID(id string) []byte { return nil } - // Split on "-" and take every other element (the slot letters). - // Format: "X-0" or "X-0-Y-0-Z-0" - var slots []byte - part := 0 - start := 0 - for i := 0; i <= len(id); i++ { - if i < len(id) && id[i] != '-' { - continue - } + // Valid IDs are exact sequences of "{slot}-0" segments, e.g. + // "H-0" or "L-0-C-0". Any malformed segment invalidates the whole ID. + parts := strings.Split(id, "-") + if len(parts)%2 != 0 { + return nil + } - if part%2 == 0 && i-start == 1 { - slots = append(slots, id[start]) + slots := make([]byte, 0, len(parts)/2) + for i := 0; i < len(parts); i += 2 { + if len(parts[i]) != 1 || parts[i+1] != "0" { + return nil } - part++ - start = i + 1 + slots = append(slots, parts[i][0]) } return slots } diff --git a/path_test.go b/path_test.go index c22f55a..7301466 100644 --- a/path_test.go +++ b/path_test.go @@ -83,3 +83,18 @@ func TestParseBlockID_ExtractsSlots_Good(t *testing.T) { } } } + +func TestParseBlockID_InvalidInput_Good(t *testing.T) { + tests := []string{ + "L-1-C-0", + "L-0-C", + "L-0-", + "X", + } + + for _, id := range tests { + if got := ParseBlockID(id); got != nil { + t.Errorf("ParseBlockID(%q) = %v, want nil", id, got) + } + } +}