JDK-8302511 : HitInfo.toString() throws IllegalArgumentException
  • Type: Bug
  • Component: javafx
  • Sub-Component: graphics
  • Affected Version: jfx21
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2023-02-14
  • Updated: 2023-06-29
  • Resolved: 2023-06-23
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
jfx21 b24Fixed
Related Reports
Relates :  
Relates :  
Description
toString() methods should not throw an exception under any circumstances (I think it is when the (x,y) coordinates are outside of the Text bounds).  The second invocation of toString on the same instance does not cause NPE, and the insertionIndex field gets set in getInsertionIndex() just before the exception is thrown - so not only we have an exception, but also the object might enter an inconsistent/incorrect state.

This may be a sign of a larger issue, but at least toString() should print N/A if HitInfo.getInsertionIndex() throws an exception.

```
Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: offset out of bounds
	at java.base/sun.text.RuleBasedBreakIterator.checkOffset(RuleBasedBreakIterator.java:730)
	at java.base/sun.text.RuleBasedBreakIterator.following(RuleBasedBreakIterator.java:744)
	at javafx.graphics/javafx.scene.text.HitInfo.getInsertionIndex(HitInfo.java:84)
	at javafx.graphics/javafx.scene.text.HitInfo.toString(HitInfo.java:100)
	at java.base/java.lang.String.valueOf(String.java:4225)
	at java.base/java.lang.StringBuilder.append(StringBuilder.java:173)
	at andy_test/goryachev.rich.RichTextAreaBehavior.nextCharacterVisually_textArea(RichTextAreaBehavior.java:506)
	at andy_test/goryachev.rich.RichTextAreaBehavior.nextCharacterVisually(RichTextAreaBehavior.java:389)
	at andy_test/goryachev.rich.RichTextAreaBehavior.moveLeft(RichTextAreaBehavior.java:316)
	at andy_test/goryachev.rich.RichTextAreaBehavior.handleKeyEvent(RichTextAreaBehavior.java:151)
	at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
	at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
	at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:232)
	at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:189)
	at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
	at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
	at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
```
Comments
Changeset: d2683b9e Author: Andy Goryachev <angorya@openjdk.org> Date: 2023-06-23 15:35:57 +0000 URL: https://git.openjdk.org/jfx/commit/d2683b9ebcb13361e8b5084e6c7da6c5a0204c93
23-06-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jfx/pull/1154 Date: 2023-06-14 15:40:41 +0000
14-06-2023

So far as I can tell, this can only happen if the HitInfo was incorrectly constructed. It would require that the charIndex passed be out of bounds for the text that was passed and that the hit is on the trailing edge. Since HitInfo has no public constructor, only FX internal code could be responsible for that. There are two calls to it - one in TextFlow passes null for the text and that will never trigger the use of the BreakIterator. The other is in the Text public final HitInfo hitTest(Point2D point) { ... ... TextLayout.Hit layoutHit = layout.getHitInfo((float)x, (float)y); return new HitInfo(layoutHit.getCharIndex(), layoutHit.getInsertionIndex(), layoutHit.isLeading(), getText()); I suspect we have something like a string of length 5 and are indicating a hit on the trailing edge of charindex=6, perhaps TextLayout.getHitInfo() is responsible for that. I recall there was some bug/email thread about what should be returned if the x,y is outside the text. I can't find it right now, but this code probably points to a good reason it shouldn't return a value beyond the length of the text. It might be best to put code into the constructor that validates the charIndex + edge against the text - if any. Then the code responsible for this would be easier to spot. Also I think getInsertionIndex() should be setting insertionIndex only at the end .. not updating it multiple times. toString() perhaps could be changed to just report the var - even if it hasn't been initialised yet. Not sure about this. But also "text" probably ought to be part of what toString() returns.
01-06-2023

> toString() methods should not throw an exception under any circumstances Indeed they should not. Even if there is an underlying problem, this should be fixed in toString itself.
15-02-2023