From 95f22c53059ccd60ee701ccf2659dacd95e4e89a Mon Sep 17 00:00:00 2001 From: Tommi Hirvola Date: Mon, 4 Mar 2024 12:56:30 +0200 Subject: [PATCH 01/10] set upper limit for REP escape sequence argument Previously, printf 'L\033[2147483647b' would call tputc('L') 2^31 times, making st unresponsive. This commit allows repeating the last character at most 65535 times in order to prevent freezing and DoS attacks. --- st.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/st.c b/st.c index 77c3e8a..683493d 100644 --- a/st.c +++ b/st.c @@ -1643,7 +1643,7 @@ csihandle(void) ttywrite(vtiden, strlen(vtiden), 0); break; case 'b': /* REP -- if last char is printable print it more times */ - DEFAULT(csiescseq.arg[0], 1); + LIMIT(csiescseq.arg[0], 1, 65535); if (term.lastc) while (csiescseq.arg[0]-- > 0) tputc(term.lastc); From f20e169a20f3ee761f7e09714f1d4c10916cf4c6 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma Date: Sun, 17 Mar 2024 14:42:44 +0100 Subject: [PATCH 02/10] config.def.h: improve latency for the default configuration --- config.def.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.def.h b/config.def.h index 91ab8ca..2cd740a 100644 --- a/config.def.h +++ b/config.def.h @@ -53,7 +53,7 @@ int allowwindowops = 0; * near minlatency, but it waits longer for slow updates to avoid partial draw. * low minlatency will tear/flicker more, as it can "detect" idle too early. */ -static double minlatency = 8; +static double minlatency = 2; static double maxlatency = 33; /* From 5ce971628106fb767ef91bf4386227423f5fdf98 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma Date: Tue, 19 Mar 2024 12:13:42 +0100 Subject: [PATCH 03/10] bump version to 0.9.1 --- config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.mk b/config.mk index 1e306f8..7f35f71 100644 --- a/config.mk +++ b/config.mk @@ -1,5 +1,5 @@ # st version -VERSION = 0.9 +VERSION = 0.9.1 # Customize below to fit your system From 8c68ec52419f3f965164cafcf589b87e8961348d Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma Date: Sat, 30 Mar 2024 12:30:49 +0100 Subject: [PATCH 04/10] Revert "Fix cursor move with wide glyphs" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 7473a8d1a57e5f9aba41b953f4e498c35e1c9dc5. This patch needs some more work. It caused regressions with programs that use GNU readline, etc. Original test-case example from Tim Culverhouse : printf " 😀" && sleep 2 && printf "\e[D" && sleep 2 && printf "\e[D" && sleep 2 After the patch it caused regressions, example test-case: printf "A歗\bB\n" --- st.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/st.c b/st.c index 683493d..b9f66e7 100644 --- a/st.c +++ b/st.c @@ -86,8 +86,8 @@ enum escape_state { typedef struct { Glyph attr; /* current char attributes */ - int x; /* terminal column */ - int y; /* terminal row */ + int x; + int y; char state; } TCursor; @@ -2175,16 +2175,12 @@ tstrsequence(uchar c) void tcontrolcode(uchar ascii) { - size_t i; - switch (ascii) { case '\t': /* HT */ tputtab(1); return; case '\b': /* BS */ - for (i = 1; term.c.x && term.line[term.c.y][term.c.x - i].u == 0; ++i) - ; - tmoveto(term.c.x - i, term.c.y); + tmoveto(term.c.x-1, term.c.y); return; case '\r': /* CR */ tmoveto(0, term.c.y); From 497a75638291454875ba1ec8d484c7f3d6f41d66 Mon Sep 17 00:00:00 2001 From: DOGMAN Date: Wed, 3 Apr 2024 19:48:11 +0200 Subject: [PATCH 05/10] Reset title when an empty title string is given With this patch, st will reset its window title when an empty string is given as the terminal title. For example: printf "\033]0;\007" Some applications, like termdown, expect this functionality. xterm implements it, but it seems that most other terminal emulators don't. In any case, I don't see why there should ever be a case where the st window doesn't have a title property. --- x.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/x.c b/x.c index b36fb8c..bd23686 100644 --- a/x.c +++ b/x.c @@ -1617,6 +1617,9 @@ xseticontitle(char *p) XTextProperty prop; DEFAULT(p, opt_title); + if (p[0] == '\0') + p = opt_title; + if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, &prop) != Success) return; @@ -1631,6 +1634,9 @@ xsettitle(char *p) XTextProperty prop; DEFAULT(p, opt_title); + if (p[0] == '\0') + p = opt_title; + if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, &prop) != Success) return; From d63b9eb90245926b531bd54b1d591adb96613e70 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma Date: Fri, 5 Apr 2024 12:18:41 +0200 Subject: [PATCH 06/10] bump version to 0.9.2 --- config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.mk b/config.mk index 7f35f71..fdc29a7 100644 --- a/config.mk +++ b/config.mk @@ -1,5 +1,5 @@ # st version -VERSION = 0.9.1 +VERSION = 0.9.2 # Customize below to fit your system From 5dbcca49263be094fc38159c297458ae323ef647 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma Date: Wed, 1 May 2024 20:45:39 +0200 Subject: [PATCH 07/10] support colons in SGR character attributes Patch by Mikhail Kot With some modifications to behave more like xterm (see note below). Example: printf '\033[48;2;255:0:0mtest\n' https://invisible-island.net/xterm/ctlseqs/ctlseqs.html Some notes: "CSI Pm m Character Attributes (SGR). [...] o xterm allows either colons (standard) or semicolons (legacy) to separate the subparameters (but after the first colon, colons must be used). --- st.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/st.c b/st.c index b9f66e7..57c6e96 100644 --- a/st.c +++ b/st.c @@ -1132,6 +1132,7 @@ csiparse(void) { char *p = csiescseq.buf, *np; long int v; + int sep = ';'; /* colon or semi-colon, but not both */ csiescseq.narg = 0; if (*p == '?') { @@ -1149,7 +1150,9 @@ csiparse(void) v = -1; csiescseq.arg[csiescseq.narg++] = v; p = np; - if (*p != ';' || csiescseq.narg == ESC_ARG_SIZ) + if (sep == ';' && *p == ':') + sep = ':'; /* allow override to colon once */ + if (*p != sep || csiescseq.narg == ESC_ARG_SIZ) break; p++; } From a0274bc20e11d8672bb2953fdd1d3010c0e708c5 Mon Sep 17 00:00:00 2001 From: Lucas de Sena Date: Fri, 9 Aug 2024 13:33:47 +0200 Subject: [PATCH 08/10] fix BadMatch error when embedding on some windows When embedded, st fails with BadMatch error if the embedder's window has non-default colormap/depth/visual. This commit fixes that by creating st's window inside root and then reparent it into embedder. The reference window for dc.gc is also changed to match root's visuals. A similar commit had been made for dmenu[1]. See this issue[2] on github for context. [1]: https://git.suckless.org/dmenu/commit/0fe460dbd469a1d5b6a7140d0e1801935e4a923b.html [2]: https://github.com/phillbush/xfiles/issues/47 --- x.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/x.c b/x.c index bd23686..d73152b 100644 --- a/x.c +++ b/x.c @@ -1131,7 +1131,7 @@ xinit(int cols, int rows) { XGCValues gcvalues; Cursor cursor; - Window parent; + Window parent, root; pid_t thispid = getpid(); XColor xmousefg, xmousebg; @@ -1168,16 +1168,19 @@ xinit(int cols, int rows) | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; xw.attrs.colormap = xw.cmap; + root = XRootWindow(xw.dpy, xw.scr); if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) - parent = XRootWindow(xw.dpy, xw.scr); - xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t, + parent = root; + xw.win = XCreateWindow(xw.dpy, root, xw.l, xw.t, win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput, xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask | CWColormap, &xw.attrs); + if (parent != root) + XReparentWindow(xw.dpy, xw.win, parent, xw.l, xw.t); memset(&gcvalues, 0, sizeof(gcvalues)); gcvalues.graphics_exposures = False; - dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures, + dc.gc = XCreateGC(xw.dpy, xw.win, GCGraphicsExposures, &gcvalues); xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, DefaultDepth(xw.dpy, xw.scr)); From 6009e6e25bdff9548f085e9ae562b1ca305d3a0b Mon Sep 17 00:00:00 2001 From: Markus Rinne Date: Mon, 25 Nov 2024 13:31:56 +0200 Subject: [PATCH 09/10] Clear screen: Fix edge case With sequence \e[1J, if cursor is on second line, clear the first line. --- st.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/st.c b/st.c index 57c6e96..2e3800e 100644 --- a/st.c +++ b/st.c @@ -1705,7 +1705,7 @@ csihandle(void) } break; case 1: /* above */ - if (term.c.y > 1) + if (term.c.y > 0) tclearregion(0, 0, term.col-1, term.c.y-1); tclearregion(0, term.c.y, term.c.x, term.c.y); break; From 98610fcd37f655d44586323dc86c1d013c2798ce Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Sun, 26 Jan 2025 13:40:57 +0100 Subject: [PATCH 10/10] Do not interpret CSI ? u as DECRC The kitty keyboard protocol docs recommend CSI ? u to query support for that protocol, see https://sw.kovidgoyal.net/kitty/keyboard-protocol/ For better or worse, fish shell uses this query to work around bugs in other terminals triggered by requesting that protocol via CSI = 5 u. Unfortunately, st interprets CSI ? u as DECRC (restore cursor position). reproduce with 'printf "\x1b[?u"; cat'. fish could work around this by switching to the alternate screen before running this query; but that might cause tearing on terminals that don't support Synchronized Output. I'm not sure. In the meantime, let's correct our parser. This adds a redundant else-after-return, for consistency with the surrounding code. --- st.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/st.c b/st.c index 2e3800e..03b9bc8 100644 --- a/st.c +++ b/st.c @@ -1801,7 +1801,11 @@ csihandle(void) tcursor(CURSOR_SAVE); break; case 'u': /* DECRC -- Restore cursor position (ANSI.SYS) */ - tcursor(CURSOR_LOAD); + if (csiescseq.priv) { + goto unknown; + } else { + tcursor(CURSOR_LOAD); + } break; case ' ': switch (csiescseq.mode[1]) {