add memory fixes from upstream: fixes crashes from plumbing

This commit is contained in:
Iris Lightshard 2021-06-13 14:41:51 -06:00
parent 5540d37849
commit 1ec33c665f
Signed by: Iris Lightshard
GPG key ID: 3B7FBC22144E6398
6 changed files with 44 additions and 28 deletions

6
acme.c
View file

@ -368,7 +368,7 @@ static int errorfd;
int erroutfd;
void acmeerrorproc(void* v) {
char *buf, *s;
char* buf;
int n;
USED(v);
@ -376,9 +376,7 @@ void acmeerrorproc(void* v) {
buf = emalloc(8192 + 1);
while ((n = read(errorfd, buf, 8192)) >= 0) {
buf[n] = '\0';
s = estrdup(buf);
sendp(cerr, s);
free(s);
sendp(cerr, estrdup(buf));
}
free(buf);
}

28
ecmd.c
View file

@ -28,7 +28,7 @@ int append(File*, Cmd*, long);
int pdisplay(File*);
void pfilename(File*);
void looper(File*, Cmd*, int);
void filelooper(Cmd*, int);
void filelooper(Text*, Cmd*, int);
void linelooper(File*, Cmd*);
Address lineaddr(long, Address, int);
int filematch(File*, String*);
@ -529,7 +529,7 @@ int x_cmd(Text* t, Cmd* cp) {
int X_cmd(Text* t, Cmd* cp) {
USED(t);
filelooper(cp, cp->cmdc == 'X');
filelooper(t, cp, cp->cmdc == 'X');
return TRUE;
}
@ -902,8 +902,9 @@ void alllocker(Window* w, void* v) {
winclose(w);
}
void filelooper(Cmd* cp, int XY) {
void filelooper(Text* t, Cmd* cp, int XY) {
int i;
Text* targ;
if (Glooping++)
editerror("can't nest %c command", "YX"[XY]);
@ -924,8 +925,25 @@ void filelooper(Cmd* cp, int XY) {
*/
allwindows(alllocker, (void*)1);
globalincref = 1;
for (i = 0; i < loopstruct.nw; i++)
cmdexec(&loopstruct.w[i]->body, cp->u.cmd);
/*
* Unlock the window running the X command.
* We'll need to lock and unlock each target window in turn.
*/
if (t && t->w)
winunlock(t->w);
for (i = 0; i < loopstruct.nw; i++) {
targ = &loopstruct.w[i]->body;
if (targ && targ->w)
winlock(targ->w, cp->cmdc);
cmdexec(targ, cp->u.cmd);
if (targ && targ->w)
winunlock(targ->w);
}
if (t && t->w)
winlock(t->w, cp->cmdc);
allwindows(alllocker, (void*)0);
globalincref = 0;
free(loopstruct.w);

2
fns.h
View file

@ -95,7 +95,7 @@ void flushwarnings(void);
void startplumbing(void);
long nlcount(Text*, long, long, long*);
long nlcounttopos(Text*, long, long, long);
Rune* parsetag(Window*, int*);
Rune* parsetag(Window*, int, int*);
Runestr runestr(Rune*, uint);
Range range(int, int);

2
look.c
View file

@ -496,7 +496,7 @@ Runestr dirname(Text* t, Rune* r, int n) {
goto Rescue;
if (n >= 1 && r[0] == '/')
goto Rescue;
b = parsetag(t->w, &i);
b = parsetag(t->w, n, &i);
slash = -1;
for (i--; i >= 0; i--) {
if (b[i] == '/') {

2
util.c
View file

@ -254,6 +254,8 @@ void warning(Mntdir* md, char* s, ...) {
int runeeq(Rune* s1, uint n1, Rune* s2, uint n2) {
if (n1 != n2)
return FALSE;
if (n1 == 0)
return TRUE;
return memcmp(s1, s2, n1 * sizeof(Rune)) == 0;
}

32
wind.c
View file

@ -106,18 +106,15 @@ void windrawbutton(Window* w) {
}
int delrunepos(Window* w) {
int n;
Rune rune;
Rune* r;
int i;
for (n = 0; n < w->tag.file->b.nc; n++) {
bufread(&w->tag.file->b, n, &rune, 1);
if (rune == ' ')
break;
}
n += 2;
if (n >= w->tag.file->b.nc)
r = parsetag(w, 0, &i);
free(r);
i += 2;
if (i >= w->tag.file->b.nc)
return -1;
return n;
return i;
}
void movetodel(Window* w) {
@ -390,7 +387,7 @@ void wincleartag(Window* w) {
/* w must be committed */
n = w->tag.file->b.nc;
r = parsetag(w, &i);
r = parsetag(w, 0, &i);
for (; i < n; i++)
if (r[i] == '|')
break;
@ -407,15 +404,15 @@ void wincleartag(Window* w) {
textsetselect(&w->tag, w->tag.q0, w->tag.q1);
}
Rune* parsetag(Window* w, int* len) {
Rune* parsetag(Window* w, int extra, int* len) {
static Rune Ldelsnarf[] =
{' ', 'D', 'e', 'l', ' ', 'S', 'n', 'a', 'r', 'f', 0};
static Rune Lspacepipe[] = {' ', '|', 0};
static Rune Ltabpipe[] = {' ', '|', 0};
static Rune Ltabpipe[] = {'\t', '|', 0};
int i;
Rune *r, *p, *pipe;
r = runemalloc(w->tag.file->b.nc + 1);
r = runemalloc(w->tag.file->b.nc + extra + 1);
bufread(&w->tag.file->b, 0, r, w->tag.file->b.nc);
r[w->tag.file->b.nc] = '\0';
@ -460,7 +457,7 @@ void winsettag1(Window* w) {
if (w->tag.ncache != 0 || w->tag.file->mod)
wincommit(w, &w->tag); /* check file name; also guarantees we can modify tag
contents */
old = parsetag(w, &i);
old = parsetag(w, 0, &i);
if (runeeq(old, i, w->body.file->name, w->body.file->nname) == FALSE) {
textdelete(&w->tag, 0, i, TRUE);
textinsert(&w->tag, 0, w->body.file->name, w->body.file->nname, TRUE);
@ -473,7 +470,8 @@ void winsettag1(Window* w) {
/* compute the text for the whole tag, replacing current only if it differs */
new = runemalloc(w->body.file->nname + 100);
i = 0;
runemove(new + i, w->body.file->name, w->body.file->nname);
if (w->body.file->nname != 0)
runemove(new, w->body.file->name, w->body.file->nname);
i += w->body.file->nname;
runemove(new + i, Ldelsnarf, 10);
i += 10;
@ -577,7 +575,7 @@ void wincommit(Window* w, Text* t) {
textcommit(f->text[i], FALSE); /* no-op for t */
if (t->what == Body)
return;
r = parsetag(w, &i);
r = parsetag(w, 0, &i);
if (runeeq(r, i, w->body.file->name, w->body.file->nname) == FALSE) {
seq++;
filemark(w->body.file);