Correctly supersede same-prefix CIDR nodes. Fixes #3565. Closes #3573

This commit is contained in:
dmiller 2026-10-29 17:49:14 +00:00
parent ec562e9e8b
commit 0b2b71a97c
3 changed files with 46 additions and 2 deletions

View file

@ -1,5 +1,9 @@
#Nmap Changelog ($Id$); -*-text-*-
o [GH#3565][GH#3573] Fixed an issue with addrset: When a CIDR spec was added
after a narrower one, its prefix exactly the common prefix of the two, the
addrset trie did not cover the whole broader range. [Dennys Kaluzny Pereira]
Nmap 7.993 [2026-10-23]
o [NSE][GH#3557] Fixed a regression which prevented most scripts in the version

View file

@ -331,8 +331,11 @@ static void trie_split (struct trie_node *this, const u32 *addr, const u32 *mask
/* Addrs have more bits in common than we care about for this node. */
new_mask[i] = this->mask[i];
}
if (new_mask[i] > mask[i]) {
/* new addr's mask is broader, so this node is superseded. */
if (new_mask[i] > mask[i]
|| (new_mask[i] == mask[i] && mask[i] != U32_ALL_BITS)) {
/* new addr's mask is no longer than the common prefix, so this node is
* superseded. Equal full words don't count: the new mask continues in
* the next word, so keep comparing. */
this->mask[i] = mask[i];
for (i++; i < 4; i++) {
this->mask[i] = 0;

View file

@ -181,6 +181,43 @@ test_addrset "192.168.0.0/24" "192.168.0.5 192.168.0.90" <<EOF
1.2.3.4
EOF
# Overlapping CIDR netmasks: order must not matter.
test_addrset "10.200.0.0/16 10.0.0.0/8" "10.150.0.20 10.200.1.1 10.0.0.1" <<EOF
10.150.0.20
10.200.1.1
10.0.0.1
11.0.0.1
EOF
test_addrset "10.0.0.0/8 10.200.0.0/16" "10.150.0.20 10.200.1.1 10.0.0.1" <<EOF
10.150.0.20
10.200.1.1
10.0.0.1
11.0.0.1
EOF
test_addrset "10.200.0.0/16 10.0.0.0/16 10.0.0.0/8" "10.150.0.20 10.200.1.1 10.0.0.1" <<EOF
10.150.0.20
10.200.1.1
10.0.0.1
11.0.0.1
EOF
# A broader IPv4 /0 after a narrower spec.
test_addrset "200.0.0.0/16 0.0.0.0/0" "200.1.1.1 200.0.0.1 1.2.3.4" <<EOF
200.1.1.1
200.0.0.1
1.2.3.4
EOF
# Overlapping IPv6 netmasks, with the broader mask on a 32-bit boundary.
test_addrset "1:2:8000::/48 1:2::/32" "1:2::1 1:2:8000::1 1:2:c000::1" <<EOF
1:2::1
1:2:8000::1
1:2:c000::1
1:3::1
EOF
# /32 netmask.
test_addrset "1.2.3.4/32" "1.2.3.4" <<EOF
192.168.0.10