From 84f6470e43578bfdc0f57f3083e5924572e88a57 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Wed, 15 Jan 2014 12:18:58 -0800 Subject: [PATCH] fix address ranges for sites with old NetAddr::IP versions, #26868 --- FS/FS/addr_range.pm | 21 ++++++++++----------- httemplate/edit/process/addr_range.html | 5 +++++ 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/FS/FS/addr_range.pm b/FS/FS/addr_range.pm index 3cf746f7d..1a8484fb6 100644 --- a/FS/FS/addr_range.pm +++ b/FS/FS/addr_range.pm @@ -149,10 +149,10 @@ sub end { $self->set('start', $end); ($end, $start) = ($start, $end); } - # bigints are PROBABLY not needed here...but if someone wants to exclude - # all the address space not assigned to them, for example, that could be - # a pretty large part of IPv4. - $self->set('length', $end->bigint - $start->bigint + 1); + # fails if $end - $start > 2^31 + # so don't do that + # (fixed in NetAddr::IP 4.050 but we can't rely on that, apparently) + $self->set('length', $end - $start + 1); return $end->addr; } my $end = $start + $self->get('length') - 1; @@ -173,7 +173,7 @@ sub contains { my $start = NetAddr::IP->new($self->start, 0); - return ($addr >= $start and $addr->bigint - $start->bigint < $self->length) + return ($addr >= $start and $addr < ( $start + $self->length) ) ? 1 : 0; } @@ -186,7 +186,7 @@ Returns a readable string showing the address range. sub as_string { my $self = shift; my $start = NetAddr::IP->new($self->start, 0); - my $end = $start + $self->length; + my $end = $start + $self->length - 1; if ( $self->length == 1 ) { # then just the address @@ -248,11 +248,10 @@ sub any_contains { L objects have netmasks. They also have overloaded operators for addition and subtraction, but those have range limitations when comparing addresses. (An IPv4 address is effectively a uint32; the difference -between two IPv4 addresses is the same range, but signed.) Therefore, -the distance between two addresses should be calculated using the -C method ($addr2->bigint - $addr1->bigint), which returns the -address as a L object, and also conveniently discards the -netmask. +between two IPv4 addresses is the same range, but signed.) In later versions +of the library the C method can be used as a workaround, but +otherwise it's not safe to subtract two addresses that might differ in the +first bit of the first octet. =head1 BUGS diff --git a/httemplate/edit/process/addr_range.html b/httemplate/edit/process/addr_range.html index 6b05d23a5..5df05596e 100644 --- a/httemplate/edit/process/addr_range.html +++ b/httemplate/edit/process/addr_range.html @@ -13,6 +13,11 @@ $cgi->param('end', $end->addr); $cgi->param('start', $start->addr); } + if ( $start + 0x7FFFFFFF <= $end ) { + # then this is going to overflow + return "Address ranges must be < 2^31 - 1 addresses long." + } + $cgi->param('length', $end - $start + 1); } else { $cgi->param('length', 1); -- 2.11.0