8000 Fix NPE in SimpleResolver (#277) · dnsjava/dnsjava@bd5177d · GitHub
[go: up one dir, main page]

Skip to content

Commit bd5177d

Browse files
authored
Fix NPE in SimpleResolver (#277)
When reading a response that is REFUSED with no more data. The code could crash while comparing the DNS query with the response. This change skips the comparison if the response is denied. Co-authored-by: mikbergl <mikael.berglund@tele2.com>
1 parent 442fff4 commit bd5177d

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed

src/main/java/org/xbill/DNS/SimpleResolver.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,12 @@ CompletableFuture<Message> sendAsync(Message query, boolean forceTcp, Executor e
402402
return f;
403403
}
404404

405+
if (response.getQuestion() == null) {
406+
f.completeExceptionally(
407+
new WireParseException("invalid message: question section missing"));
408+
return f;
409+
}
410+
405411
// validate name, class and type (rfc5452#section-9.1)
406412
if (!query.getQuestion().getName().equals(response.getQuestion().getName())) {
407413
f.completeExceptionally(
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
package org.xbill.DNS;
3+
4+
import static org.junit.jupiter.api.Assertions.*;
5+
import static org.mockito.ArgumentMatchers.any;
6+
import static org.mockito.ArgumentMatchers.anyInt;
7+
8+
import java.io.IOException;
9+
import java.net.InetSocketAddress;
10+
import java.time.Duration;
11+
import java.util.concurrent.CompletableFuture;
12+
import org.junit.jupiter.api.Test;
13+
import org.mockito.MockedStatic;
14+
import org.mockito.Mockito;
15+
16+
class SimpleResolverDeniedTest {
17+
18+
@Test
19+
void emptyResponseShouldThrowWireParseException() throws IOException {
20+
21+
Name zone = Name.fromString("example.");
22+
Message query = Message.newUpdate(zone);
23+
Record record =
24+
new CNAMERecord(Name.fromString("www", zone), DClass.IN, 300, Name.fromString("example."));
25+
query.addRecord(record, Section.UPDATE);
26+
27+
try (MockedStatic<NioUdpClient> udpClient = Mockito.mockStatic(NioUdpClient.class)) {
28+
udpClient
29+
.when(
30+
() ->
31+
NioUdpClient.sendrecv(
32+
any(),
33+
any(InetSocketAddress.class),
34+
any(byte[].class),
35+
anyInt(),
36+
any(Duration.class)))
37+
.thenAnswer(
38+
a -> {
39+
Message qparsed = new Message(a.getArgument(2, byte[].class));
40+
41+
int id = qparsed.getHeader().getID();
42+
Message response = new Message(id);
43+
response.getHeader().setRcode(Rcode.REFUSED);
44+
byte[] rbytes = response.toWire(Message.MAXLENGTH);
45+
46+
// This was the exact format returned by denying server
47+
assertArrayEquals(
48+
rbytes,
49+
new byte[] {(byte) (id >>> 8), (byte) id, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0});
50+
51+
CompletableFuture<byte[]> f = new CompletableFuture<>();
52+
f.complete(rbytes);
53+
return f;
54+
});
55+
56+
SimpleResolver simpleResolver = new SimpleResolver("127.0.0.1");
57+
58+
assertThrows(WireParseException.class, () -> simpleResolver.send(query));
59+
}
60+
}
61+
}

0 commit comments

Comments
 (0)
0