From 90c3f8f001af7711194be8d8a63ec8e944098cf7 Mon Sep 17 00:00:00 2001 From: Noa Resare Date: Thu, 21 Oct 2021 21:55:06 +0100 Subject: [PATCH] Change semantics of DNSInput.saveActive() Previously, DNSInput.saveActive() would return the active range without taking prior calls to setActive() into account. Add a test case that illustrates the failure that the user experienced, as well as a test case verifying DNSInput semantics when called recursively with ByteBuffers with limit and length set. Please see https://github.com/dnsjava/dnsjava/issues/225 for further details. --- src/main/java/org/xbill/DNS/DNSInput.java | 2 +- src/test/java/org/xbill/DNS/DNSInputTest.java | 39 +++++++++++++++++++ .../java/org/xbill/DNS/OPTRecordTest.java | 21 ++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/xbill/DNS/DNSInput.java b/src/main/java/org/xbill/DNS/DNSInput.java index 5a9d5cad3..abfb3b5bb 100644 --- a/src/main/java/org/xbill/DNS/DNSInput.java +++ b/src/main/java/org/xbill/DNS/DNSInput.java @@ -79,7 +79,7 @@ public void clearActive() { /** Returns the position of the end of the current active region. */ public int saveActive() { - return limit - offset; + return byteBuffer.limit() - offset; } /** diff --git a/src/test/java/org/xbill/DNS/DNSInputTest.java b/src/test/java/org/xbill/DNS/DNSInputTest.java index 1d1b610ff..daf974179 100644 --- a/src/test/java/org/xbill/DNS/DNSInputTest.java +++ b/src/test/java/org/xbill/DNS/DNSInputTest.java @@ -39,6 +39,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.nio.ByteBuffer; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -84,6 +86,19 @@ void setUp() { } } + static class DNSInputByteBufferLimitOffsetTest extends DNSInputBase { + @BeforeEach + void setUp() throws IOException { + m_raw = new byte[] {0, 1, 2, 3, 4, 5, (byte) 255, (byte) 255, (byte) 255, (byte) 255}; + // create a new byte array with a prefix and a suffix to be ignored + ByteArrayOutputStream out = new ByteArrayOutputStream(); + out.write(42); + out.write(m_raw); + out.write(47); + m_di = new DNSInput(ByteBuffer.wrap(out.toByteArray(), 1, 10)); + } + } + @Test void initial_state() { assertEquals(0, m_di.current()); @@ -319,4 +334,28 @@ void readCountedSting() throws WireParseException { assertEquals(3, m_di.current()); assertEquals(2, out[0]); } + + @Test + void setActive_recursive() throws WireParseException { + int outer = m_di.saveActive(); + m_di.setActive(3); + + assertEquals(0x00, m_di.readU8()); + assertEquals(2, m_di.remaining()); + + int inner = m_di.saveActive(); + + m_di.setActive(1); + assertArrayEquals(new byte[] {0x01}, m_di.readByteArray()); + + m_di.restoreActive(inner); + + assertArrayEquals(new byte[] {0x02}, m_di.readByteArray()); + assertEquals(0, m_di.remaining()); + + m_di.restoreActive(outer); + + assertEquals(0x03, m_di.readU8()); + assertEquals(6, m_di.remaining()); + } } diff --git a/src/test/java/org/xbill/DNS/OPTRecordTest.java b/src/test/java/org/xbill/DNS/OPTRecordTest.java index f217c086e..adc854bbb 100644 --- a/src/test/java/org/xbill/DNS/OPTRecordTest.java +++ b/src/test/java/org/xbill/DNS/OPTRecordTest.java @@ -6,7 +6,10 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import java.io.IOException; +import java.util.Collections; import org.junit.jupiter.api.Test; +import org.xbill.DNS.utils.base16; class OPTRecordTest { @@ -47,6 +50,24 @@ void rdataFromString() { assertTrue(thrown.getMessage().contains("no text format defined for OPT")); } + @Test + void rdataFromWire() throws IOException { + byte[] buf = base16.fromString("000029100000000000000C000A00084531D089BA80C6EB"); + OPTRecord record = (OPTRecord) OPTRecord.fromWire(new DNSInput(buf), Section.ADDITIONAL); + assertEquals( + Collections.singletonList(new CookieOption(base16.fromString("4531D089BA80C6EB"))), + record.getOptions()); + } + + @Test + void rdataFromWire_nullPadded() throws IOException { + byte[] buf = base16.fromString("000029100000000000000C000A00084531D089BA80C6EB00"); + OPTRecord record = (OPTRecord) OPTRecord.fromWire(new DNSInput(buf), Section.ADDITIONAL); + assertEquals( + Collections.singletonList(new CookieOption(base16.fromString("4531D089BA80C6EB"))), + record.getOptions()); + } + private void assertNotEqual(final OPTRecord optRecordOne, final OPTRecord optRecordTwo) { assertFalse(optRecordOne.equals(optRecordTwo)); assertFalse(optRecordTwo.equals(optRecordOne));