Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception thrown if trying to join all IPv4 and all IPv6 addresses #86

Closed
dbardbar opened this issue May 29, 2022 · 5 comments
Closed

Comments

@dbardbar
Copy link

I'm ipaddress version 5.3.4 on Java 8.

My use-case is that I have multiple ranges of IPs, both IPv4 and IPv6 (possibly with various overlaps), and I want to compact them all, and later do a binary search on the sorted array given by IPAddressSeqRange.join() to quickly check if a given IP (v4 or v6) is in any of those ranges.
join() seems to work fine with a mix of IPv4 and IPv6, but I encountered one annoying edge case where the ranges span all possible v4 and v6 addresses.

I have not encountered problems when trying to join full IPv4 range with additional ranges. As far as I can see this is the only problematic edge case.

I get an exception of

1, IP Address error: exceeds address size
inet.ipaddr.AddressValueException: 1, IP Address error: exceeds address size
at inet.ipaddr.format.standard.AddressDivisionGrouping.checkOverflow(AddressDivisionGrouping.java:1204)
at inet.ipaddr.ipv4.IPv4AddressSection.increment(IPv4AddressSection.java:1209)
at inet.ipaddr.ipv4.IPv4Address.increment(IPv4Address.java:717)
at inet.ipaddr.ipv4.IPv4Address.increment(IPv4Address.java:70)
at inet.ipaddr.IPAddressSeqRange.join(IPAddressSeqRange.java:668)

Provided is a test case that causes the exception

@Test
void bugExample() {
	IPAddress minIpv4 = new IPAddressString("0.0.0.0").getAddress();
	IPAddress maxIpv4 = new IPAddressString("255.255.255.255").getAddress();
	IPAddress minIpv6 = new IPAddressString("0::0").getAddress();
	IPAddress maxIpv6 = new IPAddressString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").getAddress();
	IPAddressSeqRange allIpv4 = minIpv4.spanWithRange(maxIpv4);
	IPAddressSeqRange allIpv6 = minIpv6.spanWithRange(maxIpv6);
	IPAddressSeqRange.join(allIpv4, allIpv6);
}
@seancfoley
Copy link
Owner

seancfoley commented May 29, 2022

Yes, this is a bug. Thanks for providing the test case. The issue will happen when joining both IPv4 and IPv6 ranges, and one of the IPv4 ranges includes the address 255.255.255.255.

I will have this fixed in a maintenance release soon. In the meantime, you could use the following work-around which is almost as efficient as the original:

static IPAddressSeqRange[] workAroundJoin(IPAddressSeqRange... ranges) {
	boolean useWorkAround = false;
	boolean hasMaxIPv4 = false;
	boolean hasIPv6 = false;
	for(IPAddressSeqRange rng : ranges) {
		if(rng == null) {
			continue;
		}
		IPAddress upper = rng.getUpper();
		hasMaxIPv4 = hasMaxIPv4 || (upper.isIPv4() && upper.includesMax());
		hasIPv6 = hasIPv6 || upper.isIPv6();
		useWorkAround = hasMaxIPv4 && hasIPv6;
		if(useWorkAround) {
			break;
		}
	}
	if(!useWorkAround) {
		// joining the ranges will not throw
		return IPAddressSeqRange.join(ranges);
	}
	// joining the ranges will throw, use work-around
	IPAddressSeqRange ranges1[] = new IPAddressSeqRange[ranges.length];
	IPAddressSeqRange ranges2[] = new IPAddressSeqRange[ranges.length];
	int i1 = 0, i2 = 0;
	for(IPAddressSeqRange rng : ranges) {
		if(rng == null) {
			continue;
		} else if(rng.getLower().isIPv4()) {
			ranges1[i1++] = rng;
		} else {
			ranges2[i2++] = rng;
		}
	}
	ranges1 = IPAddressSeqRange.join(ranges1);
	ranges2 = IPAddressSeqRange.join(ranges2);
	IPAddressSeqRange ranges3[] = new IPAddressSeqRange[ranges1.length + ranges2.length];
	System.arraycopy(ranges1, 0, ranges3, 0, ranges1.length);
	System.arraycopy(ranges2, 0, ranges3, ranges1.length, ranges2.length);
	return ranges3;
}

@dbardbar
Copy link
Author

dbardbar commented May 29, 2022

Thanks for prompt response.
I did the same workaround. Separated the ranges by family, join()-ed each one, and then combined the two resulting arrays.

@dbardbar
Copy link
Author

dbardbar commented Nov 1, 2022

Hey @seancfoley, any news on this?

@seancfoley
Copy link
Owner

@dbardbar I have not yet released the next maintenance release, but it is certainly time to do so, so I should get to it within a month.

@seancfoley
Copy link
Owner

Took a bit longer than a month. This was fixed in version 5.4.0. Closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants