shithub: riscv

Download patch

ref: 854d028db99d81752082028700bd7ada53306424
parent: 86e63c36eded29e46a17628264b73d743df9a864
author: cinap_lenrek <[email protected]>
date: Thu Dec 11 15:20:47 EST 2014

acme: fix buffer overrun in xfidutfread() and xfidruneread(), cleanup

the utf8 buffers b1 where allocated from fbufalloc() which gives
us BUFSIZE bytes, but Xfid->count can be bigger than that. so just
emalloc() the requested number of bytes.

when converting from Runes to utf-8, we have to account for the
terminating '\0' byte snprint() places, so fix the maxrune number
calculation instead of using BUFSIZE+1 as buffer size.

--- a/sys/src/cmd/acme/exec.c
+++ b/sys/src/cmd/acme/exec.c
@@ -602,10 +602,10 @@
 
 	for(q=q0; q<q1; q+=n){
 		n = q1 - q;
-		if(n > BUFSIZE/UTFmax)
-			n = BUFSIZE/UTFmax;
+		if(n > (BUFSIZE-1)/UTFmax)
+			n = (BUFSIZE-1)/UTFmax;
 		bufread(f, q, r, n);
-		m = snprint(s, BUFSIZE+1, "%.*S", n, r);
+		m = snprint(s, BUFSIZE, "%.*S", n, r);
 		if(write(fd, s, m) != m){
 			warning(nil, "can't write file %s: %r\n", name);
 			goto Rescue2;
--- a/sys/src/cmd/acme/xfid.c
+++ b/sys/src/cmd/acme/xfid.c
@@ -147,10 +147,10 @@
 			s = fbufalloc();
 			while(q0 < q1){
 				n = q1 - q0;
-				if(n > BUFSIZE/UTFmax)
-					n = BUFSIZE/UTFmax;
+				if(n > (BUFSIZE-1)/UTFmax)
+					n = (BUFSIZE-1)/UTFmax;
 				bufread(t->file, q0, r, n);
-				m = snprint(s, BUFSIZE+1, "%.*S", n, r);
+				m = snprint(s, BUFSIZE, "%.*S", n, r);
 				if(write(w->rdselfd, s, m) != m){
 					warning(nil, "can't write temp file for pipe command %r\n");
 					break;
@@ -582,7 +582,7 @@
 	int i, m, n, nb, nr, nulls;
 	Rune *r;
 	char *err, *p, *pp, *q, *e;
-	int isfbuf, scrdraw, settag;
+	int scrdraw, settag;
 	Text *t;
 
 	err = nil;
@@ -589,13 +589,7 @@
 	e = x->data+x->count;
 	scrdraw = FALSE;
 	settag = FALSE;
-	isfbuf = TRUE;
-	if(x->count < RBUFSIZE)
-		r = fbufalloc();
-	else{
-		isfbuf = FALSE;
-		r = emalloc(x->count*UTFmax+1);
-	}
+	r = emalloc(x->count*UTFmax+1);
 	x->data[x->count] = 0;
 	textcommit(&w->tag, TRUE);
 	for(n=0; n<x->count; n+=m){
@@ -773,10 +767,7 @@
 			m++;
 	}
 
-	if(isfbuf)
-		fbuffree(r);
-	else
-		free(r);
+	free(r);
 	if(err)
 		n = 0;
 	fc.count = n;
@@ -794,19 +785,12 @@
 	int m, n;
 	Rune *r;
 	char *err, *p, *q;
-	int isfbuf;
 	Text *t;
 	int c;
 	uint q0, q1;
 
 	err = nil;
-	isfbuf = TRUE;
-	if(x->count < RBUFSIZE)
-		r = fbufalloc();
-	else{
-		isfbuf = FALSE;
-		r = emalloc(x->count*UTFmax+1);
-	}
+ 	r = emalloc(x->count*UTFmax+1);
 	for(n=0; n<x->count; n+=m){
 		p = x->data+n;
 		w->owner = *p++;	/* disgusting */
@@ -856,10 +840,7 @@
 	}
 
     Out:
-	if(isfbuf)
-		fbuffree(r);
-	else
-		free(r);
+	free(r);
 	if(err)
 		n = 0;
 	fc.count = n;
@@ -886,7 +867,7 @@
 	off = x->offset;
 	r = fbufalloc();
 	b = fbufalloc();
-	b1 = fbufalloc();
+	b1 = emalloc(x->count);
 	n = 0;
 	if(qid==w->utflastqid && off>=w->utflastboff && w->utflastq<=q1){
 		boff = w->utflastboff;
@@ -906,10 +887,10 @@
 		w->utflastboff = boff;
 		w->utflastq = q;
 		nr = q1-q;
-		if(nr > BUFSIZE/UTFmax)
-			nr = BUFSIZE/UTFmax;
+		if(nr > (BUFSIZE-1)/UTFmax)
+			nr = (BUFSIZE-1)/UTFmax;
 		bufread(t->file, q, r, nr);
-		nb = snprint(b, BUFSIZE+1, "%.*S", nr, r);
+		nb = snprint(b, BUFSIZE, "%.*S", nr, r);
 		if(boff >= off){
 			m = nb;
 			if(boff+m > off+x->count)
@@ -933,7 +914,7 @@
 	fc.count = n;
 	fc.data = b1;
 	respond(x, &fc, nil);
-	fbuffree(b1);
+	free(b1);
 }
 
 int
@@ -950,16 +931,16 @@
 	wincommit(w, t);
 	r = fbufalloc();
 	b = fbufalloc();
-	b1 = fbufalloc();
+	b1 = emalloc(x->count);
 	n = 0;
 	q = q0;
 	boff = 0;
 	while(q<q1 && n<x->count){
 		nr = q1-q;
-		if(nr > BUFSIZE/UTFmax)
-			nr = BUFSIZE/UTFmax;
+		if(nr > (BUFSIZE-1)/UTFmax)
+			nr = (BUFSIZE-1)/UTFmax;
 		bufread(t->file, q, r, nr);
-		nb = snprint(b, BUFSIZE+1, "%.*S", nr, r);
+		nb = snprint(b, BUFSIZE, "%.*S", nr, r);
 		m = nb;
 		if(boff+m > x->count){
 			i = x->count - boff;
@@ -986,7 +967,7 @@
 	fc.count = n;
 	fc.data = b1;
 	respond(x, &fc, nil);
-	fbuffree(b1);
+	free(b1);
 	return q-q0;
 }