Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions message.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ func parseGroup(mp *msgParser, tags []Tag) {
for {
mp.fieldIndex++
mp.parsedFieldBytes = &mp.msg.fields[mp.fieldIndex]
preExtractBytes := mp.rawBytes
mp.rawBytes, _ = extractField(mp.parsedFieldBytes, mp.rawBytes)
mp.trailerBytes = mp.rawBytes

Expand All @@ -337,6 +338,10 @@ func parseGroup(mp *msgParser, tags []Tag) {
mp.msg.Body.add(dm)
mp.msg.Trailer.add(mp.msg.fields[mp.fieldIndex : mp.fieldIndex+1])
mp.foundTrailer = true
// Restore the buffer that still holds the trailer so the caller strips
// it from bodyBytes; otherwise the trailer stays embedded and resend
// emits a duplicate 10= tag.
mp.trailerBytes = preExtractBytes
break
} else {
// Found a body field outside the group.
Expand Down
20 changes: 20 additions & 0 deletions message_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,26 @@ func (s *MessageSuite) TestReBuildWithRepeatingGroupMultipleEntriesInGroupForRes
s.True(bytes.Equal(expectedResendBytes, resendBytes), "Unexpected bytes,\n expected: %s\n but was: %s", expectedResendBytes, resendBytes)
}

func (s *MessageSuite) TestReBuildWithRepeatingGroupWithDictionaryForResend() {
dict, dictErr := datadictionary.Parse("spec/FIX44.xml")
s.Nil(dictErr)

// A message whose body ends in a repeating group (453), parsed WITH a
// dictionary so parseGroup handles the group.
rawMsg := bytes.NewBufferString(
"8=FIX.4.4\x019=165\x0135=D\x0134=2\x0149=01001\x0150=01001a\x0152=20231231-20:19:41\x0156=TEST\x01" +
"1=acct1\x0111=13976\x0121=1\x0138=1\x0140=2\x0144=12\x0154=1\x0155=SYMABC\x0159=0\x0160=20231231-20:19:41\x01453=1\x01448=4501\x01447=D\x01452=28\x01" +
"10=026\x01")
s.Nil(ParseMessageWithDataDictionary(s.msg, rawMsg, dict, dict))

// The trailer must not stay embedded in bodyBytes.
s.False(bytes.Contains(s.msg.bodyBytes, []byte("\x0110=")), "trailer leaked into bodyBytes: %s", s.msg.bodyBytes)

// A resend rebuilt from bodyBytes must carry exactly one 10= checksum.
resendBytes := s.msg.buildWithBodyBytes(s.msg.bodyBytes)
s.Equal(1, bytes.Count(resendBytes, []byte("\x0110=")), "expected exactly one 10= checksum, got: %s", resendBytes)
}

func (s *MessageSuite) TestReverseRoute() {
s.Nil(ParseMessage(s.msg, bytes.NewBufferString("8=FIX.4.29=17135=D34=249=TW50=KK52=20060102-15:04:0556=ISLD57=AP144=BB115=JCD116=CS128=MG129=CB142=JV143=RY145=BH11=ID21=338=10040=w54=155=INTC60=20060102-15:04:0510=123")))

Expand Down
Loading