From 8446609384429bfc4342ede4b52ff42214ad2b77 Mon Sep 17 00:00:00 2001
From: Rizqi Nur Assyaufi <bandithijo@gmail.com>
Date: Mon, 18 Jul 2022 00:35:26 +0800
Subject: [PATCH] Fixes title parsing for st-0.8.5

In st, titles get truncated after the first ';' character, this patch
fixes that.
---
 st.c | 38 ++++++++++++++++++++------------------
 1 file changed, 20 insertions(+), 18 deletions(-)

diff --git a/st.c b/st.c
index 51049ba..a2e595c 100644
--- a/st.c
+++ b/st.c
@@ -42,6 +42,8 @@
 #define ISCONTROLC1(c)		(BETWEEN(c, 0x80, 0x9f))
 #define ISCONTROL(c)		(ISCONTROLC0(c) || ISCONTROLC1(c))
 #define ISDELIM(u)		(u && wcschr(worddelimiters, u))
+#define STRESCARGREST(n)	((n) == 0 ? strescseq.buf : strescseq.argp[(n)-1] + 1)
+#define STRESCARGJUST(n)	(*(strescseq.argp[n]) = '\0', STRESCARGREST(n))
 
 enum term_mode {
 	MODE_WRAP        = 1 << 0,
@@ -148,7 +150,7 @@ typedef struct {
 	char *buf;             /* allocated raw string */
 	size_t siz;            /* allocation size */
 	size_t len;            /* raw string length */
-	char *args[STR_ARG_SIZ];
+	char *argp[STR_ARG_SIZ]; /* pointers to the end of nth argument */
 	int narg;              /* nb of args */
 } STREscape;
 
@@ -1885,29 +1887,30 @@ strhandle(void)
 	int j, narg, par;
 
 	term.esc &= ~(ESC_STR_END|ESC_STR);
-	strparse();
-	par = (narg = strescseq.narg) ? atoi(strescseq.args[0]) : 0;
+	strescseq.buf[strescseq.len] = '\0';
 
 	switch (strescseq.type) {
 	case ']': /* OSC -- Operating System Command */
+		strparse();
+		par = (narg = strescseq.narg) ? atoi(STRESCARGJUST(0)) : 0;
 		switch (par) {
 		case 0:
 			if (narg > 1) {
-				xsettitle(strescseq.args[1]);
-				xseticontitle(strescseq.args[1]);
+				xsettitle(STRESCARGREST(1));
+				xseticontitle(STRESCARGREST(1));
 			}
 			return;
 		case 1:
 			if (narg > 1)
-				xseticontitle(strescseq.args[1]);
+				xseticontitle(STRESCARGREST(1));
 			return;
 		case 2:
 			if (narg > 1)
-				xsettitle(strescseq.args[1]);
+				xsettitle(STRESCARGREST(1));
 			return;
 		case 52:
 			if (narg > 2 && allowwindowops) {
-				dec = base64dec(strescseq.args[2]);
+				dec = base64dec(STRESCARGJUST(2));
 				if (dec) {
 					xsetsel(dec);
 					xclipcopy();
@@ -1920,7 +1923,7 @@ strhandle(void)
 			if (narg < 2)
 				break;
 
-			p = strescseq.args[1];
+			p = STRESCARGREST(1);
 
 			if (!strcmp(p, "?"))
 				osc_color_response(defaultfg, 10);
@@ -1933,7 +1936,7 @@ strhandle(void)
 			if (narg < 2)
 				break;
 
-			p = strescseq.args[1];
+			p = STRESCARGREST(1);
 
 			if (!strcmp(p, "?"))
 				osc_color_response(defaultbg, 11);
@@ -1946,7 +1949,7 @@ strhandle(void)
 			if (narg < 2)
 				break;
 
-			p = strescseq.args[1];
+			p = STRESCARGREST(1);
 
 			if (!strcmp(p, "?"))
 				osc_color_response(defaultcs, 12);
@@ -1958,10 +1961,10 @@ strhandle(void)
 		case 4: /* color set */
 			if (narg < 3)
 				break;
-			p = strescseq.args[2];
+			p = STRESCARGJUST(2);
 			/* FALLTHROUGH */
 		case 104: /* color reset */
-			j = (narg > 1) ? atoi(strescseq.args[1]) : -1;
+			j = (narg > 1) ? atoi(STRESCARGJUST(1)) : -1;
 
 			if (p && !strcmp(p, "?"))
 				osc4_color_response(j);
@@ -1981,7 +1984,7 @@ strhandle(void)
 		}
 		break;
 	case 'k': /* old title set compatibility */
-		xsettitle(strescseq.args[0]);
+		xsettitle(strescseq.buf);
 		return;
 	case 'P': /* DCS -- Device Control String */
 	case '_': /* APC -- Application Program Command */
@@ -2000,18 +2003,17 @@ strparse(void)
 	char *p = strescseq.buf;
 
 	strescseq.narg = 0;
-	strescseq.buf[strescseq.len] = '\0';
 
 	if (*p == '\0')
 		return;
 
 	while (strescseq.narg < STR_ARG_SIZ) {
-		strescseq.args[strescseq.narg++] = p;
 		while ((c = *p) != ';' && c != '\0')
-			++p;
+			p++;
+		strescseq.argp[strescseq.narg++] = p;
 		if (c == '\0')
 			return;
-		*p++ = '\0';
+		p++;
 	}
 }
 
-- 
2.37.1