8134116: Add more comprehensive fix and regression test for JDK-8133897

Use getTitleAt instead of Page.title field; add regression test

Reviewed-by: alexsch, serb
This commit is contained in:
Peter Brunet 2015-11-12 12:27:36 -06:00 committed by Pete Brunet
parent f8cea75f1c
commit 7b6f3bbed8
2 changed files with 145 additions and 12 deletions

View File

@ -2095,9 +2095,10 @@ public class JTabbedPane extends JComponent
*/
void setDisplayedMnemonicIndex(int mnemonicIndex) {
if (this.mnemonicIndex != mnemonicIndex) {
if (mnemonicIndex != -1 && (title == null ||
String t = getTitle();
if (mnemonicIndex != -1 && (t == null ||
mnemonicIndex < 0 ||
mnemonicIndex >= title.length())) {
mnemonicIndex >= t.length())) {
throw new IllegalArgumentException(
"Invalid mnemonic index: " + mnemonicIndex);
}
@ -2116,7 +2117,7 @@ public class JTabbedPane extends JComponent
void updateDisplayedMnemonicIndex() {
setDisplayedMnemonicIndex(
SwingUtilities.findDisplayedMnemonicIndex(title, mnemonic));
SwingUtilities.findDisplayedMnemonicIndex(getTitle(), mnemonic));
}
/////////////////
@ -2133,10 +2134,9 @@ public class JTabbedPane extends JComponent
public String getAccessibleName() {
if (accessibleName != null) {
return accessibleName;
} else if (title != null) {
return title;
} else {
return getTitle();
}
return null;
}
public String getAccessibleDescription() {
@ -2156,7 +2156,7 @@ public class JTabbedPane extends JComponent
AccessibleStateSet states;
states = parent.getAccessibleContext().getAccessibleStateSet();
states.add(AccessibleState.SELECTABLE);
int i = parent.indexOfTab(title);
int i = parent.indexOfTabComponent(tabComponent);
if (i == parent.getSelectedIndex()) {
states.add(AccessibleState.SELECTED);
}
@ -2164,7 +2164,7 @@ public class JTabbedPane extends JComponent
}
public int getAccessibleIndexInParent() {
return parent.indexOfTab(title);
return parent.indexOfTabComponent(tabComponent);
}
public int getAccessibleChildrenCount() {
@ -2272,10 +2272,8 @@ public class JTabbedPane extends JComponent
}
public Rectangle getBounds() {
int i = parent.indexOfTab(title);
// Check for no title. Even though that's a bug in the app we should
// inhibit an ArrayIndexOutOfBoundsException from getTabBounds.
return (i == -1) ? null : parent.getUI().getTabBounds(parent, i);
return parent.getUI().
getTabBounds(parent, parent.indexOfTabComponent(tabComponent));
}
public void setBounds(Rectangle r) {
@ -2343,6 +2341,11 @@ public class JTabbedPane extends JComponent
return null;
}
}
private String getTitle() {
return getTitleAt(parent.indexOfComponent(component));
}
}
/**

View File

@ -0,0 +1,130 @@
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleComponent;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
import javax.swing.*;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
/*
* @test
* @bug 8134116
* @summary JTabbedPane$Page.getBounds throws IndexOutOfBoundsException
* @run main Bug8134116
*/
public class Bug8134116 {
public static void main(String args[]) throws Exception {
try {
UIManager.setLookAndFeel(new NimbusLookAndFeel());
} catch (Exception e) {
throw new RuntimeException(e);
}
SwingUtilities.invokeAndWait(() -> {
JPanel panel0 = new JPanel();
BadPane badPane = new BadPane();
badPane.add("zero", panel0);
badPane.add("one", null);
JFrame frame = new JFrame();
frame.add(badPane);
frame.setSize(300, 300);
frame.setVisible(true);
AccessibleContext ac = badPane.getAccessibleContext();
Accessible page0 = ac.getAccessibleChild(0);
if (page0 == null) {
// Not something being tested, but checking anyway
throw new RuntimeException("getAccessibleChild(0) is null");
}
Accessible page1 = ac.getAccessibleChild(1);
if (page1 == null) {
// Not something being tested, but checking anyway
throw new RuntimeException("getAccessibleChild(1) is null");
}
// page0 and page1 are a JTabbedPane.Page, a private inner class
// and is an AccessibleContext
// and implements Accessible and AccessibleComponent
AccessibleContext pac0 = page0.getAccessibleContext();
AccessibleContext pac1 = page1.getAccessibleContext();
// the following would fail if JDK-8134116 fix not present
// test Page.getBounds
// ensure no IndexOutOfBoundsException
pac0.getAccessibleComponent().getBounds();
// test Page.getAccessibleStateSet
// At this point page 0 is selected
AccessibleStateSet accSS0 = pac0.getAccessibleStateSet();
if (!accSS0.contains(AccessibleState.SELECTED)) {
String msg = "Empty title -> AccessibleState.SELECTED not set";
throw new RuntimeException(msg);
}
// test Page.getAccessibleIndexInParent
if (pac0.getAccessibleIndexInParent() == -1) {
String msg = "Empty title -> negative AccessibleIndexInParent";
throw new RuntimeException(msg);
}
// test Page.getAccessibleName
String accName = pac0.getAccessibleName();
if (!accName.equals("zero")) {
String msg = "Empty title -> empty AccessibleName";
throw new RuntimeException(msg);
}
// test Page.getAccessibleName when component is null
accName = pac1.getAccessibleName();
if (!accName.equals("one")) {
String msg = "AccessibleName of null panel not 'one'";
throw new RuntimeException(msg);
}
// test Page.setDisplayedMnemonicIndex
// Empty title -> IllegalArgumnetException
badPane.setDisplayedMnemonicIndexAt(0, 1);
// test Page.updateDisplayedMnemonicIndex
badPane.setMnemonicAt(0, KeyEvent.VK_Z);
if (badPane.getDisplayedMnemonicIndexAt(0) == -1) {
String msg="Empty title -> getDisplayedMnemonicIndexAt failure";
throw new RuntimeException(msg);
}
});
}
// The following is likely what is being done in Burp Suite
// https://portswigger.net/burp/ which fails in the same way, i.e. the
// pages List in JTabbedPane is not being managed properly and thus
// Page.title is "" for each page. The overridden insertTab manages titles
// in the subclass passing a "" title to the superclass JTabbedPane through
// its insertTab. Later an overridden getTitleAt returns the titles as
// managed by the subclass.
static class BadPane extends JTabbedPane {
private List<String> titles;
BadPane() {
titles = new ArrayList<String>(1);
}
@Override
public void insertTab( String title, Icon icon, Component component,
String tip, int index ) {
titles.add(index, title);
super.insertTab("", icon, component, tip, index);
}
@Override
public String getTitleAt(int i) {
return titles.get(i);
}
}
}