@@ -240,11 +240,6 @@ public static JBBPCompiledBlock compile(final String script, final JBBPCustomFie
240240 int extraFieldNumberAsInt = -1 ;
241241 int customTypeFieldIndex = -1 ;
242242
243- // check that the field is not in the current structure which is a whole stream one
244- if ((code & 0xF ) != CODE_STRUCT_END && fieldUnrestrictedArrayOffset >= 0 && (structureStack .isEmpty () || structureStack .get (structureStack .size () - 1 ).startStructureOffset != fieldUnrestrictedArrayOffset )) {
245- throw new JBBPCompilationException ("Attempt to read after a 'till-the-end' field" , token );
246- }
247-
248243 final boolean extraFieldNumericDataAsExpression = ((code >>> 8 ) & EXT_FLAG_EXTRA_AS_EXPRESSION ) != 0 ;
249244 final boolean fieldTypeDiff = ((code >>> 8 ) & EXT_FLAG_EXTRA_DIFF_TYPE ) != 0 ;
250245
@@ -384,13 +379,21 @@ public static JBBPCompiledBlock compile(final String script, final JBBPCustomFie
384379 }
385380 break ;
386381 case CODE_STRUCT_START : {
387- structureStack .add (new StructStackItem (namedFields .size () + ((code & JBBPCompiler .FLAG_NAMED ) == 0 ? 0 : 1 ), startFieldOffset , code , token ));
382+ final boolean arrayReadTillEnd = (code & FLAG_ARRAY ) != 0 && (extraCode & EXT_FLAG_EXPRESSION_OR_WHOLESTREAM ) != 0 && "_" .equals (token .getArraySizeAsString ());
383+ structureStack .add (new StructStackItem (namedFields .size () + ((code & JBBPCompiler .FLAG_NAMED ) == 0 ? 0 : 1 ), startFieldOffset , arrayReadTillEnd , code , token ));
388384 }
389385 break ;
390386 case CODE_STRUCT_END : {
391387 if (structureStack .isEmpty ()) {
392388 throw new JBBPCompilationException ("Detected structure close tag without opening one" , token );
393389 } else {
390+ if (fieldUnrestrictedArrayOffset >= 0 ) {
391+ final StructStackItem startOfStruct = structureStack .get (structureStack .size () - 1 );
392+ if (startOfStruct .arrayToReadTillEndOfStream && fieldUnrestrictedArrayOffset != startOfStruct .startStructureOffset ) {
393+ throw new JBBPCompilationException ("Detected unlimited array of structures but there is already presented one" , token );
394+ }
395+ }
396+
394397 currentClosedStructure = structureStack .remove (structureStack .size () - 1 );
395398 offset += writePackedInt (out , currentClosedStructure .startStructureOffset );
396399 }
@@ -400,7 +403,11 @@ public static JBBPCompiledBlock compile(final String script, final JBBPCustomFie
400403 throw new Error ("Detected unsupported compiled code, notify the developer please [" + code + ']' );
401404 }
402405
403- if ((code & FLAG_ARRAY ) != 0 ) {
406+ if ((code & FLAG_ARRAY ) == 0 ) {
407+ if (structureStack .isEmpty () && (code & 0x0F ) != CODE_STRUCT_END && fieldUnrestrictedArrayOffset >= 0 ) {
408+ throw new JBBPCompilationException ("Detected field defined after unlimited array" , token );
409+ }
410+ } else {
404411 if ((extraCode & EXT_FLAG_EXPRESSION_OR_WHOLESTREAM ) != 0 ) {
405412 if ("_" .equals (token .getArraySizeAsString ())) {
406413 if (fieldUnrestrictedArrayOffset >= 0 ) {
@@ -635,18 +642,25 @@ private static final class StructStackItem {
635642 */
636643 private final int namedFieldCounter ;
637644
645+ /**
646+ * Flag shows that the structure is array which shoukd be read till end of stream
647+ */
648+ private final boolean arrayToReadTillEndOfStream ;
649+
638650 /**
639651 * The Constructor.
640652 *
641653 * @param namedFieldCounter the named field counter value for the structure
642654 * start
643655 * @param startStructureOffset the offset of the start structure byte-code
644656 * instruction
657+ * @param arrayToReadTillEnd if true then it is array to read till end
645658 * @param code the start byte code
646659 * @param token the token
647660 */
648- private StructStackItem (final int namedFieldCounter , final int startStructureOffset , final int code , final JBBPToken token ) {
661+ private StructStackItem (final int namedFieldCounter , final int startStructureOffset , final boolean arrayToReadTillEnd , final int code , final JBBPToken token ) {
649662 this .namedFieldCounter = namedFieldCounter ;
663+ this .arrayToReadTillEndOfStream = arrayToReadTillEnd ;
650664 this .startStructureOffset = startStructureOffset ;
651665 this .code = code ;
652666 this .token = token ;
0 commit comments