From 5f6bdef7604cd9e787da1d9ebd55d1d660ad98e3 Mon Sep 17 00:00:00 2001 From: Erik Nellessen Date: Fri, 8 Nov 2019 15:28:34 +0100 Subject: [PATCH] \#13: Add possibility to add large constructed TLV elements to BerTlvBuilder --- .../com/payneteasy/tlv/BerTlvBuilder.java | 17 +++++++--- .../com/payneteasy/tlv/BerTlvBuilderTest.java | 34 +++++++++++++++++++ 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/payneteasy/tlv/BerTlvBuilder.java b/src/main/java/com/payneteasy/tlv/BerTlvBuilder.java index f9857b4..e052c21 100644 --- a/src/main/java/com/payneteasy/tlv/BerTlvBuilder.java +++ b/src/main/java/com/payneteasy/tlv/BerTlvBuilder.java @@ -39,19 +39,27 @@ public BerTlvBuilder(BerTag aTemplate, byte[] aBuffer, int aOffset, int aLength) } public static BerTlvBuilder from(BerTlv aTlv) { + return from(aTlv, DEFAULT_SIZE); + } + + public static BerTlvBuilder from(BerTlv aTlv, int bufferSize) { if(aTlv.isConstructed()) { - BerTlvBuilder builder = template(aTlv.getTag()); + BerTlvBuilder builder = template(aTlv.getTag(), bufferSize); for (BerTlv tlv : aTlv.theList) { builder.addBerTlv(tlv); } return builder; } else { - return new BerTlvBuilder().addBerTlv(aTlv); + return new BerTlvBuilder(null, new byte[bufferSize], 0, bufferSize).addBerTlv(aTlv); } } public static BerTlvBuilder template(BerTag aTemplate) { - return new BerTlvBuilder(aTemplate); + return template(aTemplate, DEFAULT_SIZE); + } + + public static BerTlvBuilder template(BerTag aTemplate, int bufferSize) { + return new BerTlvBuilder(aTemplate, new byte[bufferSize], 0, bufferSize); } public BerTlvBuilder addEmpty(BerTag aObject) { @@ -191,7 +199,7 @@ public BerTlvBuilder add(BerTlvBuilder aBuilder) { public BerTlvBuilder addBerTlv(BerTlv aTlv) { if(aTlv.isConstructed()) { - return add(from(aTlv)); + return add(from(aTlv, theBuffer.length)); } else { return addBytes(aTlv.getTag(), aTlv.getBytesValue()); } @@ -252,4 +260,3 @@ public BerTlvs buildTlvs() { private final byte[] theBuffer; private final BerTag theTemplate; } - diff --git a/src/test/java/com/payneteasy/tlv/BerTlvBuilderTest.java b/src/test/java/com/payneteasy/tlv/BerTlvBuilderTest.java index a10544e..d5fc406 100644 --- a/src/test/java/com/payneteasy/tlv/BerTlvBuilderTest.java +++ b/src/test/java/com/payneteasy/tlv/BerTlvBuilderTest.java @@ -3,6 +3,7 @@ import org.junit.Assert; import org.junit.Test; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -184,6 +185,39 @@ public void testBigData() { Assert.assertEquals(1, berTlvs.getList().size()); } + @Test + public void test_large_value_with_error() { + try { + BerTlvBuilder builder = new BerTlvBuilder(); + BerTlv berTlv = new BerTlv(new BerTag(0x82), new byte[6 * 1024]); + builder.addBerTlv(berTlv); + 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 sequenceHeaderSize = 4; + final int bufferSize = sequenceHeaderSize + sixKilobytes + tagLength + valueLength; + + BerTlv sequenceContent = new BerTlv(new BerTag(0x82), new byte[sixKilobytes]); + ArrayList berTlvs = new ArrayList(); + berTlvs.add(sequenceContent); + BerTlv sequence = new BerTlv(new BerTag(0x30), + berTlvs); + + BerTlvBuilder builder = new BerTlvBuilder(null, new byte[bufferSize], 0, bufferSize); + builder.addBerTlv(sequence); + + byte[] bytes = builder.buildArray(); + Assert.assertEquals(bufferSize, bytes.length); + } + @Test public void test_empty() { BerTlv tlv = new BerTlv(new BerTag(0x01), new byte[]{});