From 7a386a7f2a4d0d0600e1c026486a5f4d04b31803 Mon Sep 17 00:00:00 2001 From: agnostic-apollo Date: Mon, 15 Nov 2021 07:31:14 +0500 Subject: [PATCH] Fixed: Fix ArrayIndexOutOfBoundsException when setting zero width terminal character java.lang.ArrayIndexOutOfBoundsException: length=64; index=-1 at com.termux.terminal.TerminalRow.setChar(TerminalRow.java:127) at com.termux.terminal.TerminalBuffer.setChar(TerminalBuffer.java:413) at com.termux.terminal.TerminalEmulator.emitCodePoint(TerminalEmulator.java:2329) at com.termux.terminal.TerminalEmulator.processCodePoint(TerminalEmulator.java:617) at com.termux.terminal.TerminalEmulator.processByte(TerminalEmulator.java:513) at com.termux.terminal.TerminalEmulator.append(TerminalEmulator.java:480) at com.termux.terminal.TerminalSession$MainThreadHandler.handleMessage(TerminalSession.java:339) at android.os.Handler.dispatchMessage(Handler.java:110) at android.os.Looper.loop(Looper.java:219) at android.app.ActivityThread.main(ActivityThread.java:8349) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055) --- .../main/java/com/termux/terminal/TerminalBuffer.java | 4 ++-- .../main/java/com/termux/terminal/TerminalEmulator.java | 9 ++++++++- .../src/main/java/com/termux/terminal/TerminalRow.java | 3 +++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/terminal-emulator/src/main/java/com/termux/terminal/TerminalBuffer.java b/terminal-emulator/src/main/java/com/termux/terminal/TerminalBuffer.java index 4a74ee6f..df57bd36 100644 --- a/terminal-emulator/src/main/java/com/termux/terminal/TerminalBuffer.java +++ b/terminal-emulator/src/main/java/com/termux/terminal/TerminalBuffer.java @@ -449,8 +449,8 @@ public final class TerminalBuffer { } public void setChar(int column, int row, int codePoint, long style) { - if (row >= mScreenRows || column >= mColumns) - throw new IllegalArgumentException("row=" + row + ", column=" + column + ", mScreenRows=" + mScreenRows + ", mColumns=" + mColumns); + if (row < 0 || row >= mScreenRows || column < 0 || column >= mColumns) + throw new IllegalArgumentException("TerminalBuffer.setChar(): row=" + row + ", column=" + column + ", mScreenRows=" + mScreenRows + ", mColumns=" + mColumns); row = externalToInternalRow(row); allocateFullLineIfNecessary(row).setChar(column, codePoint, style); } diff --git a/terminal-emulator/src/main/java/com/termux/terminal/TerminalEmulator.java b/terminal-emulator/src/main/java/com/termux/terminal/TerminalEmulator.java index 8efb949b..975c1a5a 100644 --- a/terminal-emulator/src/main/java/com/termux/terminal/TerminalEmulator.java +++ b/terminal-emulator/src/main/java/com/termux/terminal/TerminalEmulator.java @@ -2332,7 +2332,14 @@ public final class TerminalEmulator { } int offsetDueToCombiningChar = ((displayWidth <= 0 && mCursorCol > 0 && !mAboutToAutoWrap) ? 1 : 0); - mScreen.setChar(mCursorCol - offsetDueToCombiningChar, mCursorRow, codePoint, getStyle()); + int column = mCursorCol - offsetDueToCombiningChar; + + // Fix TerminalRow.setChar() ArrayIndexOutOfBoundsException index=-1 exception reported + // The offsetDueToCombiningChar would never be 1 if mCursorCol was 0 to get column/index=-1, + // so was mCursorCol changed after the offsetDueToCombiningChar conditional by another thread? + // TODO: Check if there are thread synchronization issues with mCursorCol and mCursorRow, possibly causing others bugs too. + if (column < 0) column = 0; + mScreen.setChar(column, mCursorRow, codePoint, getStyle()); if (autoWrap && displayWidth > 0) mAboutToAutoWrap = (mCursorCol == mRightMargin - displayWidth); diff --git a/terminal-emulator/src/main/java/com/termux/terminal/TerminalRow.java b/terminal-emulator/src/main/java/com/termux/terminal/TerminalRow.java index cefdd4f7..cbeaf522 100644 --- a/terminal-emulator/src/main/java/com/termux/terminal/TerminalRow.java +++ b/terminal-emulator/src/main/java/com/termux/terminal/TerminalRow.java @@ -124,6 +124,9 @@ public final class TerminalRow { // https://github.com/steven676/Android-Terminal-Emulator/commit/9a47042620bec87617f0b4f5d50568535668fe26 public void setChar(int columnToSet, int codePoint, long style) { + if (columnToSet < 0 || columnToSet >= mStyle.length) + throw new IllegalArgumentException("TerminalRow.setChar(): columnToSet=" + columnToSet + ", codePoint=" + codePoint + ", style=" + style); + mStyle[columnToSet] = style; final int newCodePointDisplayWidth = WcWidth.width(codePoint);