aboutsummaryrefslogtreecommitdiff
path: root/hotline
diff options
context:
space:
mode:
Diffstat (limited to 'hotline')
-rw-r--r--hotline/field.go14
-rw-r--r--hotline/field_test.go16
2 files changed, 28 insertions, 2 deletions
diff --git a/hotline/field.go b/hotline/field.go
index 554f63d..99d0d35 100644
--- a/hotline/field.go
+++ b/hotline/field.go
@@ -5,6 +5,7 @@ import (
"bytes"
"encoding/binary"
"errors"
+ "fmt"
"slices"
)
@@ -137,19 +138,28 @@ func (f *Field) DecodeNewsPath() ([]string, error) {
if len(f.Data) == 0 {
return []string{}, nil
}
+ if len(f.Data) < 2 {
+ return nil, fmt.Errorf("news path too short: %d bytes", len(f.Data))
+ }
pathCount := binary.BigEndian.Uint16(f.Data[0:2])
scanner := bufio.NewScanner(bytes.NewReader(f.Data[2:]))
scanner.Split(newsPathScanner)
- var paths []string
+ paths := make([]string, 0, pathCount)
for i := uint16(0); i < pathCount; i++ {
- scanner.Scan()
+ if !scanner.Scan() {
+ return nil, fmt.Errorf("news path truncated: declared %d items, found %d", pathCount, i)
+ }
paths = append(paths, scanner.Text())
}
+ if err := scanner.Err(); err != nil {
+ return nil, fmt.Errorf("scan news path: %w", err)
+ }
+
return paths, nil
}
diff --git a/hotline/field_test.go b/hotline/field_test.go
index 6dff102..b8d909b 100644
--- a/hotline/field_test.go
+++ b/hotline/field_test.go
@@ -248,6 +248,22 @@ func TestField_DecodeNewsPath(t *testing.T) {
wantErr: assert.NoError,
},
{
+ name: "one byte of data returns an error instead of panicking",
+ fields: fields{Data: []byte{0x00}},
+ want: nil,
+ wantErr: assert.Error,
+ },
+ {
+ name: "declared path count exceeding available items returns an error",
+ fields: fields{Data: []byte{
+ 0x00, 0x02, // path count = 2
+ 0x00, 0x00, 0x05, // 2 bytes unused + 1 byte length (5)
+ 0x48, 0x65, 0x6c, 0x6c, 0x6f, // "Hello" (only 1 item present)
+ }},
+ want: nil,
+ wantErr: assert.Error,
+ },
+ {
name: "single path",
fields: fields{Data: []byte{
0x00, 0x01, // path count = 1