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 4a74ee6f1d..df57bd3629 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 TerminalRow allocateFullLineIfNecessary(int row) { } 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 8efb949bd2..975c1a5abb 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 @@ private void emitCodePoint(int codePoint) { } 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 cefdd4f73f..cbeaf52243 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 void clear(long style) { // 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);