1
1
/*
2
- * Copyright (c) 1997, 2021 , Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 1997, 2022 , Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
30
30
import java .io .Serializable ;
31
31
import java .beans .Transient ;
32
32
33
- import javax .swing .event .*;
33
+ import javax .swing .event .EventListenerList ;
34
+ import javax .swing .event .ListSelectionEvent ;
35
+ import javax .swing .event .ListSelectionListener ;
34
36
35
37
36
38
/**
@@ -334,7 +336,7 @@ The case (r < minIndex) is not possible because r'th value was set.
334
336
We only need to check for the case when lowest entry has been cleared,
335
337
and in this case we need to search for the first value set above it.
336
338
*/
337
- if (r == minIndex ) {
339
+ if (r == minIndex && minIndex < Integer . MAX_VALUE ) {
338
340
for (minIndex = minIndex + 1 ; minIndex <= maxIndex ; minIndex ++) {
339
341
if (value .get (minIndex )) {
340
342
break ;
@@ -449,6 +451,10 @@ private void changeSelection(int clearMin, int clearMax,
449
451
if (shouldClear ) {
450
452
clear (i );
451
453
}
454
+ // Prevent Integer overflow
455
+ if (i == Integer .MAX_VALUE ) {
456
+ break ;
457
+ }
452
458
}
453
459
fireValueChanged ();
454
460
}
@@ -640,28 +646,40 @@ private void setState(int index, boolean state) {
640
646
* Otherwise leave them unselected. This method is typically
641
647
* called to sync the selection model with a corresponding change
642
648
* in the data model.
649
+ *
650
+ * @throws IndexOutOfBoundsException if either {@code index}
651
+ * or {@code length} is negative
643
652
*/
644
653
public void insertIndexInterval (int index , int length , boolean before )
645
654
{
655
+ if (length < 0 || index < 0 ) {
656
+ throw new IndexOutOfBoundsException ("index or length is negative" );
657
+ }
658
+ if (index == Integer .MAX_VALUE || length == 0 ) {
659
+ // Nothing to update
660
+ return ;
661
+ }
646
662
/* The first new index will appear at insMinIndex and the last
647
663
* one will appear at insMaxIndex
648
664
*/
649
665
int insMinIndex = (before ) ? index : index + 1 ;
650
- int insMaxIndex = (insMinIndex + length ) - 1 ;
666
+ int insMaxIndex = (insMinIndex + length >= 0 )
667
+ ? (insMinIndex + length ) - 1
668
+ : Integer .MAX_VALUE ;
651
669
652
670
/* Right shift the entire bitset by length, beginning with
653
671
* index-1 if before is true, index+1 if it's false (i.e. with
654
672
* insMinIndex).
655
673
*/
656
- for (int i = maxIndex ; i >= insMinIndex ; i --) {
674
+ for (int i = Math . min ( maxIndex , Integer . MAX_VALUE - length ) ; i >= insMinIndex ; i --) {
657
675
setState (i + length , value .get (i ));
658
676
}
659
677
660
678
/* Initialize the newly inserted indices.
661
679
*/
662
680
boolean setInsertedValues = ((getSelectionMode () == SINGLE_SELECTION ) ?
663
681
false : value .get (index ));
664
- for (int i = insMinIndex ; i <= insMaxIndex ; i ++ ) {
682
+ for (int i = insMaxIndex ; i >= insMinIndex ; i -- ) {
665
683
setState (i , setInsertedValues );
666
684
}
667
685
@@ -686,18 +704,38 @@ public void insertIndexInterval(int index, int length, boolean before)
686
704
* the selection model. This is typically called to sync the selection
687
705
* model width a corresponding change in the data model. Note
688
706
* that (as always) index0 need not be <= index1.
707
+ *
708
+ * @throws IndexOutOfBoundsException if either index is negative
689
709
*/
690
710
public void removeIndexInterval (int index0 , int index1 )
691
711
{
712
+ if (index0 < 0 || index1 < 0 ) {
713
+ throw new IndexOutOfBoundsException ("index is negative" );
714
+ }
715
+
692
716
int rmMinIndex = Math .min (index0 , index1 );
693
717
int rmMaxIndex = Math .max (index0 , index1 );
718
+
719
+ if (rmMinIndex == 0 && rmMaxIndex == Integer .MAX_VALUE ) {
720
+ for (int i = Integer .MAX_VALUE ; i >= 0 ; i --) {
721
+ setState (i , false );
722
+ }
723
+
724
+ if (this .anchorIndex != -1 || this .leadIndex != -1 ) {
725
+ updateLeadAnchorIndices (-1 , -1 );
726
+ }
727
+ return ;
728
+ }
729
+
694
730
int gapLength = (rmMaxIndex - rmMinIndex ) + 1 ;
695
731
696
732
/* Shift the entire bitset to the left to close the index0, index1
697
733
* gap.
698
734
*/
699
- for (int i = rmMinIndex ; i <= maxIndex ; i ++) {
700
- setState (i , value .get (i + gapLength ));
735
+ for (int i = rmMinIndex ; i >= 0 && i <= maxIndex ; i ++) {
736
+ setState (i , (i <= Integer .MAX_VALUE - gapLength )
737
+ && (i + gapLength >= minIndex )
738
+ && value .get (i + gapLength ));
701
739
}
702
740
703
741
int leadIndex = this .leadIndex ;
0 commit comments