shithub: riscv

Download patch

ref: bf2195b88c9c1483d97cb4578f81467cad73c39e
parent: 9aa6573359ffad41ef197b7f83623d7cbdeca068
author: cinap_lenrek <[email protected]>
date: Sun Mar 27 12:38:39 EDT 2016

file: deal with negative coordinates in plan9 bitmaps, print image size

--- a/sys/src/cmd/file.c
+++ b/sys/src/cmd/file.c
@@ -167,7 +167,7 @@
 int	istar(void);
 int	isface(void);
 int	isexec(void);
-int	p9bitnum(uchar*);
+int	p9bitnum(char*, int*);
 int	p9subfont(uchar*);
 void	print_utf(void);
 void	type(char*, int);
@@ -1310,28 +1310,18 @@
  */
 #define	P9BITLEN	12
 int
-p9bitnum(uchar *bp)
+p9bitnum(char *s, int *v)
 {
-	int n, c, len;
+	char *es;
 
-	len = P9BITLEN;
-	while(*bp == ' ') {
-		bp++;
-		len--;
-		if(len <= 0)
-			return -1;
-	}
-	n = 0;
-	while(len > 1) {
-		c = *bp++;
-		if(!isdigit(c))
-			return -1;
-		n = n*10 + c-'0';
-		len--;
-	}
-	if(*bp != ' ')
+	if(s[P9BITLEN-1] != ' ')
 		return -1;
-	return n;
+	s[P9BITLEN-1] = '\0';
+	*v = strtol(s, &es, 10);
+	s[P9BITLEN-1] = ' ';
+	if(es != &s[P9BITLEN-1])
+		return -1;
+	return 0;
 }
 
 int
@@ -1347,13 +1337,18 @@
 	if(s == es)
 		return -1;
 	if('0'<=*s && *s<='9')
-		return 1<<strtol(s, 0, 0);
+		return 1<<strtol(s, nil, 0);
 
 	*newp = 1;
 	d = 0;
 	while(s<es && *s!=' '){
-		s++;			/* skip letter */
-		d += strtoul(s, &s, 10);
+		if(strchr("rgbkamx", *s) == nil)
+			return -1;
+		s++;
+		if('0'<=*s && *s<='9')
+			d += strtoul(s, &s, 10);
+		else
+			return -1;
 	}
 
 	if(d % 8 == 0 || 8 % d == 0)
@@ -1366,7 +1361,6 @@
 isp9bit(void)
 {
 	int dep, lox, loy, hix, hiy, px, new, cmpr;
-	ulong t;
 	long len;
 	char *newlabel;
 	uchar *cp;
@@ -1373,36 +1367,35 @@
 
 	cp = buf;
 	cmpr = 0;
-	newlabel = "old ";
-
 	if(memcmp(cp, "compressed\n", 11) == 0) {
 		cmpr = 1;
 		cp = buf + 11;
 	}
 
-	dep = depthof((char*)cp + 0*P9BITLEN, &new);
-	if(new)
-		newlabel = "";
-	lox = p9bitnum(cp + 1*P9BITLEN);
-	loy = p9bitnum(cp + 2*P9BITLEN);
-	hix = p9bitnum(cp + 3*P9BITLEN);
-	hiy = p9bitnum(cp + 4*P9BITLEN);
-	if(dep < 0 || lox < 0 || loy < 0 || hix < 0 || hiy < 0)
+	if((dep = depthof((char*)cp + 0*P9BITLEN, &new)) < 0)
 		return 0;
+	newlabel = new ? "" : "old ";
+	if(p9bitnum((char*)cp + 1*P9BITLEN, &lox) < 0)
+		return 0;
+	if(p9bitnum((char*)cp + 2*P9BITLEN, &loy) < 0)
+		return 0;
+	if(p9bitnum((char*)cp + 3*P9BITLEN, &hix) < 0)
+		return 0;
+	if(p9bitnum((char*)cp + 4*P9BITLEN, &hiy) < 0)
+		return 0;
 
+	hix -= lox;
+	hiy -= loy;
+	if(hix <= 0 || hiy <= 0)
+		return 0;
+
 	if(dep < 8){
 		px = 8/dep;		/* pixels per byte */
 		/* set l to number of bytes of data per scan line */
-		if(lox >= 0)
-			len = (hix+px-1)/px - lox/px;
-		else{			/* make positive before divide */
-			t = (-lox)+px-1;
-			t = (t/px)*px;
-			len = (t+hix+px-1)/px;
-		}
+		len = (hix+px-1)/px;
 	}else
-		len = (hix-lox)*dep/8;
-	len *= hiy - loy;		/* col length */
+		len = hix*dep/8;
+	len *= hiy;			/* col length */
 	len += 5 * P9BITLEN;		/* size of initial ascii */
 
 	/*
@@ -1412,8 +1405,8 @@
 	 * for subfont, the subfont header should follow immediately.
 	 */
 	if (cmpr) {
-		print(mime ? "image/p9bit\n" : "Compressed %splan 9 image or subfont, depth %d\n",
-			newlabel, dep);
+		print(mime ? "image/p9bit\n" : "Compressed %splan 9 image or subfont, depth %d, size %dx%d\n",
+			newlabel, dep, hix, hiy);
 		return 1;
 	}
 	/*
@@ -1422,11 +1415,13 @@
 	 */
 	if (len != 0 && (mbuf->length == 0 || mbuf->length == len ||
 	    mbuf->length > len && mbuf->length < len+P9BITLEN)) {
-		print(mime ? "image/p9bit\n" : "%splan 9 image, depth %d\n", newlabel, dep);
+		print(mime ? "image/p9bit\n" : "%splan 9 image, depth %d, size %dx%d\n",
+			newlabel, dep, hix, hiy);
 		return 1;
 	}
 	if (p9subfont(buf+len)) {
-		print(mime ? "image/p9bit\n" : "%ssubfont file, depth %d\n", newlabel, dep);
+		print(mime ? "image/p9bit\n" : "%ssubfont file, depth %d, size %dx%d\n",
+			newlabel, dep, hix, hiy);
 		return 1;
 	}
 	return 0;
@@ -1441,16 +1436,15 @@
 	if (p+3*P9BITLEN > buf+sizeof(buf))
 		return 1;
 
-	n = p9bitnum(p + 0*P9BITLEN);	/* char count */
-	if (n < 0)
+	if (p9bitnum((char*)p + 0*P9BITLEN, &n) < 0)	/* char count */
 		return 0;
-	h = p9bitnum(p + 1*P9BITLEN);	/* height */
-	if (h < 0)
+	if (p9bitnum((char*)p + 1*P9BITLEN, &h) < 0)	/* height */
 		return 0;
-	a = p9bitnum(p + 2*P9BITLEN);	/* ascent */
-	if (a < 0)
+	if (p9bitnum((char*)p + 2*P9BITLEN, &a) < 0)	/* ascent */
 		return 0;
-	return 1;
+	if(n > 0 && h > 0 && a >= 0)
+		return 1;
+	return 0;
 }
 
 #define	WHITESPACE(c)		((c) == ' ' || (c) == '\t' || (c) == '\n')