From 1ec33c665f78a76f8b038af8ae857e44ccc1af30 Mon Sep 17 00:00:00 2001 From: Derek Stevens Date: Sun, 13 Jun 2021 14:41:51 -0600 Subject: [PATCH] add memory fixes from upstream: fixes crashes from plumbing --- acme.c | 6 ++---- ecmd.c | 28 +++++++++++++++++++++++----- fns.h | 2 +- look.c | 2 +- util.c | 2 ++ wind.c | 32 +++++++++++++++----------------- 6 files changed, 44 insertions(+), 28 deletions(-) diff --git a/acme.c b/acme.c index 5cbe271..1392d61 100644 --- a/acme.c +++ b/acme.c @@ -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); } diff --git a/ecmd.c b/ecmd.c index cdc5765..2ae8403 100644 --- a/ecmd.c +++ b/ecmd.c @@ -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); diff --git a/fns.h b/fns.h index 0078f44..ec7ba90 100644 --- a/fns.h +++ b/fns.h @@ -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); diff --git a/look.c b/look.c index 8b122db..aeb2d42 100644 --- a/look.c +++ b/look.c @@ -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] == '/') { diff --git a/util.c b/util.c index 74377f4..80322f1 100644 --- a/util.c +++ b/util.c @@ -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; } diff --git a/wind.c b/wind.c index c85fba0..88ae454 100644 --- a/wind.c +++ b/wind.c @@ -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);