ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:70827] [Ruby trunk - Bug #11531] [Open] IPAddr#== implements wrong logic
       [not found] <redmine.issue-11531.20150916031715@ruby-lang.org>
@ 2015-09-16  3:17 ` panasmeister
  2016-11-06 16:22 ` [ruby-core:78018] [Ruby trunk Bug#11531] " knu
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 7+ messages in thread
From: panasmeister @ 2015-09-16  3:17 UTC (permalink / raw)
  To: ruby-core

Issue #11531 has been reported by Aleksander Panasyuk.

----------------------------------------
Bug #11531: IPAddr#== implements wrong logic
https://bugs.ruby-lang.org/issues/11531

* Author: Aleksander Panasyuk
* Status: Open
* Priority: Normal
* Assignee: 
* ruby -v: 2.1.5p273
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
----------------------------------------
# Description
IPAddr#== should implement the logic of comparison of two IPAddr instances. This generally means that it compares two IP addresses.
Lets look at the code of this method:

https://github.com/ruby/ruby/blob/c8b3f1b470e343e7408ab5883f046b1056d94ccc/lib/ipaddr.rb#L151

`return @family == other.family && @addr == other.to_i`

It returns the result of comparison of the families and the addresses, but it should also compare the netmask which describes the network where this address is located.
The code below shows the test case for this comparison:
`
ip1 = IPAddr.new '195.51.100.0/24'
ip2 = IPAddr.new '195.51.100.0/26'
ip1 == ip2 #=> true
`
This code shows that two identical IP addresses from different networks are equal. But the result should be `false` because these addresses are not identical.

# Possible solution
Depending on Feature #11210 i would propose following implementation of this method:
`
def ==(other)
  other = coerce_other(other)
  return @family == other.family && @addr == other.to_i && @mask_addr == other.netmask
end
`



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [ruby-core:78018] [Ruby trunk Bug#11531] IPAddr#== implements wrong logic
       [not found] <redmine.issue-11531.20150916031715@ruby-lang.org>
  2015-09-16  3:17 ` [ruby-core:70827] [Ruby trunk - Bug #11531] [Open] IPAddr#== implements wrong logic panasmeister
@ 2016-11-06 16:22 ` knu
  2016-11-15 22:28 ` [ruby-core:78160] " bjmllr
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 7+ messages in thread
From: knu @ 2016-11-06 16:22 UTC (permalink / raw)
  To: ruby-core

Issue #11531 has been updated by Akinori MUSHA.


I think this is intentional.  IPAddr represents an IP address, not an IP network, so it does not consider a difference in netmasks as significant.

----------------------------------------
Bug #11531: IPAddr#== implements wrong logic
https://bugs.ruby-lang.org/issues/11531#change-61361

* Author: Aleksander Panasyuk
* Status: Open
* Priority: Normal
* Assignee: 
* ruby -v: 2.1.5p273
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
----------------------------------------
# Description
IPAddr#== should implement the logic of comparison of two IPAddr instances. This generally means that it compares two IP addresses.
Lets look at the code of this method:

https://github.com/ruby/ruby/blob/c8b3f1b470e343e7408ab5883f046b1056d94ccc/lib/ipaddr.rb#L151

`return @family == other.family && @addr == other.to_i`

It returns the result of comparison of the families and the addresses, but it should also compare the netmask which describes the network where this address is located.
The code below shows the test case for this comparison:
`
ip1 = IPAddr.new '195.51.100.0/24'
ip2 = IPAddr.new '195.51.100.0/26'
ip1 == ip2 #=> true
`
This code shows that two identical IP addresses from different networks are equal. But the result should be `false` because these addresses are not identical.

# Possible solution
Depending on Feature #11210 i would propose following implementation of this method:
`
def ==(other)
  other = coerce_other(other)
  return @family == other.family && @addr == other.to_i && @mask_addr == other.netmask
end
`



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [ruby-core:78160] [Ruby trunk Bug#11531] IPAddr#== implements wrong logic
       [not found] <redmine.issue-11531.20150916031715@ruby-lang.org>
  2015-09-16  3:17 ` [ruby-core:70827] [Ruby trunk - Bug #11531] [Open] IPAddr#== implements wrong logic panasmeister
  2016-11-06 16:22 ` [ruby-core:78018] [Ruby trunk Bug#11531] " knu
@ 2016-11-15 22:28 ` bjmllr
  2016-11-23 17:37 ` [ruby-core:78278] " runner
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 7+ messages in thread
From: bjmllr @ 2016-11-15 22:28 UTC (permalink / raw)
  To: ruby-core

Issue #11531 has been updated by Ben Miller.


> it does not consider a difference in netmasks as significant

IPAddr.new isn't consistent with this principle:

```ruby
IPAddr.new("1.2.3.4/24") == IPAddr.new("1.2.3.4/32") # => false
```

1.2.3.4/24 is valid notation for a host address, yet IPAddr.new will drop the low-order bits to make it a valid network address:

```ruby
IPAddr.new("1.2.3.4/24") == IPAddr.new("1.2.3.0/24") # => true
```

I'm not sure why we would want to have a netmask at all if IPAddr is only for host addresses.

----------------------------------------
Bug #11531: IPAddr#== implements wrong logic
https://bugs.ruby-lang.org/issues/11531#change-61517

* Author: Aleksander Panasyuk
* Status: Open
* Priority: Normal
* Assignee: 
* ruby -v: 2.1.5p273
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
----------------------------------------
# Description
IPAddr#== should implement the logic of comparison of two IPAddr instances. This generally means that it compares two IP addresses.
Lets look at the code of this method:

https://github.com/ruby/ruby/blob/c8b3f1b470e343e7408ab5883f046b1056d94ccc/lib/ipaddr.rb#L151

`return @family == other.family && @addr == other.to_i`

It returns the result of comparison of the families and the addresses, but it should also compare the netmask which describes the network where this address is located.
The code below shows the test case for this comparison:
`
ip1 = IPAddr.new '195.51.100.0/24'
ip2 = IPAddr.new '195.51.100.0/26'
ip1 == ip2 #=> true
`
This code shows that two identical IP addresses from different networks are equal. But the result should be `false` because these addresses are not identical.

# Possible solution
Depending on Feature #11210 i would propose following implementation of this method:
`
def ==(other)
  other = coerce_other(other)
  return @family == other.family && @addr == other.to_i && @mask_addr == other.netmask
end
`



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [ruby-core:78278] [Ruby trunk Bug#11531] IPAddr#== implements wrong logic
       [not found] <redmine.issue-11531.20150916031715@ruby-lang.org>
                   ` (2 preceding siblings ...)
  2016-11-15 22:28 ` [ruby-core:78160] " bjmllr
@ 2016-11-23 17:37 ` runner
  2016-11-23 17:40 ` [ruby-core:78279] " runner
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 7+ messages in thread
From: runner @ 2016-11-23 17:37 UTC (permalink / raw)
  To: ruby-core

Issue #11531 has been updated by Steven Hansen.


Akinori MUSHA wrote:
> I think this is intentional.  IPAddr represents an IP address, not an IP network, so it does not consider a difference in netmasks as significant.

I disagree that IPAddr represents an IP address (I think a more accurately represents a CIDR block).  To add to Ben's point:

`
IPAddr.new('128.128.128.128').to_range.to_a # => [#<IPAddr: IPv4:128.128.128.128/255.255.255.255>]
`

`
IPAddr.new('128.128.128.128/30').to_range.to_a # => [#<IPAddr: IPv4:128.128.128.128/255.255.255.252>, #<IPAddr: IPv4:128.128.128.129/255.255.255.252>, #<IPAddr: IPv4:128.128.128.130/255.255.25│
5.252>, #<IPAddr: IPv4:128.128.128.131/255.255.255.252>]
`

The fact that IPAddr accepts a CIDR block mean it represents 1 or more IPs.  So an IPAddr with 1 IP should not be equal to an IPAddr with 4 IPs

----------------------------------------
Bug #11531: IPAddr#== implements wrong logic
https://bugs.ruby-lang.org/issues/11531#change-61645

* Author: Aleksander Panasyuk
* Status: Open
* Priority: Normal
* Assignee: 
* ruby -v: 2.1.5p273
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
----------------------------------------
# Description
IPAddr#== should implement the logic of comparison of two IPAddr instances. This generally means that it compares two IP addresses.
Lets look at the code of this method:

https://github.com/ruby/ruby/blob/c8b3f1b470e343e7408ab5883f046b1056d94ccc/lib/ipaddr.rb#L151

`return @family == other.family && @addr == other.to_i`

It returns the result of comparison of the families and the addresses, but it should also compare the netmask which describes the network where this address is located.
The code below shows the test case for this comparison:
`
ip1 = IPAddr.new '195.51.100.0/24'
ip2 = IPAddr.new '195.51.100.0/26'
ip1 == ip2 #=> true
`
This code shows that two identical IP addresses from different networks are equal. But the result should be `false` because these addresses are not identical.

# Possible solution
Depending on Feature #11210 i would propose following implementation of this method:
`
def ==(other)
  other = coerce_other(other)
  return @family == other.family && @addr == other.to_i && @mask_addr == other.netmask
end
`



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [ruby-core:78279] [Ruby trunk Bug#11531] IPAddr#== implements wrong logic
       [not found] <redmine.issue-11531.20150916031715@ruby-lang.org>
                   ` (3 preceding siblings ...)
  2016-11-23 17:37 ` [ruby-core:78278] " runner
@ 2016-11-23 17:40 ` runner
  2019-10-31 16:51 ` [ruby-core:95611] [Ruby master " merch-redmine
  2019-12-29 12:50 ` [ruby-core:96570] " hsbt
  6 siblings, 0 replies; 7+ messages in thread
From: runner @ 2016-11-23 17:40 UTC (permalink / raw)
  To: ruby-core

Issue #11531 has been updated by Steven Hansen.


Steven Hansen wrote:
> > IPAddr represents an IP address, not an IP network, so it does not consider a difference in netmasks as significant.
> 
> I disagree that IPAddr represents an IP address (I think a more accurately represents a CIDR block).  To add to Ben's point:
> 
> ~~~ ruby
> IPAddr.new('128.128.128.128').to_range.to_a # => [#<IPAddr: IPv4:128.128.128.128/255.255.255.255>]
> ~~~
> 
> ~~~ ruby
> IPAddr.new('128.128.128.128/30').to_range.to_a # => [
  #<IPAddr: IPv4:128.128.128.128/255.255.255.252>, 
  #<IPAddr: IPv4:128.128.128.129/255.255.255.252>, 
  #<IPAddr: IPv4:128.128.128.130/255.255.25│5.252>, 
  #<IPAddr: IPv4:128.128.128.131/255.255.255.252>
]
> ~~~
> 
> The fact that IPAddr accepts a CIDR block mean it represents 1 or more IPs.  So an IPAddr with 1 IP should not be equal to an IPAddr with 4 IPs



----------------------------------------
Bug #11531: IPAddr#== implements wrong logic
https://bugs.ruby-lang.org/issues/11531#change-61646

* Author: Aleksander Panasyuk
* Status: Open
* Priority: Normal
* Assignee: 
* ruby -v: 2.1.5p273
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
----------------------------------------
# Description
IPAddr#== should implement the logic of comparison of two IPAddr instances. This generally means that it compares two IP addresses.
Lets look at the code of this method:

https://github.com/ruby/ruby/blob/c8b3f1b470e343e7408ab5883f046b1056d94ccc/lib/ipaddr.rb#L151

`return @family == other.family && @addr == other.to_i`

It returns the result of comparison of the families and the addresses, but it should also compare the netmask which describes the network where this address is located.
The code below shows the test case for this comparison:
`
ip1 = IPAddr.new '195.51.100.0/24'
ip2 = IPAddr.new '195.51.100.0/26'
ip1 == ip2 #=> true
`
This code shows that two identical IP addresses from different networks are equal. But the result should be `false` because these addresses are not identical.

# Possible solution
Depending on Feature #11210 i would propose following implementation of this method:
`
def ==(other)
  other = coerce_other(other)
  return @family == other.family && @addr == other.to_i && @mask_addr == other.netmask
end
`



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [ruby-core:95611] [Ruby master Bug#11531] IPAddr#== implements wrong logic
       [not found] <redmine.issue-11531.20150916031715@ruby-lang.org>
                   ` (4 preceding siblings ...)
  2016-11-23 17:40 ` [ruby-core:78279] " runner
@ 2019-10-31 16:51 ` merch-redmine
  2019-12-29 12:50 ` [ruby-core:96570] " hsbt
  6 siblings, 0 replies; 7+ messages in thread
From: merch-redmine @ 2019-10-31 16:51 UTC (permalink / raw)
  To: ruby-core

Issue #11531 has been updated by jeremyevans0 (Jeremy Evans).


I am not sure whether this is a bug. `eql?` considers the netmask, but `==` does not.  So if you want to consider the netmask, you can currently use `eql?`. Changing `==` to be the same as `eql?` could cause backwards compatibility issues.

The major problem is one of design, in that `IPAddr` can operate as either a specific IP address or as a network/CIDR-block.  I think it would have been better to use separate classes for those two concepts, but that is not fixable with the current design. 

----------------------------------------
Bug #11531: IPAddr#== implements wrong logic
https://bugs.ruby-lang.org/issues/11531#change-82400

* Author: panasyuk (Aleksander Panasyuk)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
* ruby -v: 2.1.5p273
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
----------------------------------------
# Description
IPAddr#== should implement the logic of comparison of two IPAddr instances. This generally means that it compares two IP addresses.
Lets look at the code of this method:

https://github.com/ruby/ruby/blob/c8b3f1b470e343e7408ab5883f046b1056d94ccc/lib/ipaddr.rb#L151

`return @family == other.family && @addr == other.to_i`

It returns the result of comparison of the families and the addresses, but it should also compare the netmask which describes the network where this address is located.
The code below shows the test case for this comparison:
`
ip1 = IPAddr.new '195.51.100.0/24'
ip2 = IPAddr.new '195.51.100.0/26'
ip1 == ip2 #=> true
`
This code shows that two identical IP addresses from different networks are equal. But the result should be `false` because these addresses are not identical.

# Possible solution
Depending on Feature #11210 i would propose following implementation of this method:
`
def ==(other)
  other = coerce_other(other)
  return @family == other.family && @addr == other.to_i && @mask_addr == other.netmask
end
`



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [ruby-core:96570] [Ruby master Bug#11531] IPAddr#== implements wrong logic
       [not found] <redmine.issue-11531.20150916031715@ruby-lang.org>
                   ` (5 preceding siblings ...)
  2019-10-31 16:51 ` [ruby-core:95611] [Ruby master " merch-redmine
@ 2019-12-29 12:50 ` hsbt
  6 siblings, 0 replies; 7+ messages in thread
From: hsbt @ 2019-12-29 12:50 UTC (permalink / raw)
  To: ruby-core

Issue #11531 has been updated by hsbt (Hiroshi SHIBATA).

Assignee set to knu (Akinori MUSHA)
Status changed from Open to Assigned

----------------------------------------
Bug #11531: IPAddr#== implements wrong logic
https://bugs.ruby-lang.org/issues/11531#change-83528

* Author: panasyuk (Aleksander Panasyuk)
* Status: Assigned
* Priority: Normal
* Assignee: knu (Akinori MUSHA)
* Target version: 
* ruby -v: 2.1.5p273
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
----------------------------------------
# Description
IPAddr#== should implement the logic of comparison of two IPAddr instances. This generally means that it compares two IP addresses.
Lets look at the code of this method:

https://github.com/ruby/ruby/blob/c8b3f1b470e343e7408ab5883f046b1056d94ccc/lib/ipaddr.rb#L151

`return @family == other.family && @addr == other.to_i`

It returns the result of comparison of the families and the addresses, but it should also compare the netmask which describes the network where this address is located.
The code below shows the test case for this comparison:
`
ip1 = IPAddr.new '195.51.100.0/24'
ip2 = IPAddr.new '195.51.100.0/26'
ip1 == ip2 #=> true
`
This code shows that two identical IP addresses from different networks are equal. But the result should be `false` because these addresses are not identical.

# Possible solution
Depending on Feature #11210 i would propose following implementation of this method:
`
def ==(other)
  other = coerce_other(other)
  return @family == other.family && @addr == other.to_i && @mask_addr == other.netmask
end
`



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2019-12-29 12:50 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <redmine.issue-11531.20150916031715@ruby-lang.org>
2015-09-16  3:17 ` [ruby-core:70827] [Ruby trunk - Bug #11531] [Open] IPAddr#== implements wrong logic panasmeister
2016-11-06 16:22 ` [ruby-core:78018] [Ruby trunk Bug#11531] " knu
2016-11-15 22:28 ` [ruby-core:78160] " bjmllr
2016-11-23 17:37 ` [ruby-core:78278] " runner
2016-11-23 17:40 ` [ruby-core:78279] " runner
2019-10-31 16:51 ` [ruby-core:95611] [Ruby master " merch-redmine
2019-12-29 12:50 ` [ruby-core:96570] " hsbt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).