Skip to content

Commit 9c93db9

Browse files
Merge pull request #767 from raphaelroshan/fix/resend-group-duplicate-checksum
Fix duplicate 10= checksum when resending a message ending in a repeating group
2 parents 4bd79e3 + 42443c0 commit 9c93db9

2 files changed

Lines changed: 25 additions & 0 deletions

File tree

message.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ func parseGroup(mp *msgParser, tags []Tag) {
313313
for {
314314
mp.fieldIndex++
315315
mp.parsedFieldBytes = &mp.msg.fields[mp.fieldIndex]
316+
preExtractBytes := mp.rawBytes
316317
mp.rawBytes, _ = extractField(mp.parsedFieldBytes, mp.rawBytes)
317318
mp.trailerBytes = mp.rawBytes
318319

@@ -337,6 +338,10 @@ func parseGroup(mp *msgParser, tags []Tag) {
337338
mp.msg.Body.add(dm)
338339
mp.msg.Trailer.add(mp.msg.fields[mp.fieldIndex : mp.fieldIndex+1])
339340
mp.foundTrailer = true
341+
// Restore the buffer that still holds the trailer so the caller strips
342+
// it from bodyBytes; otherwise the trailer stays embedded and resend
343+
// emits a duplicate 10= tag.
344+
mp.trailerBytes = preExtractBytes
340345
break
341346
} else {
342347
// Found a body field outside the group.

message_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,26 @@ func (s *MessageSuite) TestReBuildWithRepeatingGroupMultipleEntriesInGroupForRes
448448
s.True(bytes.Equal(expectedResendBytes, resendBytes), "Unexpected bytes,\n expected: %s\n but was: %s", expectedResendBytes, resendBytes)
449449
}
450450

451+
func (s *MessageSuite) TestReBuildWithRepeatingGroupWithDictionaryForResend() {
452+
dict, dictErr := datadictionary.Parse("spec/FIX44.xml")
453+
s.Nil(dictErr)
454+
455+
// A message whose body ends in a repeating group (453), parsed WITH a
456+
// dictionary so parseGroup handles the group.
457+
rawMsg := bytes.NewBufferString(
458+
"8=FIX.4.4\x019=165\x0135=D\x0134=2\x0149=01001\x0150=01001a\x0152=20231231-20:19:41\x0156=TEST\x01" +
459+
"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" +
460+
"10=026\x01")
461+
s.Nil(ParseMessageWithDataDictionary(s.msg, rawMsg, dict, dict))
462+
463+
// The trailer must not stay embedded in bodyBytes.
464+
s.False(bytes.Contains(s.msg.bodyBytes, []byte("\x0110=")), "trailer leaked into bodyBytes: %s", s.msg.bodyBytes)
465+
466+
// A resend rebuilt from bodyBytes must carry exactly one 10= checksum.
467+
resendBytes := s.msg.buildWithBodyBytes(s.msg.bodyBytes)
468+
s.Equal(1, bytes.Count(resendBytes, []byte("\x0110=")), "expected exactly one 10= checksum, got: %s", resendBytes)
469+
}
470+
451471
func (s *MessageSuite) TestReverseRoute() {
452472
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")))
453473

0 commit comments

Comments
 (0)