JDK-8041682 : NPE from BasicListUI.Actions.getNextPageIndex
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 7u45,7-pool,8-pool,9
  • Priority: P3
  • Status: Closed
  • Resolution: Incomplete
  • OS: windows_7
  • Submitted: 2013-12-10
  • Updated: 2017-11-20
  • Resolved: 2015-07-02
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) Client VM (build 24.45-b08, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

A DESCRIPTION OF THE PROBLEM :
We've occasionally seen an NPE coming from BasicListUI.Actions.getNextPageIndex(...) when a user hits the PageDown key.  The stack trace is:

java.lang.NullPointerException
java.awt.Rectangle.intersects(Unknown Source)
javax.swing.plaf.basic.BasicListUI$Actions.getNextPageIndex(Unknown Source)
javax.swing.plaf.basic.BasicListUI$Actions.actionPerformed(Unknown Source)
javax.swing.SwingUtilities.notifyAction(Unknown Source)
javax.swing.JComponent.processKeyBinding(Unknown Source)

Looking at the 7.0.45 source code, there seems to be a missing null check in getNextPageIndex.

Reading the code I can see the only way to get Rectangle.intersects(...) to throw an NPE is by passing a null pointer into intersects.   Looking at the code for BasicListUI.Actions.getNextPageIndex(...) it is taking whatever value list.getCellBounds(index, index) returns and passing it into Rectangle.intersects(...) without a null check.

The JavaDocs for JList.getCellBounds(index, index) states that it can return null, and the implementation BasicListUI.getCellBounds(JList, int, int) does return null under some circumstances.

While these circumstances do not occur often (seems the list is being shortened while someone is trying to scroll down to more of the list), it is possible and the prevention seems simple.

My thought was to check for null before calling Rectangle.intersects(...) so that lines 2054 and 2071 would read something like:

if(cellBounds != null && visRect.intersects(cellBounds))

Also, line 2060 and 2076 would need null checks as well.

Let me know if you have any questions, concerns or thoughts on the proposed fix.

Thanks!


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Haven't figured this out yet, but from reading the code, the problem seems clear.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No NPEs.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.NullPointerException
java.awt.Rectangle.intersects(Unknown Source)
javax.swing.plaf.basic.BasicListUI$Actions.getNextPageIndex(Unknown Source)
javax.swing.plaf.basic.BasicListUI$Actions.actionPerformed(Unknown Source)
javax.swing.SwingUtilities.notifyAction(Unknown Source)
javax.swing.JComponent.processKeyBinding(Unknown Source)

REPRODUCIBILITY :
This bug can be reproduced rarely.

CUSTOMER SUBMITTED WORKAROUND :
Override BasicListUI.getCellBounds so that it never returns null, but instead returns an empty rectangle of size 0,0 at point 0,0.
Comments
Source code of JDK 9, JDK 8, JDK 7 was analyzed and it was defined that all these release families of JDK contain this problem.
24-04-2014