JDK-6628576 : InterfaceAddress.equals() NPE when broadcast field == null
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: linux
  • CPU: x86
  • Submitted: 2007-11-12
  • Updated: 2011-03-24
  • Resolved: 2011-03-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7 b25Fixed
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_03"
Java(TM) SE Runtime Environment (build 1.6.0_03-b05)
Java HotSpot(TM) 64-Bit Server VM (build 1.6.0_03-b05, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
All - this a bug in the java.net library

A DESCRIPTION OF THE PROBLEM :
InterfaceAddress.equals() NPE when broadcast field == null
This can be seen when comparing InterfaceAddress(es) represneting point-to-point links. The problem occurs because of a missing check when broadcast==null in the equals() method:

 public boolean equals(Object obj) {
	if (!(obj instanceof InterfaceAddress)) {
	    return false;
	}
	InterfaceAddress cmp = (InterfaceAddress) obj;
	if ((address != null & cmp.address == null) ||
	    (!address.equals(cmp.address)))
	    return false;
ERROR>>	if ((broadcast != null & cmp.broadcast == null) ||
	    (!broadcast.equals(cmp.broadcast)))
	    return false;
	if (maskLength != cmp.maskLength)
	    return false;
	return true;
    }

When broadcast==null above the OR section is run and broadcast.equals() causes the NPE (because broadcast==null).

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Obtain an InterfaceAddress with broadcast==null.  An address for a point-to-point link works well.

Then compare this address (on the left hand side) using equals to another InterfaceAddress.

If broadcast is null a NPE will result.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
true if the InterfaceAddress(es) are equal, false otherwise.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.NullPointerException
	at java.net.InterfaceAddress.equals(InterfaceAddress.java:91)
	at wb.net.mon.NetworkInterfaceMonitor.traverseNetworkInterfaces(NetworkInterfaceMonitor.java:54)
	at wb.net.mon.NetworkInterfaceMonitor.pollAndUpdateMos(NetworkInterfaceMonitor.java:36)
	at wb.net.mon.NetworkInterfaceMonitor.access$0(NetworkInterfaceMonitor.java:30)
	at wb.net.mon.NetworkInterfaceMonitor$1.run(NetworkInterfaceMonitor.java:26)
	at wb.util.thread.ThreadPool.runWorkItem(ThreadPool.java:98)
	at wb.util.thread.ThreadPool.doWork(ThreadPool.java:122)
	at wb.util.thread.ThreadPool.access$8(ThreadPool.java:107)
	at wb.util.thread.ThreadPool$2.run(ThreadPool.java:87)
	at java.lang.Thread.run(Thread.java:619)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
Given an InterfaceAddress with a NULL broadcast address:

InterfaceAddress address=//get an interface address with a null broadcast field
address.equals(address));

NOTE: The above equals comparison does not check for this==obj (another issue, but useful for this test since the above statement should always return true, but in fact generates an NPE).
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Write and use a comparator that handles all field comparisons properly.

NOTE: this is a huge problem since InterfaceAddress(es) can not be used in standard ways (e.g. in collections relying on equals, etc.).

Comments
SUGGESTED FIX src/share/classes/java/net/InterfaceAddress.java public boolean equals(Object obj) { if (!(obj instanceof InterfaceAddress)) { return false; } InterfaceAddress cmp = (InterfaceAddress) obj; - if ((address != null & cmp.address == null) || - (!address.equals(cmp.address))) + if ( !(address == null ? cmp.address == null : address.equals(cmp.address)) ) return false; - if ((broadcast != null & cmp.broadcast == null) || - (!broadcast.equals(cmp.broadcast))) + if ( !(broadcast == null ? cmp.broadcast == null : broadcast.equals(cmp.broadcast)) ) return false; if (maskLength != cmp.maskLength) return false; return true; }
20-11-2007

EVALUATION Update logic in InterfaceAddress.equals to correctly handle null instance fields.
20-11-2007