RFR: 5080391: ArrayIndexOutOfBounds during "undo" of Right-to-Left text insert
Alexey Ivanov
aivanov at openjdk.org
Mon Oct 3 12:28:46 UTC 2022
On Tue, 27 Sep 2022 11:16:36 GMT, Prasanta Sadhukhan <psadhukhan at openjdk.org> wrote:
> javax.swing.text.AbstractDocument$BranchElement.replace(...) method throws an `ArrayIndexOutOfBoundsException: arraycopy: length -1 is negative` when using an UndoManager on the default document of a JTextArea and you try to undo the insertion of a LEFT-TO-RIGHT language (e.g. Arabic) that is immediately followed by setting the component orientation on the JTextArea.
>
> This is because System.arrayCopy() is called with -ve length because of the calculation done in AbstractDocment.replace where `src` is of 2bytes because of unicode text causing `nmove` to become -ve if `nchildren` is 1 (an unicode character is inserted)
>
> System.arrayCopy throws `IndexOutOfBoundsException if:
>
> The srcPos argument is negative.
> The destPos argument is negative.
> The length argument is negative
>
>
> so the fix is made to make nmove, src, dest +ve
> Also, Element.getElement() can return null which is not checked, causing NPE, if deletion of text is done which results in no element, which is also fixed in the PR
>
> All jtreg testsuite tests are run without any regression.
src/java.desktop/share/classes/javax/swing/text/AbstractDocument.java line 958:
> 956: int index = bidiRoot.getElementIndex(p0);
> 957: Element bidiElem = bidiRoot.getElement(index);
> 958: if (bidiElem != null && bidiElem.getEndOffset() >= p1) {
Is it possible that `bidiElem` is `null`? It should never be. If it is, it is a bug in the code and throwing NPE seems good — it will be the indication of the bug.
Since the NPE has never been thrown from this code, I'd rather leave it unchanged here.
src/java.desktop/share/classes/javax/swing/text/AbstractDocument.java line 2325:
> 2323: int src = Math.abs(offset + length);
> 2324: int nmove = Math.abs(nchildren - src);
> 2325: int dest = Math.abs(src + delta);
I'm rather unsure why any of these could become negative. Would it be possible that using `Math.abs` corrupts the document or leads to a data loss?
The thing is the `UndoableEdit` was produced while the document and the component didn't have `bidi` set to `true`. Inserting a right-to-left text changes that situation, and `bidiRoot` starts to contain elements. I assume changing the component orientation also modifies the contents of `bidiRoot`. As such, performing the undo operation may become impossible because the recorded state in the `UndoableEdit` is inconsistent with the current state of the document.
test/jdk/javax/swing/text/AbstractDocument/TestUndoError.java line 39:
> 37: import javax.swing.undo.UndoManager;
> 38:
> 39: public class TestUndoError {
`TestUndoInsertArabicText`? It's more specific this way.
test/jdk/javax/swing/text/AbstractDocument/TestUndoError.java line 42:
> 40:
> 41: private static JTextArea textArea_;
> 42: private static UndoManager manager_;
Is the underscore necessary at the end of the field names?
test/jdk/javax/swing/text/AbstractDocument/TestUndoError.java line 51:
> 49: textArea_ = new JTextArea();
> 50: manager_ = new UndoManager();
> 51: frame = new JFrame("Undo - Redo Error");
Is `frame` even required? Using `textArea` should be enough.
-------------
PR: https://git.openjdk.org/jdk/pull/10446
More information about the client-libs-dev
mailing list