diff --git a/fix_int.go b/fix_int.go
index 6bd968003..a7bd62ca8 100644
--- a/fix_int.go
+++ b/fix_int.go
@@ -31,6 +31,10 @@ const (
// atoi is similar to the function in strconv, but is tuned for ints appearing in FIX field types.
func atoi(d []byte) (int, error) {
+ if len(d) == 0 {
+ return 0, errors.New("empty bytes")
+ }
+
if d[0] == asciiMinus {
n, err := parseUInt(d[1:])
return (-1) * n, err
diff --git a/fix_int_test.go b/fix_int_test.go
index caa9b7840..ee363fe6c 100644
--- a/fix_int_test.go
+++ b/fix_int_test.go
@@ -35,6 +35,9 @@ func TestFIXInt_Read(t *testing.T) {
err = field.Read([]byte("blah"))
assert.NotNil(t, err, "Unexpected error")
+
+ err = field.Read([]byte(""))
+ assert.NotNil(t, err, "Unexpected error")
}
func TestFIXInt_Int(t *testing.T) {
diff --git a/message.go b/message.go
index 69407cf5d..02ca2ad66 100644
--- a/message.go
+++ b/message.go
@@ -553,6 +553,12 @@ func extractXMLDataField(parsedFieldBytes *TagValue, buffer []byte, dataLen int)
remBytes = buffer
return
}
+ // Compared against the remaining buffer so a large dataLen cannot overflow int.
+ if dataLen < 0 || dataLen > len(buffer)-endIndex-2 {
+ err = parseError{OrigError: fmt.Sprintf("extractXMLDataField: XMLDataLen %d exceeds remaining buffer of %d bytes", dataLen, len(buffer)-endIndex-2)}
+ remBytes = buffer
+ return
+ }
endIndex += dataLen + 1
err = parsedFieldBytes.parse(buffer[:endIndex+1])
diff --git a/message_test.go b/message_test.go
index a51c5231e..e096f1da2 100644
--- a/message_test.go
+++ b/message_test.go
@@ -64,6 +64,38 @@ func (s *MessageSuite) TestParseMessageEmpty() {
s.NotNil(err)
}
+func (s *MessageSuite) TestParseMessageXMLDataLenOutOfRange() {
+ var tests = []struct {
+ name string
+ rawMsg string
+ }{
+ {"overrun", "8=FIX.4.29=2035=n34=249=CME56=OAEAAAN212=999999999213=10=000"},
+ {"int overflow", "8=FIX.4.29=2035=n34=249=CME56=OAEAAAN212=9223372036854775807213=10=000"},
+ }
+
+ for _, test := range tests {
+ s.Run(test.name, func() {
+ s.NotNil(ParseMessage(NewMessage(), bytes.NewBufferString(test.rawMsg)))
+ })
+ }
+}
+
+func (s *MessageSuite) TestParseMessageEmptyIntField() {
+ var tests = []struct {
+ name string
+ rawMsg string
+ }{
+ {"body length", "8=FIX.4.29=35=D34=249=TW56=ISLD10=000"},
+ {"xml data len", "8=FIX.4.29=2035=n34=249=CME56=OAEAAAN212=213=10=000"},
+ }
+
+ for _, test := range tests {
+ s.Run(test.name, func() {
+ s.NotNil(ParseMessage(NewMessage(), bytes.NewBufferString(test.rawMsg)))
+ })
+ }
+}
+
func (s *MessageSuite) TestParseMessage() {
rawMsg := bytes.NewBufferString("8=FIX.4.29=10435=D34=249=TW52=20140515-19:49:56.65956=ISLD11=10021=140=154=155=TSLA60=00010101-00:00:00.00010=039")