2626import static org .junit .jupiter .api .Assertions .fail ;
2727
2828import com .igormaznitsa .jbbp .compiler .JBBPNamedFieldInfo ;
29+ import com .igormaznitsa .jbbp .compiler .tokenizer .JBBPFieldTypeParameterContainer ;
2930import com .igormaznitsa .jbbp .exceptions .JBBPCompilationException ;
3031import com .igormaznitsa .jbbp .exceptions .JBBPNumericFieldValueConversionException ;
3132import com .igormaznitsa .jbbp .exceptions .JBBPParsingException ;
33+ import com .igormaznitsa .jbbp .exceptions .JBBPReachedArraySizeLimitException ;
3234import com .igormaznitsa .jbbp .exceptions .JBBPTooManyFieldsFoundException ;
3335import com .igormaznitsa .jbbp .io .JBBPArraySizeLimiter ;
3436import com .igormaznitsa .jbbp .io .JBBPBitInputStream ;
37+ import com .igormaznitsa .jbbp .io .JBBPBitOrder ;
3538import com .igormaznitsa .jbbp .io .JBBPByteOrder ;
3639import com .igormaznitsa .jbbp .model .JBBPAbstractArrayField ;
3740import com .igormaznitsa .jbbp .model .JBBPAbstractField ;
@@ -1198,33 +1201,25 @@ public void testParse_NonFixedBitArray_ParsedAsEmptyArray() throws Exception {
11981201 assertEquals (0 , parsed .findFieldForNameAndType ("array" , JBBPFieldArrayBit .class ).size ());
11991202 }
12001203
1201- @ Test
1202- public void testParse_ProcessingOfExtraFieldValuesInSkippedStructureFields () throws Exception {
1203- final JBBPFieldStruct parsed = JBBPParser .prepare (
1204- "byte len; struct1 [len] { int a; var:23231223 [1024] helloarray; int b; bit:3; bit:7 [10233]; var:-1332 hello; skip:34221223; bit:7; bit:1; align:3445; bit:2; int skippedInt; long lng; insidestruct {bit:1; bit:2; bit:3;} } int end; " )
1205- .parse (new byte [] {0 , 1 , 2 , 3 , 4 }, new JBBPVarFieldProcessor () {
1204+ private static void testArrayLimiter_2elementsLimit (final byte [] testData , final String script ,
1205+ final JBBPVarFieldProcessor varFieldProcessor ,
1206+ final JBBPCustomFieldTypeProcessor customFieldTypeProcessor )
1207+ throws Exception {
1208+ ByteArrayInputStream dataStream = new ByteArrayInputStream (testData );
1209+ final JBBPParser parser = JBBPParser .prepare (script , customFieldTypeProcessor );
1210+ parser .parse (dataStream , varFieldProcessor , null );
1211+ assertFalse (dataStream .available () > 0 );
12061212
1207- @ Override
1208- public JBBPAbstractArrayField <? extends JBBPAbstractField > readVarArray (
1209- JBBPBitInputStream inStream , int arraySize , JBBPNamedFieldInfo fieldName ,
1210- int extraValue , JBBPByteOrder byteOrder , JBBPNamedNumericFieldMap numericFieldMap ,
1211- JBBPArraySizeLimiter arraySizeLimiter )
1212- throws IOException {
1213- fail ("Must not be called" );
1214- return null ;
1215- }
1213+ final ByteArrayInputStream dataStreamLimit1 = new ByteArrayInputStream (testData );
1214+ assertThrows (JBBPReachedArraySizeLimitException .class ,
1215+ () -> parser .parse (dataStreamLimit1 , varFieldProcessor , null , () -> 2 ));
1216+ assertTrue (dataStreamLimit1 .available () > 0 );
12161217
1217- @ Override
1218- public JBBPAbstractField readVarField (JBBPBitInputStream inStream ,
1219- JBBPNamedFieldInfo fieldName , int extraValue ,
1220- JBBPByteOrder byteOrder ,
1221- JBBPNamedNumericFieldMap numericFieldMap )
1222- throws IOException {
1223- fail ("Must not be called" );
1224- return null ;
1225- }
1226- }, null );
1227- assertEquals (0x01020304 , parsed .findFieldForNameAndType ("end" , JBBPFieldInt .class ).getAsInt ());
1218+ final ByteArrayInputStream dataStreamLimit2 = new ByteArrayInputStream (testData );
1219+ assertEquals (2 ,
1220+ ((JBBPAbstractArrayField <?>) parser .parse (dataStreamLimit2 , varFieldProcessor , null ,
1221+ () -> -2 ).getArray ()[0 ]).size ());
1222+ assertTrue (dataStreamLimit2 .available () > 0 );
12281223 }
12291224
12301225 @ Test
@@ -1917,11 +1912,40 @@ public void testParse_NonFixedDoubleArray_ParsedAsEmptyArray() throws Exception
19171912 assertEquals (0 , parsed .findFieldForNameAndType ("array" , JBBPFieldArrayDouble .class ).size ());
19181913 }
19191914
1915+ @ Test
1916+ public void testParse_ProcessingOfExtraFieldValuesInSkippedStructureFields () throws Exception {
1917+ final JBBPFieldStruct parsed = JBBPParser .prepare (
1918+ "byte len; struct1 [len] { int a; var:23231223 [1024] helloarray; int b; bit:3; bit:7 [10233]; var:-1332 hello; skip:34221223; bit:7; bit:1; align:3445; bit:2; int skippedInt; long lng; insidestruct {bit:1; bit:2; bit:3;} } int end; " )
1919+ .parse (new byte [] {0 , 1 , 2 , 3 , 4 }, new JBBPVarFieldProcessor () {
1920+
1921+ @ Override
1922+ public JBBPAbstractArrayField <? extends JBBPAbstractField > readVarArray (
1923+ JBBPBitInputStream inStream , int arraySize , JBBPNamedFieldInfo fieldName ,
1924+ int extraValue , JBBPByteOrder byteOrder , JBBPNamedNumericFieldMap numericFieldMap ,
1925+ JBBPArraySizeLimiter arraySizeLimiter )
1926+ throws IOException {
1927+ fail ("Must not be called" );
1928+ return null ;
1929+ }
1930+
1931+ @ Override
1932+ public JBBPAbstractField readVarField (JBBPBitInputStream inStream ,
1933+ JBBPNamedFieldInfo fieldName , int extraValue ,
1934+ JBBPByteOrder byteOrder ,
1935+ JBBPNamedNumericFieldMap numericFieldMap )
1936+ throws IOException {
1937+ fail ("Must not be called" );
1938+ return null ;
1939+ }
1940+ }, null );
1941+ assertEquals (0x01020304 , parsed .findFieldForNameAndType ("end" , JBBPFieldInt .class ).getAsInt ());
1942+ }
1943+
19201944 @ Test
19211945 public void testParse_FixedDoubleArray_Default () throws Exception {
19221946 final JBBPFieldArrayDouble longs = JBBPParser .prepare ("doublej[2];" ).parse (
1923- new byte [] {(byte ) 0xF7 , 0x43 , 0x65 , 0x10 , 0x35 , 0x23 , 0x67 , (byte ) 0xA0 , 0x32 , 0x33 , 0x61 ,
1924- (byte ) 0xCA , (byte ) 0xBE , 0x22 , 0x12 , 0x30 })
1947+ new byte [] {(byte ) 0xF7 , 0x43 , 0x65 , 0x10 , 0x35 , 0x23 , 0x67 , (byte ) 0xA0 , 0x32 , 0x33 , 0x61 ,
1948+ (byte ) 0xCA , (byte ) 0xBE , 0x22 , 0x12 , 0x30 })
19251949 .findFieldForType (JBBPFieldArrayDouble .class );
19261950 assertEquals (2 , longs .size ());
19271951 assertEquals (-3.126878492655484E266d , longs .getAsDouble (0 ), TestUtils .FLOAT_DELTA );
@@ -1931,8 +1955,8 @@ public void testParse_FixedDoubleArray_Default() throws Exception {
19311955 @ Test
19321956 public void testParse_FixedDoubleArray_BigEndian () throws Exception {
19331957 final JBBPFieldArrayDouble longs = JBBPParser .prepare (">doublej[2];" ).parse (
1934- new byte [] {(byte ) 0xF7 , 0x43 , 0x65 , 0x10 , 0x35 , 0x23 , 0x67 , (byte ) 0xA0 , 0x32 , 0x33 , 0x61 ,
1935- (byte ) 0xCA , (byte ) 0xBE , 0x22 , 0x12 , 0x30 })
1958+ new byte [] {(byte ) 0xF7 , 0x43 , 0x65 , 0x10 , 0x35 , 0x23 , 0x67 , (byte ) 0xA0 , 0x32 , 0x33 , 0x61 ,
1959+ (byte ) 0xCA , (byte ) 0xBE , 0x22 , 0x12 , 0x30 })
19361960 .findFieldForType (JBBPFieldArrayDouble .class );
19371961 assertEquals (2 , longs .size ());
19381962 assertEquals (-3.126878492655484E266d , longs .getAsDouble (0 ), TestUtils .FLOAT_DELTA );
@@ -1942,8 +1966,8 @@ public void testParse_FixedDoubleArray_BigEndian() throws Exception {
19421966 @ Test
19431967 public void testParse_FixedDoubleArray_LittleEndian () throws Exception {
19441968 final JBBPFieldArrayDouble longs = JBBPParser .prepare ("<doublej[2];" ).parse (
1945- new byte [] {(byte ) 0xF7 , 0x43 , 0x65 , 0x10 , 0x35 , 0x23 , 0x67 , (byte ) 0xA0 , 0x32 , 0x33 , 0x61 ,
1946- (byte ) 0xCA , (byte ) 0xBE , 0x22 , 0x12 , 0x30 })
1969+ new byte [] {(byte ) 0xF7 , 0x43 , 0x65 , 0x10 , 0x35 , 0x23 , 0x67 , (byte ) 0xA0 , 0x32 , 0x33 , 0x61 ,
1970+ (byte ) 0xCA , (byte ) 0xBE , 0x22 , 0x12 , 0x30 })
19471971 .findFieldForType (JBBPFieldArrayDouble .class );
19481972 assertEquals (2 , longs .size ());
19491973 assertEquals (-1.3805405664501578E-152d , longs .getAsDouble (0 ), TestUtils .FLOAT_DELTA );
@@ -1953,8 +1977,8 @@ public void testParse_FixedDoubleArray_LittleEndian() throws Exception {
19531977 @ Test
19541978 public void testParse_NonFixedDoubleArray_Default () throws Exception {
19551979 final JBBPFieldArrayDouble longs = JBBPParser .prepare ("doublej[_];" ).parse (
1956- new byte [] {(byte ) 0xF7 , 0x43 , 0x65 , 0x10 , 0x35 , 0x23 , 0x67 , (byte ) 0xA0 , 0x32 , 0x33 , 0x61 ,
1957- (byte ) 0xCA , (byte ) 0xBE , 0x22 , 0x12 , 0x30 })
1980+ new byte [] {(byte ) 0xF7 , 0x43 , 0x65 , 0x10 , 0x35 , 0x23 , 0x67 , (byte ) 0xA0 , 0x32 , 0x33 , 0x61 ,
1981+ (byte ) 0xCA , (byte ) 0xBE , 0x22 , 0x12 , 0x30 })
19581982 .findFieldForType (JBBPFieldArrayDouble .class );
19591983 assertEquals (2 , longs .size ());
19601984 assertEquals (-3.126878492655484E266d , longs .getAsDouble (0 ), TestUtils .FLOAT_DELTA );
@@ -1964,25 +1988,14 @@ public void testParse_NonFixedDoubleArray_Default() throws Exception {
19641988 @ Test
19651989 public void testParse_NonFixedDoubleArray_BigEndian () throws Exception {
19661990 final JBBPFieldArrayDouble longs = JBBPParser .prepare (">doublej[_];" ).parse (
1967- new byte [] {(byte ) 0xF7 , 0x43 , 0x65 , 0x10 , 0x35 , 0x23 , 0x67 , (byte ) 0xA0 , 0x32 , 0x33 , 0x61 ,
1968- (byte ) 0xCA , (byte ) 0xBE , 0x22 , 0x12 , 0x30 })
1991+ new byte [] {(byte ) 0xF7 , 0x43 , 0x65 , 0x10 , 0x35 , 0x23 , 0x67 , (byte ) 0xA0 , 0x32 , 0x33 , 0x61 ,
1992+ (byte ) 0xCA , (byte ) 0xBE , 0x22 , 0x12 , 0x30 })
19691993 .findFieldForType (JBBPFieldArrayDouble .class );
19701994 assertEquals (2 , longs .size ());
19711995 assertEquals (-3.126878492655484E266d , longs .getAsDouble (0 ), TestUtils .FLOAT_DELTA );
19721996 assertEquals (7.189183308668011E-67d , longs .getAsDouble (1 ), TestUtils .FLOAT_DELTA );
19731997 }
19741998
1975- @ Test
1976- public void testParse_NonFixedDoubleArray_LittleEndian () throws Exception {
1977- final JBBPFieldArrayDouble longs = JBBPParser .prepare ("<doublej[_];" ).parse (
1978- new byte [] {(byte ) 0xF7 , 0x43 , 0x65 , 0x10 , 0x35 , 0x23 , 0x67 , (byte ) 0xA0 , 0x32 , 0x33 , 0x61 ,
1979- (byte ) 0xCA , (byte ) 0xBE , 0x22 , 0x12 , 0x30 })
1980- .findFieldForType (JBBPFieldArrayDouble .class );
1981- assertEquals (2 , longs .size ());
1982- assertEquals (-1.3805405664501578E-152 , longs .getAsDouble (0 ), TestUtils .FLOAT_DELTA );
1983- assertEquals (3.915579175603706E-77 , longs .getAsDouble (1 ), TestUtils .FLOAT_DELTA );
1984- }
1985-
19861999 @ Test
19872000 public void testParse_VarBitArray () throws Exception {
19882001 final JBBPFieldArrayBit array =
@@ -2251,13 +2264,14 @@ public void testParse_EmptyStructArrayInsideStruct_WholeStream() throws Exceptio
22512264 }
22522265
22532266 @ Test
2254- public void testParse_SkipStructureForZeroItems () throws Exception {
2255- final JBBPFieldStruct parsed = JBBPParser .prepare (
2256- "byte len; sss [len]{ sss2[10]{ sss3{long;} sss4[45]{ushort; bool [11]; short; bit:4;} byte;}} byte end;" )
2257- .parse (new byte [] {0x00 , 0x1F });
2258- assertEquals (0 , parsed .findFieldForPathAndType ("len" , JBBPFieldByte .class ).getAsInt ());
2259- assertEquals (0 , parsed .findFieldForPathAndType ("sss" , JBBPFieldArrayStruct .class ).size ());
2260- assertEquals (0x1F , parsed .findFieldForPathAndType ("end" , JBBPFieldByte .class ).getAsInt ());
2267+ public void testParse_NonFixedDoubleArray_LittleEndian () throws Exception {
2268+ final JBBPFieldArrayDouble longs = JBBPParser .prepare ("<doublej[_];" ).parse (
2269+ new byte [] {(byte ) 0xF7 , 0x43 , 0x65 , 0x10 , 0x35 , 0x23 , 0x67 , (byte ) 0xA0 , 0x32 , 0x33 , 0x61 ,
2270+ (byte ) 0xCA , (byte ) 0xBE , 0x22 , 0x12 , 0x30 })
2271+ .findFieldForType (JBBPFieldArrayDouble .class );
2272+ assertEquals (2 , longs .size ());
2273+ assertEquals (-1.3805405664501578E-152 , longs .getAsDouble (0 ), TestUtils .FLOAT_DELTA );
2274+ assertEquals (3.915579175603706E-77 , longs .getAsDouble (1 ), TestUtils .FLOAT_DELTA );
22612275 }
22622276
22632277 @ Test
@@ -2491,6 +2505,16 @@ public void testConvertToSrc_Java_DefaultPackage() {
24912505 assertTrue (src .get (0 ).getResult ().get ("SomeClass.java" ).length () > 128 );
24922506 }
24932507
2508+ @ Test
2509+ public void testParse_SkipStructureForZeroItems () throws Exception {
2510+ final JBBPFieldStruct parsed = JBBPParser .prepare (
2511+ "byte len; sss [len]{ sss2[10]{ sss3{long;} sss4[45]{ushort; bool [11]; short; bit:4;} byte;}} byte end;" )
2512+ .parse (new byte [] {0x00 , 0x1F });
2513+ assertEquals (0 , parsed .findFieldForPathAndType ("len" , JBBPFieldByte .class ).getAsInt ());
2514+ assertEquals (0 , parsed .findFieldForPathAndType ("sss" , JBBPFieldArrayStruct .class ).size ());
2515+ assertEquals (0x1F , parsed .findFieldForPathAndType ("end" , JBBPFieldByte .class ).getAsInt ());
2516+ }
2517+
24942518 @ Test
24952519 public void testUintUseInExpression () throws Exception {
24962520 final JBBPParser parser = JBBPParser .prepare ("uint length; uint[(length * 2) >> 1] array;" );
@@ -2504,11 +2528,86 @@ public void testUintUseInExpression() throws Exception {
25042528 assertEquals (2 , length .getAsInt ());
25052529 assertEquals (2 , array .size ());
25062530
2507- JBBPNumericFieldValueConversionException exception = assertThrows (JBBPNumericFieldValueConversionException .class , () -> array .getElementAt (0 ).getAsInt ());
2531+ JBBPNumericFieldValueConversionException exception =
2532+ assertThrows (JBBPNumericFieldValueConversionException .class ,
2533+ () -> array .getElementAt (0 ).getAsInt ());
25082534 assertTrue (exception .toString ().contains ("0xFFF0E012" ));
25092535
25102536 assertEquals (0xFFF0E012L , array .getElementAt (0 ).getAsLong ());
25112537 assertEquals (0x01020304 , array .getElementAt (1 ).getAsInt ());
25122538 }
25132539
2540+ @ Test
2541+ public void testLimitedWholeStreamArrayRead () throws Exception {
2542+ testArrayLimiter_2elementsLimit (TestUtils .getRandomBytes (128 ), "bit:4 [_] test;" , null , null );
2543+ testArrayLimiter_2elementsLimit (TestUtils .getRandomBytes (128 ), "bool [_] test;" , null , null );
2544+ testArrayLimiter_2elementsLimit (TestUtils .getRandomBytes (128 ), "byte [_] test;" , null , null );
2545+ testArrayLimiter_2elementsLimit (TestUtils .getRandomBytes (128 ), "ubyte [_] test;" , null , null );
2546+ testArrayLimiter_2elementsLimit (TestUtils .getRandomBytes (128 ), "short [_] test;" , null , null );
2547+ testArrayLimiter_2elementsLimit (TestUtils .getRandomBytes (128 ), "ushort [_] test;" , null , null );
2548+ testArrayLimiter_2elementsLimit (TestUtils .getRandomBytes (128 ), "int [_] test;" , null , null );
2549+ testArrayLimiter_2elementsLimit (TestUtils .getRandomBytes (128 ), "uint [_] test;" , null , null );
2550+ testArrayLimiter_2elementsLimit (TestUtils .getRandomBytes (128 ), "long [_] test;" , null , null );
2551+ testArrayLimiter_2elementsLimit (TestUtils .getRandomBytes (128 ), "floatj [_] test;" , null , null );
2552+ testArrayLimiter_2elementsLimit (TestUtils .getRandomBytes (128 ), "doublej [_] test;" , null , null );
2553+ testArrayLimiter_2elementsLimit (
2554+ TestUtils .makeStringArray (JBBPByteOrder .BIG_ENDIAN , "hello" , "world" , "one" , "two" , "three" ,
2555+ "four" ), "stringj [_] test;" , null , null );
2556+
2557+ testArrayLimiter_2elementsLimit (TestUtils .getRandomBytes (128 ), "var [_] test;" ,
2558+ new JBBPVarFieldProcessor () {
2559+ @ Override
2560+ public JBBPAbstractArrayField <? extends JBBPAbstractField > readVarArray (
2561+ JBBPBitInputStream inStream , int arraySize , JBBPNamedFieldInfo fieldName ,
2562+ int extraValue , JBBPByteOrder byteOrder , JBBPNamedNumericFieldMap numericFieldMap ,
2563+ JBBPArraySizeLimiter arraySizeLimiter ) throws IOException {
2564+ if (arraySize >= 0 ) {
2565+ throw new IllegalArgumentException ("Expected whole stream read" );
2566+ }
2567+ final byte [] result = inStream .readByteArray (arraySize , arraySizeLimiter );
2568+ return new JBBPFieldArrayByte (fieldName , result );
2569+ }
2570+
2571+ @ Override
2572+ public JBBPAbstractField readVarField (JBBPBitInputStream inStream ,
2573+ JBBPNamedFieldInfo fieldName , int extraValue ,
2574+ JBBPByteOrder byteOrder ,
2575+ JBBPNamedNumericFieldMap numericFieldMap )
2576+ throws IOException {
2577+ throw new UnsupportedOperationException ("Must not be called" );
2578+ }
2579+ }, null );
2580+
2581+ testArrayLimiter_2elementsLimit (TestUtils .getRandomBytes (128 ), "some [_] test;" , null ,
2582+ new JBBPCustomFieldTypeProcessor () {
2583+ @ Override
2584+ public String [] getCustomFieldTypes () {
2585+ return new String [] {"some" };
2586+ }
2587+
2588+ @ Override
2589+ public boolean isAllowed (JBBPFieldTypeParameterContainer fieldType , String fieldName ,
2590+ int extraData , boolean isArray ) {
2591+ return "some" .equals (fieldType .getTypeName ());
2592+ }
2593+
2594+ @ Override
2595+ public JBBPAbstractField readCustomFieldType (JBBPBitInputStream in , JBBPBitOrder bitOrder ,
2596+ int parserFlags ,
2597+ JBBPFieldTypeParameterContainer customTypeFieldInfo ,
2598+ JBBPNamedFieldInfo fieldName , int extraData ,
2599+ boolean readWholeStream , int arrayLength ,
2600+ JBBPArraySizeLimiter arraySizeLimiter )
2601+ throws IOException {
2602+ if (!readWholeStream ) {
2603+ throw new IllegalArgumentException ("Expected only read whole stream array" );
2604+ }
2605+
2606+ final byte [] read = in .readByteArray (-1 , JBBPByteOrder .BIG_ENDIAN , arraySizeLimiter );
2607+ return new JBBPFieldArrayByte (fieldName , read );
2608+ }
2609+ });
2610+
2611+ }
2612+
25142613}
0 commit comments