36 lines
2.1 KiB
Diff
36 lines
2.1 KiB
Diff
# UNDF: UNDF-2026-000000830
|
|
# UNDF:
|
|
# Defect: netty-0002
|
|
# Component: io.netty.resolver.dns.DnsResolveContext
|
|
# Pattern: CWE-407 — ArrayList.contains() for DNS result deduplication
|
|
# Severity: MEDIUM
|
|
# Complexity: O(R²) per DNS resolution → O(R) with companion HashSet
|
|
# Description: DnsResolveContext accumulates resolved addresses into
|
|
# finalResult (an ArrayList) and calls finalResult.contains(converted)
|
|
# to deduplicate. With R results, this is O(R²). The code comment
|
|
# acknowledges HashSet would be ideal but chooses ArrayList to avoid
|
|
# "extra memory copy and allocations" — but the O(R²) scan cost
|
|
# dominates for responses with many records (e.g., CDN domains with
|
|
# 50+ A records). Fix: maintain a companion HashSet for O(1) dedup
|
|
# while keeping the ArrayList for ordered result access.
|
|
--- a/resolver-dns/src/main/java/io/netty/resolver/dns/DnsResolveContext.java
|
|
+++ b/resolver-dns/src/main/java/io/netty/resolver/dns/DnsResolveContext.java
|
|
@@ -905,10 +905,11 @@
|
|
if (!promise.isDone()) {
|
|
- // We want to ensure we do not have duplicates in finalResult as this may be unexpected.
|
|
- //
|
|
- // While using a LinkedHashSet or HashSet may sound like the perfect fit for this we will use an
|
|
- // ArrayList here as duplicates should be found quite unfrequently in the wild and we dont want to pay
|
|
- // for the extra memory copy and allocations in this cases later on.
|
|
+ // Deduplicate with a companion HashSet for O(1) membership test.
|
|
+ // The ArrayList is retained for ordered access.
|
|
if (finalResult == null) {
|
|
finalResult = new ArrayList<T>(8);
|
|
+ finalResultSet = new HashSet<T>(8);
|
|
finalResult.add(converted);
|
|
- } else if (isDuplicateAllowed() || !finalResult.contains(converted)) {
|
|
+ finalResultSet.add(converted);
|
|
+ } else if (isDuplicateAllowed() || !finalResultSet.contains(converted)) {
|
|
finalResult.add(converted);
|
|
+ finalResultSet.add(converted);
|
|
} else {
|