git: 9front

Download patch

ref: c30e30bd41b7328120127aec5b19fc036798d2e3
parent: 2191d72205863d2c53ea6ac36991cb4c13204c7c
author: rodri <rgl@antares-labs.eu>
date: Sun Jan 25 13:06:41 EST 2026

lib(mem)draw: assert chan type uniqueness except for CIgnore

without this check it's possible to create images with multiple
channels of the same type, contrary to the documented image(6)
format.

--- a/sys/src/libdraw/chan.c
+++ b/sys/src/libdraw/chan.c
@@ -41,11 +41,11 @@
 {
 	char *p, *q;
 	ulong c;
-	int t, n, d;
+	int usedt, t, n, d;
 
 	c = 0;
-	d = 0;
-	p=s;
+	d = usedt = 0;
+	p = s;
 	while(*p && isspace(*p))
 		p++;
 
@@ -53,6 +53,8 @@
 		if((q = strchr(channames, p[0])) == nil) 
 			return 0;
 		t = q-channames;
+		if(t != CIgnore && usedt & (1<<t))
+			return 0;
 		if(p[1] < '0' || p[1] > '9')
 			return 0;
 		n = p[1]-'0';
@@ -59,6 +61,7 @@
 		d += n;
 		c = (c<<8) | __DC(t, n);
 		p += 2;
+		usedt |= 1<<t;
 	}
 	if(d==0 || (d>8 && d%8) || (d<8 && 8%d))
 		return 0;
--- a/sys/src/libmemdraw/alloc.c
+++ b/sys/src/libmemdraw/alloc.c
@@ -142,7 +142,7 @@
 	int d;
 	int t, j, k;
 	ulong cc;
-	int bytes;
+	int bytes, usedt;
 
 	if((d = chantodepth(chan)) == 0) {
 		werrstr("bad channel descriptor");
@@ -153,9 +153,10 @@
 	i->chan = chan;
 	i->flags &= ~(Fgrey|Falpha|Fcmap|Fbytes);
 	bytes = 1;
+	usedt = 0;
 	for(cc=chan, j=0, k=0; cc; j+=NBITS(cc), cc>>=8, k++){
 		t=TYPE(cc);
-		if(t < 0 || t >= NChan){
+		if(t < 0 || t >= NChan || (t != CIgnore && usedt & (1<<t))){
 			werrstr("bad channel string");
 			return -1;
 		}
@@ -171,6 +172,7 @@
 		i->shift[t] = j;
 		i->mask[t] = (1<<NBITS(cc))-1;
 		i->nbits[t] = NBITS(cc);
+		usedt |= 1<<t;
 		if(NBITS(cc) != 8)
 			bytes = 0;
 	}
--