Skip to content

Commit 57fef4c

Browse files
committed
parseGroup: stop misattributing body fields after nested groups
1 parent 7dfe5b3 commit 57fef4c

2 files changed

Lines changed: 17 additions & 20 deletions

File tree

message.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ func parseGroup(mp *msgParser, tags []Tag) {
310310
dm := mp.msg.fields[mp.fieldIndex : mp.fieldIndex+1]
311311
fields := getGroupFields(mp.msg, tags, mp.appDataDictionary)
312312

313+
parseLoop:
313314
for {
314315
mp.fieldIndex++
315316
mp.parsedFieldBytes = &mp.msg.fields[mp.fieldIndex]
@@ -350,16 +351,15 @@ func parseGroup(mp *msgParser, tags []Tag) {
350351
fields = getGroupFields(mp.msg, searchTags, mp.appDataDictionary)
351352
continue
352353
}
353-
if len(tags) > 1 {
354-
searchTags = tags[:len(tags)-1]
355-
}
356-
// Did this tag occur after a nested group and belongs to the parent group.
357-
if isNumInGroupField(mp.msg, searchTags, mp.appDataDictionary) {
358-
// Add the field member to the group.
359-
dm = append(dm, *mp.parsedFieldBytes)
360-
// Continue parsing the parent group.
361-
fields = getGroupFields(mp.msg, searchTags, mp.appDataDictionary)
362-
continue
354+
// The tag isn't a member of the current group. Walk up: if an
355+
// ancestor group includes it, resume there; otherwise it's body-level.
356+
for len(tags) > 1 {
357+
tags = tags[:len(tags)-1]
358+
fields = getGroupFields(mp.msg, tags, mp.appDataDictionary)
359+
if isGroupMember(mp.parsedFieldBytes.tag, fields) {
360+
dm = append(dm, *mp.parsedFieldBytes)
361+
continue parseLoop
362+
}
363363
}
364364
// Add the repeating group.
365365
mp.msg.Body.add(dm)

message_test.go

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -143,16 +143,13 @@ func (s *MessageSuite) TestParseGroup_BodyFieldAfterNestedGroup() {
143143
// NoQuoteSets count (group delimiter) lands in Body as expected.
144144
s.True(s.msg.Body.Has(Tag(296)))
145145

146-
// ToDo: should be correct — QuoteStatus (297) must be a top-level body
147-
// field per FIX 4.4. Current parseGroup logic silently absorbs 297 into
148-
// the NoQuoteSets group buffer because it only checks whether the
149-
// parent tag is a NumInGroup, not whether 297 is a member of the
150-
// parent group template.
151-
s.False(s.msg.Body.Has(Tag(297)),
152-
"BUG: QuoteStatus (297) is absent from Body.FieldMap — parser "+
153-
"mis-attributed it to the parent NoQuoteSets group. This "+
154-
"assertion documents the bug; flip to s.True(...) when "+
155-
"parseGroup is fixed.")
146+
// QuoteStatus (297) must be a top-level body field per FIX 4.4.
147+
s.True(s.msg.Body.Has(Tag(297)),
148+
"QuoteStatus (297) must land at the body level; it is a body field "+
149+
"in MassQuoteAcknowledgement, not a member of NoQuoteSets.")
150+
val, verr := s.msg.Body.GetInt(Tag(297))
151+
s.Nil(verr)
152+
s.Equal(1, val)
156153
}
157154

158155
func (s *MessageSuite) TestBuild() {

0 commit comments

Comments
 (0)