fix(html): validate block ID parsing
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
a928d01b9e
commit
5d13a4028b
2 changed files with 28 additions and 13 deletions
26
path.go
26
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
|
||||
}
|
||||
|
|
|
|||
15
path_test.go
15
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue