Skip to content

Commit

Permalink
fbb: Ignore leading whitespace when parsing msg
Browse files Browse the repository at this point in the history
Resolves issue #86 (hopefully)
  • Loading branch information
martinhpedersen committed Oct 18, 2023
1 parent 056353e commit 6983167
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
22 changes: 22 additions & 0 deletions fbb/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,12 +290,34 @@ func (m *Message) Cc() (cc []Address) {
return
}

// copied from from stdlib's bytes/bytes.go
var asciiSpace = [256]uint8{'\t': 1, '\n': 1, '\v': 1, '\f': 1, '\r': 1, ' ': 1}

// trimLeft advances the reader until the first byte not
func trimLeftSpace(r *bufio.Reader) {
for {
b, err := r.Peek(1)
if err != nil || asciiSpace[b[0]] == 0 {
break
}
r.Discard(len(b))
}
}

// Implements ReaderFrom for Message.
//
// Reads the given io.Reader and fills in values fetched from the stream.
func (m *Message) ReadFrom(r io.Reader) error {
reader := bufio.NewReader(r)

// Trim leading whitespace before reading the header:
// Got a mysterious bug that traced back to the possibility of a
// received message with leading CRLFs. Trimming space characters
// before reading the header should be safe, as the worst case scenario
// is that we fail to parse the header as opposed to definitely
// failing.
trimLeftSpace(reader)

if h, err := textproto.NewReader(reader).ReadMIMEHeader(); err != nil {
return err
} else {
Expand Down
32 changes: 32 additions & 0 deletions fbb/message_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,38 @@ import (
"unicode"
)

func TestReadMessageWithWhitespaceBeforeHeader(t *testing.T) {
m1 := NewMessage(Private, "one-long-mid")
m1.AddTo("N0CALL")
m1.SetFrom("LA5NTA")
m1.SetBody("Hello world")

// Write the message with leading whitespace garbage
var buf bytes.Buffer
buf.WriteString("\r\n\r\n\t ")
if err := m1.Write(&buf); err != nil {
t.Fatal(err)
}

// Read the message and verify that we decoded the header successfully.
m2 := &Message{}
if err := m2.ReadFrom(bytes.NewReader(buf.Bytes())); err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(m1.Header, m2.Header) {
t.Error("parsed message header differs", m1, m2)
}
}

func TestEmptyMessageReadError(t *testing.T) {
if err := (&Message{}).ReadFrom(strings.NewReader("")); err == nil {
t.Errorf("Reading empty message did not error")
}
if err := (&Message{}).ReadFrom(strings.NewReader("\r\n\r\nfoobar")); err == nil {
t.Errorf("Reading headerless message did not error")
}
}

func TestParseDate(t *testing.T) {
tests := []string{
"2016/12/30 01:00", // The correct format according to winlink.org/b2f.
Expand Down

0 comments on commit 6983167

Please sign in to comment.