From 36b378261bada6c3a2c82c334a11dbb061918aef Mon Sep 17 00:00:00 2001 From: Luciano Viana <30724718+lucianoviana@users.noreply.github.com> Date: Tue, 3 Sep 2024 14:45:34 +0200 Subject: [PATCH] [bugfix] Issue 518 - nested repeating group validation was not working when the count tag was lower than the actual number of occurrences of the repeating group. (#520) --- .../generation/DecoderGenerator.java | 7 ++++++- .../artio/dictionary/ExampleDictionary.java | 11 ++++++++++- .../AbstractDecoderGeneratorTest.java | 18 ++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/artio-codecs/src/main/java/uk/co/real_logic/artio/dictionary/generation/DecoderGenerator.java b/artio-codecs/src/main/java/uk/co/real_logic/artio/dictionary/generation/DecoderGenerator.java index e49867b68f..a20e0c044f 100644 --- a/artio-codecs/src/main/java/uk/co/real_logic/artio/dictionary/generation/DecoderGenerator.java +++ b/artio-codecs/src/main/java/uk/co/real_logic/artio/dictionary/generation/DecoderGenerator.java @@ -1925,7 +1925,12 @@ private String decodeGroup(final Entry entry) " {\n" + " invalidTagId = tag;\n" + " rejectReason = %6$s;\n" + - " return position;\n" + + " while (%1$sCurrent != null) \n" + + " {\n" + + " position += %1$sCurrent.decode(buffer, position, end - position);\n" + + " %1$sCurrent = %1$sCurrent.next();\n" + + " }\n" + + " return position - offset;\n" + " }\n" + " }\n" + " }\n", diff --git a/artio-codecs/src/test/java/uk/co/real_logic/artio/dictionary/ExampleDictionary.java b/artio-codecs/src/test/java/uk/co/real_logic/artio/dictionary/ExampleDictionary.java index f9bf351d36..3cb6d3f88c 100644 --- a/artio-codecs/src/test/java/uk/co/real_logic/artio/dictionary/ExampleDictionary.java +++ b/artio-codecs/src/test/java/uk/co/real_logic/artio/dictionary/ExampleDictionary.java @@ -35,6 +35,7 @@ public final class ExampleDictionary { public static final String NO_EG_GROUP = "NoEgGroup"; + public static final String NO_NESTED_EG_GROUP = "NoNestedGroup"; public static final String NO_SECOND_EG_GROUP = "NoSecondEgGroup"; public static final String NO_ADMIN_EG_GROUP = "NoAdminEgGroup"; public static final String NO_COMPONENT_GROUP = "NoComponentGroup"; @@ -472,6 +473,14 @@ public final class ExampleDictionary "8=FIX.4.4\0019=71\00135=0\001115=abc\001116=2\001117=1.1\001127=19700101-00:00:00.001" + "\001120=3\001121=1\001121=2\00110=053\001"; + public static final String NESTED_REPEATING_GROUP_MESSAGE_WITH_TOO_LOW_NUMBER_FIELD = + "8=FIX.4.4\0019=77\00135=0\001115=abc\001116=2\001117=1.1\001127=19700101-00:00:00.001" + + "\001120=1\001121=1\001122=1\001123=1\001123=1\00110=063\001"; + + public static final String NESTED_REPEATING_GROUP_MESSAGE_WITH_TOO_HIGH_NUMBER_FIELD = + "8=FIX.4.4\0019=77\00135=0\001115=abc\001116=2\001117=1.1\001127=19700101-00:00:00.001" + + "\001120=1\001121=1\001122=2\001123=1\00110=063\001"; + public static final String NON_EMPTY_OPTIONAL_COMPONENT_OF_REQUIRED_GROUP = "8=FIX.4.4\0019=81\00135=OCRG\0012001=1\0012002=555-100-1234\00110=246\001"; @@ -563,7 +572,7 @@ private static Dictionary buildMessageExample() final Field dayOfMonthField = registerField(messageEgFields, 129, "DayOfMonthField", Type.DAYOFMONTH); final Group nestedGroup = Group.of(registerField( - messageEgFields, 122, "NoNestedGroup", INT), messageEgFields); + messageEgFields, 122, NO_NESTED_EG_GROUP, INT), messageEgFields); nestedGroup.optionalEntry(registerField(messageEgFields, 123, "NestedField", INT)); final Group egGroup = Group.of(registerField(messageEgFields, 120, NO_EG_GROUP, INT), messageEgFields); diff --git a/artio-codecs/src/test/java/uk/co/real_logic/artio/dictionary/generation/AbstractDecoderGeneratorTest.java b/artio-codecs/src/test/java/uk/co/real_logic/artio/dictionary/generation/AbstractDecoderGeneratorTest.java index 466bf8d716..6cb11281b4 100644 --- a/artio-codecs/src/test/java/uk/co/real_logic/artio/dictionary/generation/AbstractDecoderGeneratorTest.java +++ b/artio-codecs/src/test/java/uk/co/real_logic/artio/dictionary/generation/AbstractDecoderGeneratorTest.java @@ -838,6 +838,24 @@ public void shouldReasonablyValidateGroupNumbersLessThanTheNumberOfElementsInThe assertInvalid(decoder, INCORRECT_NUMINGROUP_COUNT_FOR_REPEATING_GROUP, 120); } + @Test + public void shouldSupportGroupNumbersGreaterThanTheNumberOfElementsInTheNestedGroup() throws Exception + { + final Decoder decoder = decodeHeartbeatWithRejectingUnknownFields( + NESTED_REPEATING_GROUP_MESSAGE_WITH_TOO_HIGH_NUMBER_FIELD); + + assertInvalid(decoder, INCORRECT_NUMINGROUP_COUNT_FOR_REPEATING_GROUP, 122); + } + + @Test + public void shouldReasonablyValidateGroupNumbersLessThanTheNumberOfElementsInTheNestedGroup() throws Exception + { + final Decoder decoder = decodeHeartbeatWithRejectingUnknownFields( + NESTED_REPEATING_GROUP_MESSAGE_WITH_TOO_LOW_NUMBER_FIELD); + + assertInvalid(decoder, INCORRECT_NUMINGROUP_COUNT_FOR_REPEATING_GROUP, 122); + } + @Test public void shouldLeaveDecoderInUsableIfUnknownFieldForRepeatingGroupReachedAndRejectingOn() throws Exception {