ber-tlv icon indicating copy to clipboard operation
ber-tlv copied to clipboard

Custom buffer size ignored when adding BerTlv to BerTlvBuilder

Open eriknellessen opened this issue 4 years ago • 4 comments

The following code will lead to an error, if myBerTlv has a value that has over 5120 bytes:

BerTlvBuilder berTlvBuilder = new BerTlvBuilder(myBerTlv.getTag(),
                                                        new byte[1000000],
                                                        0,
                                                        1000000);
byte[] bytes = berTlvBuilder.addBerTlv(myBerTlv);

The exception I got was:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
	at java.lang.System.arraycopy(Native Method)
	at com.payneteasy.tlv.BerTlvBuilder.addBytes(BerTlvBuilder.java:178)
	at com.payneteasy.tlv.BerTlvBuilder.addBytes(BerTlvBuilder.java:162)
	at com.payneteasy.tlv.BerTlvBuilder.addBerTlv(BerTlvBuilder.java:196)
	at com.payneteasy.tlv.BerTlvBuilder.from(BerTlvBuilder.java:45)
	at com.payneteasy.tlv.BerTlvBuilder.addBerTlv(BerTlvBuilder.java:194)
	at com.payneteasy.tlv.BerTlvBuilder.from(BerTlvBuilder.java:45)
	at com.payneteasy.tlv.BerTlvBuilder.addBerTlv(BerTlvBuilder.java:194)
	at com.payneteasy.tlv.BerTlvBuilder.from(BerTlvBuilder.java:45)
	at com.payneteasy.tlv.BerTlvBuilder.addBerTlv(BerTlvBuilder.java:194)
	at com.payneteasy.tlv.BerTlvBuilder.from(BerTlvBuilder.java:45)
	at com.payneteasy.tlv.BerTlvBuilder.addBerTlv(BerTlvBuilder.java:194)

When using the addBerTlv method, the code eventually calls public BerTlvBuilder(BerTag aTemplate), a method that overwrites the custom buffer with the default settings.

eriknellessen avatar Oct 24 '19 12:10 eriknellessen

I now understood that what I wanted to do was rather this:

BerTlvBuilder berTlvBuilder = BerTlvBuilder.from(myBerTlv);

Anyhow, this leaves no possibility to configure a custom buffer size. With elements over 5120 bytes (and I do have to handle those), it will lead to the exception posted above.

eriknellessen avatar Oct 24 '19 13:10 eriknellessen

Hi,

Here is the tests for your issue:

new BerTlvBuilder(null, new byte[bufferSize], 0, bufferSize);

    @Test
    public void test_large_value_with_error() {
        try {
            BerTlvBuilder builder = new BerTlvBuilder();
            builder.addBytes(new BerTag(0x82), new byte[6 * 1024]);
            Assert.fail("Should throw ArrayIndexOutOfBoundsException because default buffer size is 5KB");
        } catch (ArrayIndexOutOfBoundsException e) {
            Assert.assertNull(e.getMessage());
        }
    }

    @Test
    public void test_large_value() {
        final int     sixKilobytes = 6 * 1024;
        final int     tagLength    = 1;
        final int     valueLength  = 3;
        final int     bufferSize   = sixKilobytes + tagLength + valueLength;

        BerTlvBuilder builder = new BerTlvBuilder(null, new byte[bufferSize], 0, bufferSize);
        builder.addBytes(new BerTag(0x82), new byte[sixKilobytes]);

        byte[] bytes = builder.buildArray();
        Assert.assertEquals(bufferSize, bytes.length);
    }

It seems that we can use large buffer size for elements more the 5kb.

evsinev avatar Oct 28 '19 23:10 evsinev

Hi,

thanks for your response. As far as I can see, you use the addBytes method, not the addBerTlv method. The addBytes method does not lead to the error, as far as I can see.

A test like this should lead to the error (I did not compile or test this code, just trying to give the idea):

@Test
public void test_large_value() {
    final int     sixKilobytes = 6 * 1024;
    final int     tagLength    = 1;
    final int     valueLength  = 3;
    final int     bufferSize   = sixKilobytes + tagLength + valueLength;

    BerTlvBuilder builder = new BerTlvBuilder(null, new byte[bufferSize], 0, bufferSize);
    BerTlv berTlv = new BerTlv(new BerTag(0x82), new byte[sixKilobytes]);
    builder.addBerTlv(berTlv);

    byte[] bytes = builder.buildArray();
    Assert.assertEquals(bufferSize, bytes.length);
}

eriknellessen avatar Oct 29 '19 08:10 eriknellessen

I tried the test code I posted and found out that it did not reproduce the problem, because the BerTlv was not constructed.

I created a pull request with a test reproducing the problem and proposing a solution: #14

eriknellessen avatar Nov 08 '19 14:11 eriknellessen