[PATCH 01/20] fbconsole: remove incomplete CSI_CNT state
Ahmad Fatoum
a.fatoum at barebox.org
Sun May 3 01:33:03 PDT 2026
DEC private sequences use '?' as a parameter prefix byte (e.g. ESC[?25h
to show the cursor).
The CSI state machine treats any non-digit, non-separator as a final
byte and dispatches fbc_parse_csi(), but '?' is only a prefix with
the real final byte ('h' or 'l') following later.
fbc_parse_csi() handles this by recording '?' in csi_cmd and
transitioning to CSI_CNT, which resumes CSI parameter accumulation
for the digits and final byte that follow.
This introduces a subtle bug: The character directly after the ? is not
saved into the priv->csi buffer. This didn't matter so far, because we
only handle h and l without regard to the number before it.
By simplifying the code and removing that extra state, we also fix this
bug by not having that incomplete CSI_CNT state in-between.
Signed-off-by: Ahmad Fatoum <a.fatoum at barebox.org>
---
drivers/video/fbconsole.c | 30 +++++++++---------------------
1 file changed, 9 insertions(+), 21 deletions(-)
diff --git a/drivers/video/fbconsole.c b/drivers/video/fbconsole.c
index 7946d013b24d..60e9783266b6 100644
--- a/drivers/video/fbconsole.c
+++ b/drivers/video/fbconsole.c
@@ -17,7 +17,6 @@ enum state_t {
LIT, /* Literal input */
ESC, /* Start of escape sequence */
CSI, /* Reading arguments in "CSI Pn ;...*/
- CSI_CNT,
};
enum fbconsole_rotation {
@@ -555,10 +554,6 @@ static void fbc_parse_csi(struct fbc_priv *priv)
case 'm':
fbc_parse_colors(priv);
return;
- case '?': /* vt100: show/hide cursor */
- priv->csi_cmd = last;
- priv->state = CSI_CNT;
- return;
case 'h':
/* suffix for vt100 "[?25h" */
switch (priv->csi_cmd) {
@@ -674,29 +669,22 @@ static void fbc_putc(struct console_device *cdev, char c)
}
switch (c) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
+ case '?':
+ /* DEC private sequences use '?' as a parameter prefix byte.
+ * Record '?' in csi_cmd and continue CSI parameter
+ * accumulation for digits and the final byte that follows.
+ */
+ priv->csi_cmd = c;
+ break;
+ case '0' ... '9':
case ';':
case ':':
break;
default:
fbc_parse_csi(priv);
- if (priv->state != CSI_CNT)
- priv->state = LIT;
+ priv->state = LIT;
}
break;
- case CSI_CNT:
- priv->state = CSI;
- break;
-
}
priv->in_console = 0;
--
2.47.3
More information about the barebox
mailing list