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