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

28
ecmd.c
View file

@ -28,7 +28,7 @@ int append(File*, Cmd*, long);
int pdisplay(File*); int pdisplay(File*);
void pfilename(File*); void pfilename(File*);
void looper(File*, Cmd*, int); void looper(File*, Cmd*, int);
void filelooper(Cmd*, int); void filelooper(Text*, Cmd*, int);
void linelooper(File*, Cmd*); void linelooper(File*, Cmd*);
Address lineaddr(long, Address, int); Address lineaddr(long, Address, int);
int filematch(File*, String*); int filematch(File*, String*);
@ -529,7 +529,7 @@ int x_cmd(Text* t, Cmd* cp) {
int X_cmd(Text* t, Cmd* cp) { int X_cmd(Text* t, Cmd* cp) {
USED(t); USED(t);
filelooper(cp, cp->cmdc == 'X'); filelooper(t, cp, cp->cmdc == 'X');
return TRUE; return TRUE;
} }
@ -902,8 +902,9 @@ void alllocker(Window* w, void* v) {
winclose(w); winclose(w);
} }
void filelooper(Cmd* cp, int XY) { void filelooper(Text* t, Cmd* cp, int XY) {
int i; int i;
Text* targ;
if (Glooping++) if (Glooping++)
editerror("can't nest %c command", "YX"[XY]); editerror("can't nest %c command", "YX"[XY]);
@ -924,8 +925,25 @@ void filelooper(Cmd* cp, int XY) {
*/ */
allwindows(alllocker, (void*)1); allwindows(alllocker, (void*)1);
globalincref = 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); allwindows(alllocker, (void*)0);
globalincref = 0; globalincref = 0;
free(loopstruct.w); free(loopstruct.w);

2
fns.h
View file

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

2
look.c
View file

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