[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