Skip to content

Commit 036d81b

Browse files
FlorianKirmaierkevinrushforth
authored andcommittedNov 30, 2023
8269921: TextFlow: listeners on bounds can throw NPE while computing text bounds
Reviewed-by: kcr, angorya
1 parent 0d33417 commit 036d81b

File tree

2 files changed

+113
-1
lines changed

2 files changed

+113
-1
lines changed
 

‎modules/javafx.graphics/src/main/java/javafx/scene/text/Text.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ void layoutSpan(GlyphList[] runs) {
357357
BaseBounds getSpanBounds() {
358358
if (spanBoundsInvalid) {
359359
GlyphList[] runs = getRuns();
360-
if (runs.length != 0) {
360+
if (runs != null && runs.length != 0) {
361361
float left = Float.POSITIVE_INFINITY;
362362
float top = Float.POSITIVE_INFINITY;
363363
float right = 0;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package test.javafx.scene.text;
26+
27+
import javafx.application.Platform;
28+
import java.util.concurrent.CountDownLatch;
29+
import java.util.concurrent.TimeUnit;
30+
31+
import static org.junit.jupiter.api.Assertions.assertFalse;
32+
import static org.junit.jupiter.api.Assertions.assertTrue;
33+
import javafx.stage.Stage;
34+
import javafx.scene.Node;
35+
import javafx.scene.Scene;
36+
import javafx.scene.control.Label;
37+
import javafx.scene.control.ListCell;
38+
import javafx.scene.control.ListView;
39+
import javafx.scene.control.ScrollPane;
40+
import javafx.scene.text.Text;
41+
import javafx.scene.text.TextFlow;
42+
import javafx.scene.layout.VBox;
43+
import org.junit.jupiter.api.BeforeAll;
44+
import org.junit.jupiter.api.Test;
45+
import test.util.Util;
46+
47+
public class TextFlowCrashTest {
48+
49+
private boolean exceptionWasThrown;
50+
51+
@BeforeAll
52+
public static void initFX() throws Exception {
53+
CountDownLatch startupLatch = new CountDownLatch(1);
54+
Platform.startup(() -> {
55+
Platform.setImplicitExit(false);
56+
startupLatch.countDown();
57+
});
58+
assertTrue(startupLatch.await(15, TimeUnit.SECONDS), "Timeout waiting for FX runtime to start");
59+
}
60+
61+
@Test
62+
public void testTextflowCrash() {
63+
Util.runAndWait(() -> {
64+
Stage stage = new Stage();
65+
VBox root = new VBox();
66+
addBoundsListener(root);
67+
Platform.runLater(() -> {
68+
root.getChildren().add(getBuggyNode());
69+
});
70+
stage.setScene(new Scene(root,
71+
200,
72+
200));
73+
stage.show();
74+
});
75+
76+
Util.runAndWait(() -> {
77+
assertFalse(exceptionWasThrown);
78+
});
79+
}
80+
81+
public ScrollPane getBuggyNode() {
82+
ListView<String> listView = new ListView();
83+
listView.getItems().add("AAA");
84+
listView.setCellFactory((view) -> {
85+
ListCell cell = new ListCell();
86+
TextFlow flow = new TextFlow();
87+
flow.getChildren().add(new Text("a"));
88+
Text text2 = new Text("b");
89+
text2.sceneProperty().addListener((p,o,n) -> {
90+
try {
91+
text2.getBoundsInParent();
92+
} catch (Throwable e) {
93+
exceptionWasThrown = true;
94+
throw e;
95+
}
96+
});
97+
flow.getChildren().add(text2);
98+
cell.setGraphic(flow);
99+
addBoundsListener(cell);
100+
return cell;
101+
});
102+
ScrollPane scrollPane = new ScrollPane(listView);
103+
addBoundsListener(listView);
104+
addBoundsListener(scrollPane);
105+
return scrollPane;
106+
}
107+
108+
public void addBoundsListener(Node node) {
109+
node.boundsInParentProperty().addListener((p,o,n) -> {
110+
});
111+
}
112+
}

3 commit comments

Comments
 (3)

openjdk-notifier[bot] commented on Nov 30, 2023

@openjdk-notifier[bot]

kevinrushforth commented on Nov 30, 2023

@kevinrushforth
Member

/tag 22+20

openjdk[bot] commented on Nov 30, 2023

@openjdk[bot]

@kevinrushforth The tag 22+20 was successfully created.

Please sign in to comment.