Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
6187113: DefaultListSelectionModel.removeIndexInterval(0, Integer.MAX…
…_VALUE) fails

Co-authored-by: Alexey Ivanov <aivanov@openjdk.org>
Reviewed-by: aivanov
  • Loading branch information
prsadhuk and aivanov-jdk committed Jan 30, 2023
1 parent 4bd3f0a commit c2ebd17
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 8 deletions.
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -30,7 +30,9 @@
import java.io.Serializable;
import java.beans.Transient;

import javax.swing.event.*;
import javax.swing.event.EventListenerList;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;


/**
Expand Down Expand Up @@ -334,7 +336,7 @@ The case (r < minIndex) is not possible because r'th value was set.
We only need to check for the case when lowest entry has been cleared,
and in this case we need to search for the first value set above it.
*/
if (r == minIndex) {
if (r == minIndex && minIndex < Integer.MAX_VALUE) {
for(minIndex = minIndex + 1; minIndex <= maxIndex; minIndex++) {
if (value.get(minIndex)) {
break;
Expand Down Expand Up @@ -449,6 +451,10 @@ private void changeSelection(int clearMin, int clearMax,
if (shouldClear) {
clear(i);
}
// Prevent Integer overflow
if (i == Integer.MAX_VALUE) {
break;
}
}
fireValueChanged();
}
Expand Down Expand Up @@ -640,28 +646,40 @@ private void setState(int index, boolean state) {
* Otherwise leave them unselected. This method is typically
* called to sync the selection model with a corresponding change
* in the data model.
*
* @throws IndexOutOfBoundsException if either {@code index}
* or {@code length} is negative
*/
public void insertIndexInterval(int index, int length, boolean before)
{
if (length < 0 || index < 0) {
throw new IndexOutOfBoundsException("index or length is negative");
}
if (index == Integer.MAX_VALUE || length == 0) {
// Nothing to update
return;
}
/* The first new index will appear at insMinIndex and the last
* one will appear at insMaxIndex
*/
int insMinIndex = (before) ? index : index + 1;
int insMaxIndex = (insMinIndex + length) - 1;
int insMaxIndex = (insMinIndex + length >= 0)
? (insMinIndex + length) - 1
: Integer.MAX_VALUE;

/* Right shift the entire bitset by length, beginning with
* index-1 if before is true, index+1 if it's false (i.e. with
* insMinIndex).
*/
for(int i = maxIndex; i >= insMinIndex; i--) {
for(int i = Math.min(maxIndex, Integer.MAX_VALUE - length); i >= insMinIndex; i--) {
setState(i + length, value.get(i));
}

/* Initialize the newly inserted indices.
*/
boolean setInsertedValues = ((getSelectionMode() == SINGLE_SELECTION) ?
false : value.get(index));
for(int i = insMinIndex; i <= insMaxIndex; i++) {
for(int i = insMaxIndex; i >= insMinIndex; i--) {
setState(i, setInsertedValues);
}

Expand All @@ -686,18 +704,38 @@ public void insertIndexInterval(int index, int length, boolean before)
* the selection model. This is typically called to sync the selection
* model width a corresponding change in the data model. Note
* that (as always) index0 need not be &lt;= index1.
*
* @throws IndexOutOfBoundsException if either index is negative
*/
public void removeIndexInterval(int index0, int index1)
{
if (index0 < 0 || index1 < 0) {
throw new IndexOutOfBoundsException("index is negative");
}

int rmMinIndex = Math.min(index0, index1);
int rmMaxIndex = Math.max(index0, index1);

if (rmMinIndex == 0 && rmMaxIndex == Integer.MAX_VALUE) {
for (int i = Integer.MAX_VALUE; i >= 0; i--) {
setState(i, false);
}

if (this.anchorIndex != -1 || this.leadIndex != -1) {
updateLeadAnchorIndices(-1, -1);
}
return;
}

int gapLength = (rmMaxIndex - rmMinIndex) + 1;

/* Shift the entire bitset to the left to close the index0, index1
* gap.
*/
for(int i = rmMinIndex; i <= maxIndex; i++) {
setState(i, value.get(i + gapLength));
for (int i = rmMinIndex; i >= 0 && i <= maxIndex; i++) {
setState(i, (i <= Integer.MAX_VALUE - gapLength)
&& (i + gapLength >= minIndex)
&& value.get(i + gapLength));
}

int leadIndex = this.leadIndex;
Expand Down
65 changes: 65 additions & 0 deletions test/jdk/javax/swing/TestDefListModelException.java
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6187113
* @summary Verifies if
* DefaultListSelectionModel.removeIndexInterval(0, Integer.MAX_VALUE) fails
* @run main TestDefListModelException
*/
import javax.swing.DefaultListSelectionModel;

public class TestDefListModelException {

public static void main(String[] args) throws Exception {
test1();
test2();
test3();
test4();
}

private static void test1() {
DefaultListSelectionModel selectionModel = new DefaultListSelectionModel();
selectionModel.setSelectionInterval(0, 1);
selectionModel.removeIndexInterval(0, Integer.MAX_VALUE);
}

private static void test2() {
DefaultListSelectionModel selectionModel = new DefaultListSelectionModel();
selectionModel.setSelectionInterval(Integer.MAX_VALUE - 1, Integer.MAX_VALUE);
selectionModel.removeIndexInterval(0, 1);
}

private static void test3() {
DefaultListSelectionModel selectionModel = new DefaultListSelectionModel();
selectionModel.setSelectionInterval(Integer.MAX_VALUE - 2, Integer.MAX_VALUE - 1);
selectionModel.removeIndexInterval(0, Integer.MAX_VALUE - 1);
}

private static void test4() {
DefaultListSelectionModel selectionModel = new DefaultListSelectionModel();
selectionModel.setSelectionInterval(Integer.MAX_VALUE - 1, Integer.MAX_VALUE);
selectionModel.insertIndexInterval(Integer.MAX_VALUE - 1, Integer.MAX_VALUE, true);
}
}

1 comment on commit c2ebd17

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.