mirror of
https://github.com/fankes/termux-app.git
synced 2025-09-06 10:45:23 +08:00
Fixed: Fix CSI parameters parsing like for SGR sequences that start with a ;
or have sequential ;
characters
https://vt100.net/docs/vt510-rm/chapter4.html#S4.3.3 https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_(Control_Sequence_Introducer)_sequences Credits for finding the issue belongs to @Screwtapello https://github.com/mawww/kakoune/issues/4339#issuecomment-916980723 Closes #2272, Closes mawww/kakoune#4339
This commit is contained in:
@@ -126,6 +126,10 @@ public final class TerminalEmulator {
|
|||||||
private String mTitle;
|
private String mTitle;
|
||||||
private final Stack<String> mTitleStack = new Stack<>();
|
private final Stack<String> mTitleStack = new Stack<>();
|
||||||
|
|
||||||
|
/** If processing first character of first parameter of {@link #ESC_CSI}. */
|
||||||
|
private boolean mIsCSIStart;
|
||||||
|
/** The last character processed of a parameter of {@link #ESC_CSI}. */
|
||||||
|
private Integer mLastCSIArg;
|
||||||
|
|
||||||
/** The cursor position. Between (0,0) and (mRows-1, mColumns-1). */
|
/** The cursor position. Between (0,0) and (mRows-1, mColumns-1). */
|
||||||
private int mCursorRow, mCursorCol;
|
private int mCursorRow, mCursorCol;
|
||||||
@@ -1386,6 +1390,8 @@ public final class TerminalEmulator {
|
|||||||
break;
|
break;
|
||||||
case '[':
|
case '[':
|
||||||
continueSequence(ESC_CSI);
|
continueSequence(ESC_CSI);
|
||||||
|
mIsCSIStart = true;
|
||||||
|
mLastCSIArg = null;
|
||||||
break;
|
break;
|
||||||
case '=': // DECKPAM
|
case '=': // DECKPAM
|
||||||
setDecsetinternalBit(DECSET_BIT_APPLICATION_KEYPAD, true);
|
setDecsetinternalBit(DECSET_BIT_APPLICATION_KEYPAD, true);
|
||||||
@@ -2093,8 +2099,33 @@ public final class TerminalEmulator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Process the next ASCII character of a parameter. */
|
/**
|
||||||
private void parseArg(int b) {
|
* Process the next ASCII character of a parameter.
|
||||||
|
*
|
||||||
|
* Parameter characters modify the action or interpretation of the sequence. You can use up to
|
||||||
|
* 16 parameters per sequence. You must use the ; character to separate parameters.
|
||||||
|
* All parameters are unsigned, positive decimal integers, with the most significant
|
||||||
|
* digit sent first. Any parameter greater than 9999 (decimal) is set to 9999
|
||||||
|
* (decimal). If you do not specify a value, a 0 value is assumed. A 0 value
|
||||||
|
* or omitted parameter indicates a default value for the sequence. For most
|
||||||
|
* sequences, the default value is 1.
|
||||||
|
*
|
||||||
|
* https://vt100.net/docs/vt510-rm/chapter4.html#S4.3.3
|
||||||
|
* */
|
||||||
|
private void parseArg(int inputByte) {
|
||||||
|
int[] bytes = new int[]{inputByte};
|
||||||
|
// Only doing this for ESC_CSI and not for other ESC_CSI_* since they seem to be using their
|
||||||
|
// own defaults with getArg*() calls, but there may be missed cases
|
||||||
|
if (mEscapeState == ESC_CSI) {
|
||||||
|
if ((mIsCSIStart && inputByte == ';') || // If sequence starts with a ; character, like \033[;m
|
||||||
|
(!mIsCSIStart && mLastCSIArg != null && mLastCSIArg == ';' && inputByte == ';')) { // If sequence contains sequential ; characters, like \033[;;m
|
||||||
|
bytes = new int[]{'0', ';'}; // Assume 0 was passed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mIsCSIStart = false;
|
||||||
|
|
||||||
|
for (int b : bytes) {
|
||||||
if (b >= '0' && b <= '9') {
|
if (b >= '0' && b <= '9') {
|
||||||
if (mArgIndex < mArgs.length) {
|
if (mArgIndex < mArgs.length) {
|
||||||
int oldValue = mArgs[mArgIndex];
|
int oldValue = mArgs[mArgIndex];
|
||||||
@@ -2116,6 +2147,8 @@ public final class TerminalEmulator {
|
|||||||
} else {
|
} else {
|
||||||
unknownSequence(b);
|
unknownSequence(b);
|
||||||
}
|
}
|
||||||
|
mLastCSIArg = b;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getArg0(int defaultValue) {
|
private int getArg0(int defaultValue) {
|
||||||
|
@@ -151,6 +151,19 @@ public class TerminalTest extends TerminalTestCase {
|
|||||||
assertEquals(TextStyle.COLOR_INDEX_FOREGROUND, mTerminal.mForeColor);
|
assertEquals(TextStyle.COLOR_INDEX_FOREGROUND, mTerminal.mForeColor);
|
||||||
assertEquals(TextStyle.COLOR_INDEX_BACKGROUND, mTerminal.mBackColor);
|
assertEquals(TextStyle.COLOR_INDEX_BACKGROUND, mTerminal.mBackColor);
|
||||||
|
|
||||||
|
// Test CSI resetting to default if sequence starts with ; or has sequential ;;
|
||||||
|
// Check TerminalEmulator.parseArg()
|
||||||
|
enterString("\033[31m\033[m");
|
||||||
|
assertEquals(TextStyle.COLOR_INDEX_FOREGROUND, mTerminal.mForeColor);
|
||||||
|
enterString("\033[31m\033[;m");
|
||||||
|
assertEquals(TextStyle.COLOR_INDEX_FOREGROUND, mTerminal.mForeColor);
|
||||||
|
enterString("\033[31m\033[0m");
|
||||||
|
assertEquals(TextStyle.COLOR_INDEX_FOREGROUND, mTerminal.mForeColor);
|
||||||
|
enterString("\033[31m\033[0;m");
|
||||||
|
assertEquals(TextStyle.COLOR_INDEX_FOREGROUND, mTerminal.mForeColor);
|
||||||
|
enterString("\033[31;;m");
|
||||||
|
assertEquals(TextStyle.COLOR_INDEX_FOREGROUND, mTerminal.mForeColor);
|
||||||
|
|
||||||
// 256 colors:
|
// 256 colors:
|
||||||
enterString("\033[38;5;119m");
|
enterString("\033[38;5;119m");
|
||||||
assertEquals(119, mTerminal.mForeColor);
|
assertEquals(119, mTerminal.mForeColor);
|
||||||
|
Reference in New Issue
Block a user