git: 9front

Download patch

ref: ec325a67501696be009576039de41f230f81b27d
parent: aae224a92023099c786253c706297fd619f3f352
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Nov 9 17:44:43 EST 2025

vt: correctly handle terminators in osc codes

when we get an osc control code, we were gobbling the '\a' terminator,
and assuming any \033 code was a terminator, not just \033\\; this was
not correct, and would lead us to attempting to read an unbounded amount
of input for an osc code.

--- a/sys/src/cmd/vt/vt.c
+++ b/sys/src/cmd/vt/vt.c
@@ -891,7 +891,7 @@
 			n = 1;
 			c = 0;
 			while (!cs->raw && host_avail() && x+n<=xmax && n<BUFS
-			    && (c = nextcmd())>=' ' && c<'\177') {
+			    && (c = nextchar())>=' ' && c<'\177') {
 				buf[n++] = c;
 				c = 0;
 			}
@@ -1027,14 +1027,41 @@
 	return 1;
 }
 
+static int
+readosc(char *buf, int nbuf)
+{
+	Rune ch;
+	int i;
 
+	i = 0;
+	while(1){
+		ch = nextchar();
+		if(ch == '\a')
+			break;
+		if(ch == '\033'){
+			ch = nextchar();
+			if(ch == '\\')
+				break;
+			if(i < nbuf - UTFmax - 1)
+				buf[i++] = '\033';
+		}
+		if(cursctl(ch))
+			continue;
+		if(i < nbuf - UTFmax - 1)
+			i += runetochar(buf+i, &ch);
+	}
+	buf[i] = 0;
+	return i;
+}
+
 // handle ESC], Operating System Command
 static void
 osc(void)
 {
-	Rune ch, buf[BUFS+1];
-	int fd, osc, got, i;
+	char buf[BUFS];
+	int fd, osc, got;
 	char *o, *s;
+	Rune ch;
 
 	osc = number(&ch, &got);
 	if(got) {
@@ -1042,30 +1069,15 @@
 		case 0:
 		case 1:
 		case 2: /* set title */
-			i = 0;
-
-			while((ch = nextcmd()) != '\a') {
-				if(i < nelem(buf) - 1) {
-					buf[i++] = ch;
-				}
-			}
-			buf[i] = 0;
+			readosc(buf, sizeof(buf));
 			if((fd = open("/dev/label", OWRITE)) >= 0) {
-				fprint(fd, "%S", buf);
+				fprint(fd, "%s", buf);
 				close(fd);
 			}
 			break;
 
 		case 7: /* set pwd */
-			i = 0;
-
-			while((ch = nextcmd()) != '\033'){
-				if(i < sizeof(osc7cwd)-UTFmax-1)
-					i += runetochar(osc7cwd+i, &ch);
-			}
-			nextcmd();
-			osc7cwd[i] = 0;
-
+			readosc(osc7cwd, sizeof(osc7cwd));
 			/* file://hostname/path → /n/hostname/path */
 			if(strncmp(osc7cwd, "file://", 7) == 0){
 				osc7cwd[0] = '/';
--