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;
}
--
⑨