Skip to content

Commit 9161c07

Browse files
committed
Fixed: fully consume unknown CSI sequences containing non-numeric parameter byte
To-do: this is untested, would appreciate help. Standard ECMA-48: Control Functions for Coded Character Sets specifies the format of CSI commands. Wikipedia has a concise description: https://en.wikipedia.org/wiki/ANSI_escape_code#Control_Sequence_Introducer_commands Do this for at least for sequences like "CSI = 5 u" that contain non-numeric parameter bytes. This fixes a problem with fish shell 4.0.0 which (for better or worse) uses that sequence. This patch introduces a slight inconsistency: for the above example, "unknownSequence('u')" will be called. The resulting log message may be confusing, because we *do* support "CSI u". We should fix this to log the entire unknown sequence. I can try doing that. In future we should also fully consume all other unknown CSI commands. A contrived example would be "CSI ! ! a". If desired, I'm happy to fix those as well, as I have some context already (but I don't think that would block this patch). Closes termux#4338
1 parent d2cd6ac commit 9161c07

File tree

1 file changed

+20
-0
lines changed

1 file changed

+20
-0
lines changed

terminal-emulator/src/main/java/com/termux/terminal/TerminalEmulator.java

+20
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ public final class TerminalEmulator {
8383
private static final int ESC_APC = 20;
8484
/** Escape processing: "ESC _" or Application Program Command (APC), followed by Escape. */
8585
private static final int ESC_APC_ESCAPE = 21;
86+
/** Escape processing: ESC [ <parameter bytes> */
87+
private static final int ESC_CSI_UNKNOWN_PARAM = 22;
88+
/** Escape processing: ESC [ <parameter bytes> <intermediate bytes> */
89+
private static final int ESC_CSI_UNKNOWN_INTERMEDIATE = 23;
8690

8791
/** The number of parameter arguments including colon separated sub-parameters. */
8892
private static final int MAX_ESCAPE_PARAMETERS = 32;
@@ -656,6 +660,8 @@ public void processCodePoint(int b) {
656660
mUseLineDrawingG1 = (b == '0');
657661
break;
658662
case ESC_CSI:
663+
case ESC_CSI_UNKNOWN_PARAM:
664+
case ESC_CSI_UNKNOWN_INTERMEDIATE:
659665
doCsi(b);
660666
break;
661667
case ESC_CSI_EXCLAMATION:
@@ -1488,6 +1494,18 @@ private void restoreCursor() {
14881494

14891495
/** Following a CSI - Control Sequence Introducer, "\033[". {@link #ESC_CSI}. */
14901496
private void doCsi(int b) {
1497+
if (mEscapeState == ESC_CSI_UNKNOWN_PARAM || mEscapeState == ESC_CSI_UNKNOWN_INTERMEDIATE) {
1498+
if (mEscapeState == ESC_CSI_UNKNOWN_PARAM && b >= 0x30 && b <= 0x3F) {
1499+
continueSequence(mEscapeState); // parameter byte
1500+
} else if (b >= 0x40 && b <= 0x7E) {
1501+
unknownSequence(b); // final byte
1502+
} else if (b >= 0x20 && b <= 0x2F) {
1503+
continueSequence(ESC_CSI_UNKNOWN_INTERMEDIATE); // intermediate byte
1504+
} else {
1505+
unknownSequence(b);
1506+
}
1507+
return;
1508+
}
14911509
switch (b) {
14921510
case '!':
14931511
continueSequence(ESC_CSI_EXCLAMATION);
@@ -2218,6 +2236,8 @@ private void parseArg(int b) {
22182236
logError("Too many parameters when in state: " + mEscapeState);
22192237
}
22202238
continueSequence(mEscapeState);
2239+
} else if (b == '<' || b == '=' || b == '>' || b == '?') {
2240+
continueSequence(ESC_CSI_UNKNOWN_PARAM);
22212241
} else {
22222242
unknownSequence(b);
22232243
}

0 commit comments

Comments
 (0)