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.
This commit is contained in:
cinap_lenrek 2014-12-11 20:20:47 +01:00
parent 86e63c36ed
commit 854d028db9
2 changed files with 21 additions and 40 deletions

View file

@ -602,10 +602,10 @@ putfile(File *f, int q0, int q1, Rune *namer, int nname)
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;

View file

@ -147,10 +147,10 @@ xfidopen(Xfid *x)
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,20 +582,14 @@ xfidctlwrite(Xfid *x, Window *w)
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;
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 @@ out:
m++;
}
if(isfbuf)
fbuffree(r);
else
free(r);
free(r);
if(err)
n = 0;
fc.count = n;
@ -794,19 +785,12 @@ xfideventwrite(Xfid *x, Window *w)
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 @@ xfideventwrite(Xfid *x, Window *w)
}
Out:
if(isfbuf)
fbuffree(r);
else
free(r);
free(r);
if(err)
n = 0;
fc.count = n;
@ -886,7 +867,7 @@ xfidutfread(Xfid *x, Text *t, uint q1, int qid)
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 @@ xfidutfread(Xfid *x, Text *t, uint q1, int qid)
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 @@ xfidutfread(Xfid *x, Text *t, uint q1, int qid)
fc.count = n;
fc.data = b1;
respond(x, &fc, nil);
fbuffree(b1);
free(b1);
}
int
@ -950,16 +931,16 @@ xfidruneread(Xfid *x, Text *t, uint q0, uint q1)
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 @@ xfidruneread(Xfid *x, Text *t, uint q0, uint q1)
fc.count = n;
fc.data = b1;
respond(x, &fc, nil);
fbuffree(b1);
free(b1);
return q-q0;
}