Skip to content

Commit

Permalink
8330462: StringIndexOutOfBoundException when typing anything into Tex…
Browse files Browse the repository at this point in the history
…tField

Reviewed-by: angorya, kcr, arapte
  • Loading branch information
koppor authored and kevinrushforth committed May 8, 2024
1 parent 35880ce commit d3da033
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2024, 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 @@ -27,6 +27,8 @@

import static javafx.scene.AccessibleAttribute.*;
import java.text.BreakIterator;

import com.sun.javafx.util.Utils;
import javafx.geometry.Bounds;
import javafx.scene.AccessibleAction;
import javafx.scene.AccessibleAttribute;
Expand Down Expand Up @@ -98,8 +100,26 @@ private void validateRange(String text) {
}

int length = text.length();
start = Math.max(0, Math.min(start, length));
end = Math.max(start, Math.min(end, length));
start = Utils.clamp(0, start, length);
end = Utils.clamp(start, end, length);
}

/**
* In the context of substrings, this method calculates the end index based on the start index,
* requested string length, and the maximum end index. <code>0 <= start <= end <= length</code>;
* see {@link #validateRange(String)}.
*
* @param startIndex The start index in a string. Needs to be 0 or more (not checked in the code).
* @param length The requested length of a string when starting from "start".
* Negative numbers are treated as full length.
* @param endIndex The maximum end index to return. Needs to be equal or greater than startIndex
* (not checked in the code).
*/
static int getEndIndex(int startIndex, int length, int endIndex) {
if (length < 0 || (endIndex - startIndex) <= length) {
return endIndex;
}
return startIndex + length;
}

void setRange(int start, int end) {
Expand Down Expand Up @@ -358,11 +378,16 @@ private long GetEnclosingElement() {
return accessible.getNativeAccessible();
}

/**
* Returns the text contained in the TEXT attribute, starting from the start index and ending at the end index.
*
* @param maxLength The maximum length of the returned string
*/
private String GetText(int maxLength) {
String text = (String)getAttribute(TEXT);
if (text == null) return null;
validateRange(text);
int endOffset = maxLength != -1 ? Math.min(end, start + maxLength) : end;
int endOffset = getEndIndex(start, maxLength, end);
// System.out.println("+GetText [" + text.substring(start, endOffset)+"]");
return text.substring(start, endOffset);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2024, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package com.sun.glass.ui.win;

/**
* Provides access to the {@link WinTextRangeProvider} class by making its
* package-private fields and methods public for test cases in
* {@link test.com.sun.glass.ui.win.WinTextRangeProviderTest WinTextRangeProviderTest}.
*/
public class WinTextRangeProviderShim {
public static int getEndIndex(int start, int length, int maxEndIndex) {
return WinTextRangeProvider.getEndIndex(start, length, maxEndIndex);
}
}
2 changes: 1 addition & 1 deletion tests/system/src/test/.classpath
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<classpathentry combineaccessrules="false" kind="src" path="/graphics">
<attributes>
<attribute name="module" value="true"/>
<attribute name="add-exports" value="javafx.graphics/com.sun.glass.ui=ALL-UNNAMED:javafx.graphics/com.sun.glass.ui.monocle=ALL-UNNAMED:javafx.graphics/com.sun.javafx.sg.prism=ALL-UNNAMED:javafx.graphics/com.sun.prism.impl=ALL-UNNAMED:javafx.graphics/com.sun.javafx.image.impl=ALL-UNNAMED:javafx.graphics/com.sun.glass.events=ALL-UNNAMED:javafx.graphics/com.sun.javafx.application=ALL-UNNAMED:javafx.graphics/com.sun.javafx.css=ALL-UNNAMED:javafx.graphics/com.sun.javafx.geom=ALL-UNNAMED:javafx.graphics/com.sun.javafx.tk=ALL-UNNAMED:javafx.graphics/com.sun.glass.ui.mac=ALL-UNNAMED:javafx.graphics/com.sun.javafx.scene.text=ALL-UNNAMED:javafx.graphics/com.sun.javafx.text=ALL-UNNAMED:javafx.graphics/com.sun.javafx.font=ALL-UNNAMED"/>
<attribute name="add-exports" value="javafx.graphics/com.sun.glass.ui=ALL-UNNAMED:javafx.graphics/com.sun.glass.ui.monocle=ALL-UNNAMED:javafx.graphics/com.sun.javafx.sg.prism=ALL-UNNAMED:javafx.graphics/com.sun.prism.impl=ALL-UNNAMED:javafx.graphics/com.sun.javafx.image.impl=ALL-UNNAMED:javafx.graphics/com.sun.glass.events=ALL-UNNAMED:javafx.graphics/com.sun.javafx.application=ALL-UNNAMED:javafx.graphics/com.sun.javafx.css=ALL-UNNAMED:javafx.graphics/com.sun.javafx.geom=ALL-UNNAMED:javafx.graphics/com.sun.javafx.tk=ALL-UNNAMED:javafx.graphics/com.sun.glass.ui.mac=ALL-UNNAMED:javafx.graphics/com.sun.glass.ui.win=ALL-UNNAMED:javafx.graphics/com.sun.javafx.scene.text=ALL-UNNAMED:javafx.graphics/com.sun.javafx.text=ALL-UNNAMED:javafx.graphics/com.sun.javafx.font=ALL-UNNAMED"/>
</attributes>
</classpathentry>
<classpathentry combineaccessrules="false" kind="src" path="/controls">
Expand Down
1 change: 1 addition & 0 deletions tests/system/src/test/addExports
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
--add-exports javafx.graphics/com.sun.glass.ui=ALL-UNNAMED
--add-exports javafx.graphics/com.sun.glass.ui.mac=ALL-UNNAMED
--add-exports javafx.graphics/com.sun.glass.ui.monocle=ALL-UNNAMED
--add-exports javafx.graphics/com.sun.glass.ui.win=ALL-UNNAMED
--add-exports javafx.graphics/com.sun.javafx.animation=ALL-UNNAMED
--add-exports javafx.graphics/com.sun.javafx.application=ALL-UNNAMED
--add-exports javafx.graphics/com.sun.javafx.css=ALL-UNNAMED
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright (c) 2024, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package test.com.sun.glass.ui.win;

import com.sun.javafx.PlatformUtil;
import com.sun.glass.ui.win.WinTextRangeProviderShim;

import java.util.concurrent.CountDownLatch;
import java.util.stream.Stream;

import test.util.Util;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assumptions.assumeTrue;

public class WinTextRangeProviderTest {

private static final CountDownLatch startupLatch = new CountDownLatch(1);

@BeforeAll
static void initFX() throws Exception {
assumeTrue(PlatformUtil.isWindows());
Util.startup(startupLatch, () -> startupLatch.countDown());
}

@AfterAll
static void shutdown() {
assumeTrue(PlatformUtil.isWindows());
Util.shutdown();
}

static Stream<Arguments> getEndIndexParameters() {
return Stream.of(
Arguments.of(1, 0, 1, 2),
Arguments.of(1, 0, 2, 1),
Arguments.of(55, 50, 10, 55),
Arguments.of(60, 50, 10, Integer.MAX_VALUE),
Arguments.of(1, 0, Integer.MAX_VALUE, 1),
Arguments.of(50, 50, Integer.MAX_VALUE, 50),
Arguments.of(Integer.MAX_VALUE, 0, Integer.MAX_VALUE, Integer.MAX_VALUE),
Arguments.of(60, 50, -1, 60),
Arguments.of(60, 50, Integer.MIN_VALUE, 60)
);
}

@ParameterizedTest
@MethodSource("getEndIndexParameters")
public void testGetEndIndex(Integer expected, Integer startIndex, Integer length, Integer maxEndIndex) {
assumeTrue(PlatformUtil.isWindows());
assertEquals(expected, WinTextRangeProviderShim.getEndIndex(startIndex, length, maxEndIndex));
}
}

5 comments on commit d3da033

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

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

@arapte
Copy link
Member

@arapte arapte commented on d3da033 May 13, 2024

Choose a reason for hiding this comment

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

/backport jfx22u

@openjdk
Copy link

@openjdk openjdk bot commented on d3da033 May 13, 2024

Choose a reason for hiding this comment

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

@arapte Could not automatically backport d3da033a to openjdk/jfx22u due to conflicts in the following files:

  • tests/system/src/test/.classpath

Please fetch the appropriate branch/commit and manually resolve these conflicts by using the following commands in your personal fork of openjdk/jfx22u. Note: these commands are just some suggestions and you can use other equivalent commands you know.

# Fetch the up-to-date version of the target branch
$ git fetch --no-tags https://git.openjdk.org/jfx22u.git master:master

# Check out the target branch and create your own branch to backport
$ git checkout master
$ git checkout -b backport-arapte-d3da033a

# Fetch the commit you want to backport
$ git fetch --no-tags https://git.openjdk.org/jfx.git d3da033a2dd5c287733545935242a8d1f71c0554

# Backport the commit
$ git cherry-pick --no-commit d3da033a2dd5c287733545935242a8d1f71c0554
# Resolve conflicts now

# Commit the files you have modified
$ git add files/with/resolved/conflicts
$ git commit -m 'Backport d3da033a2dd5c287733545935242a8d1f71c0554'

Once you have resolved the conflicts as explained above continue with creating a pull request towards the openjdk/jfx22u with the title Backport d3da033a2dd5c287733545935242a8d1f71c0554.

Below you can find a suggestion for the pull request body:

Hi all,

This pull request contains a backport of commit d3da033a from the openjdk/jfx repository.

The commit being backported was authored by Oliver Kopp on 8 May 2024 and was reviewed by Andy Goryachev, Kevin Rushforth and Ambarish Rapte.

Thanks!

@jperedadnr
Copy link
Collaborator

Choose a reason for hiding this comment

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

/backport jfx21u

@openjdk
Copy link

@openjdk openjdk bot commented on d3da033 May 15, 2024

Choose a reason for hiding this comment

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

@jperedadnr Could not automatically backport d3da033a to openjdk/jfx21u due to conflicts in the following files:

  • tests/system/src/test/.classpath

Please fetch the appropriate branch/commit and manually resolve these conflicts by using the following commands in your personal fork of openjdk/jfx21u. Note: these commands are just some suggestions and you can use other equivalent commands you know.

# Fetch the up-to-date version of the target branch
$ git fetch --no-tags https://git.openjdk.org/jfx21u.git master:master

# Check out the target branch and create your own branch to backport
$ git checkout master
$ git checkout -b backport-jperedadnr-d3da033a

# Fetch the commit you want to backport
$ git fetch --no-tags https://git.openjdk.org/jfx.git d3da033a2dd5c287733545935242a8d1f71c0554

# Backport the commit
$ git cherry-pick --no-commit d3da033a2dd5c287733545935242a8d1f71c0554
# Resolve conflicts now

# Commit the files you have modified
$ git add files/with/resolved/conflicts
$ git commit -m 'Backport d3da033a2dd5c287733545935242a8d1f71c0554'

Once you have resolved the conflicts as explained above continue with creating a pull request towards the openjdk/jfx21u with the title Backport d3da033a2dd5c287733545935242a8d1f71c0554.

Below you can find a suggestion for the pull request body:

Hi all,

This pull request contains a backport of commit d3da033a from the openjdk/jfx repository.

The commit being backported was authored by Oliver Kopp on 8 May 2024 and was reviewed by Andy Goryachev, Kevin Rushforth and Ambarish Rapte.

Thanks!

Please sign in to comment.