git: 9front

Download patch

ref: 3671a33a24cb47659ceae9ab3d070b9ac8ddf7ed
parent: 5ba6c22fafed27542b105dc293371d2b1a1c8a1d
author: Ori Bernstein <ori@eigenstate.org>
date: Tue Jan 20 11:43:05 EST 2026

troff: check bounds for \D commands

when given an invalid \D command, we could crash
by indexing out of bounds in ptout0; this change
passes the index and checks bounds.

--- a/sys/src/cmd/troff/fns.h
+++ b/sys/src/cmd/troff/fns.h
@@ -294,7 +294,7 @@
 void	t_ptinit(void);
 void	t_specnames(void);
 void	t_ptout(Tchar i);
-int	ptout0(Tchar *pi);
+int	ptout0(Tchar *pi, int);
 void	ptchname(int);
 void	ptflush(void);
 void	ptps(void);
--- a/sys/src/cmd/troff/t10.c
+++ b/sys/src/cmd/troff/t10.c
@@ -143,7 +143,7 @@
 	lead += dip->blss + lss;
 	dip->blss = 0;
 	for (k = oline; k < olinep; )
-		k += ptout0(k);	/* now passing a pointer! */
+		k += ptout0(k, olinep - k);	/* now passing a pointer! */
 	olinep = oline;
 	lead += dip->alss;
 	a = dip->alss;
@@ -154,7 +154,7 @@
 	OUT "n%d %d\n", b, a PUT;	/* be nice to chuck */
 }
 
-int ptout0(Tchar *pi)
+int ptout0(Tchar *pi, int np)
 {
 	int j, k, w, z, dx, dy, dx2, dy2, n;
 	int outsize;	/* size of object being printed */
@@ -207,8 +207,10 @@
 			ptlead();
 		OUT "x X " PUT;
 		xon++;
-		for (j = 1; cbits(pi[j]) != XOFF; j++)
+		for (j = 1; j+1 < np && cbits(pi[j]) != XOFF; j++)
 			outascii(pi[j]);
+		if(cbits(pi[j]) != XOFF)
+			ERROR "invalid xon drawing" FATAL;
 		oput('\n');
 		xon--;
 		return j+1;
@@ -250,6 +252,8 @@
 	if (k == DRAWFCN) {
 		if (esc)
 			ptesc();
+		if(np < 5)
+			ERROR "invalid draw" FATAL;
 		w = 0;
 		dx = absmot(pi[3]);
 		if (isnmot(pi[3]))
@@ -286,6 +290,8 @@
 			vpos += dy;
 			break;
 		case DRAWARC:	/* arc */
+			if(np < 7)
+				ERROR "invalid draw" FATAL;
 			dx2 = absmot(pi[5]);
 			if (isnmot(pi[5]))
 				dx2 = -dx2;
@@ -310,7 +316,7 @@
 				OUT "\n" PUT;
 				break;
 			}
-			for (n = 5; cbits(pi[n]) != DRAWFCN; n += 2) {
+			for (n = 5; n+1 < np && cbits(pi[n]) != DRAWFCN; n += 2) {
 				dx = absmot(pi[n]);
 				if (isnmot(pi[n]))
 					dx = -dx;
@@ -321,10 +327,12 @@
 				hpos += dx;
 				vpos += dy;
 			}
+			if (cbits(pi[n]) != DRAWFCN)
+				ERROR "invalid spline drawing" FATAL;
 			OUT "\n" PUT;
 			break;
 		}
-		for (n = 3; cbits(pi[n]) != DRAWFCN; n++)
+		for (n = 3; n < np && cbits(pi[n]) != DRAWFCN; n++)
 			;
 		outsize = n + 1;
 	} else if (k < ALPHABET) {
--