From 580e733e77156f8d80337fd1f13727a168e197e0 Mon Sep 17 00:00:00 2001 From: Leander Beernaert Date: Fri, 12 May 2023 10:55:16 +0200 Subject: [PATCH] fix(GODT-2595): Fix out of bounds crash in rfc822 parser --- rfc822/parser.go | 7 +++++++ rfc822/parser_test.go | 17 +++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/rfc822/parser.go b/rfc822/parser.go index 093365ac..89ba2531 100644 --- a/rfc822/parser.go +++ b/rfc822/parser.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/base64" "errors" + "fmt" "io" "mime/quotedprintable" @@ -113,6 +114,12 @@ func (section *Section) Part(identifier ...int) (*Section, error) { } if len(children) != 0 { + childIndex := identifier[0] - 1 + + if childIndex >= len(children) { + return nil, fmt.Errorf("invalid part index") + } + return children[identifier[0]-1].Part(identifier[1:]...) } } diff --git a/rfc822/parser_test.go b/rfc822/parser_test.go index a61532b8..dba875c5 100644 --- a/rfc822/parser_test.go +++ b/rfc822/parser_test.go @@ -95,8 +95,7 @@ This part does end with a linebreak. } } -func TestParseEmbeddedMessage(t *testing.T) { - const literal = `From: Nathaniel Borenstein +const embeddedLiteral = `From: Nathaniel Borenstein To: Ned Freed Subject: Sample message MIME-Version: 1.0 @@ -134,9 +133,10 @@ This part is also embedded This is the epilogue. It is also to be ignored. ` - section := Parse([]byte(literal)) +func TestParseEmbeddedMessage(t *testing.T) { + section := Parse([]byte(embeddedLiteral)) - assert.Equal(t, literal, string(section.Literal())) + assert.Equal(t, embeddedLiteral, string(section.Literal())) { part, err := section.Part(1) @@ -341,3 +341,12 @@ func FuzzParseDec(f *testing.F) { _, _ = Parse(inputData).DecodedBody() }) } + +func TestParserAccessingInvalidPartDoesNotCrash(t *testing.T) { + section := Parse([]byte(embeddedLiteral)) + + assert.Equal(t, embeddedLiteral, string(section.Literal())) + + _, err := section.Part(2, 3) + require.Error(t, err) +}