Two bug fixes.

1. Make sure cmdname NUL-terminates its arguments.
2. Fix the elogapply warning, hopefully.
This commit is contained in:
rsc 2005-03-23 20:19:53 +00:00
parent 97f2be1c5f
commit 5e77b8bb61
2 changed files with 31 additions and 43 deletions

View file

@ -137,7 +137,6 @@ edittext(Window *w, int q, Rune *r, int nr)
case Inactive: case Inactive:
return "permission denied"; return "permission denied";
case Inserting: case Inserting:
w->neditwrsel += nr;
eloginsert(f, q, r, nr); eloginsert(f, q, r, nr);
return nil; return nil;
case Collecting: case Collecting:
@ -215,7 +214,7 @@ c_cmd(Text *t, Cmd *cp)
{ {
elogreplace(t->file, addr.r.q0, addr.r.q1, cp->u.text->r, cp->u.text->n); elogreplace(t->file, addr.r.q0, addr.r.q1, cp->u.text->r, cp->u.text->n);
t->q0 = addr.r.q0; t->q0 = addr.r.q0;
t->q1 = addr.r.q0+cp->u.text->n; t->q1 = addr.r.q1;
return TRUE; return TRUE;
} }
@ -520,7 +519,7 @@ s_cmd(Text *t, Cmd *cp)
if(!didsub && nest==0) if(!didsub && nest==0)
editerror("no substitution"); editerror("no substitution");
t->q0 = addr.r.q0; t->q0 = addr.r.q0;
t->q1 = addr.r.q1+delta; t->q1 = addr.r.q1;
return TRUE; return TRUE;
Err: Err:
@ -602,7 +601,6 @@ runpipe(Text *t, int cmd, Rune *cr, int ncr, int state)
w = t->w; w = t->w;
t->q0 = addr.r.q0; t->q0 = addr.r.q0;
t->q1 = addr.r.q1; t->q1 = addr.r.q1;
w->neditwrsel = 0;
if(cmd == '<' || cmd=='|') if(cmd == '<' || cmd=='|')
elogdelete(t->file, t->q0, t->q1); elogdelete(t->file, t->q0, t->q1);
} }
@ -632,10 +630,6 @@ runpipe(Text *t, int cmd, Rune *cr, int ncr, int state)
editing = Inactive; editing = Inactive;
if(t!=nil && t->w!=nil) if(t!=nil && t->w!=nil)
winlock(t->w, 'M'); winlock(t->w, 'M');
if(state == Inserting){
t->q0 = addr.r.q0;
t->q1 = addr.r.q0 + t->w->neditwrsel;
}
} }
int int
@ -746,7 +740,7 @@ append(File *f, Cmd *cp, long p)
if(cp->u.text->n > 0) if(cp->u.text->n > 0)
eloginsert(f, p, cp->u.text->r, cp->u.text->n); eloginsert(f, p, cp->u.text->r, cp->u.text->n);
f->curtext->q0 = p; f->curtext->q0 = p;
f->curtext->q1 = p+cp->u.text->n; f->curtext->q1 = p;
return TRUE; return TRUE;
} }
@ -1307,8 +1301,10 @@ cmdname(File *f, String *str, int set)
runemove(r, s, n); runemove(r, s, n);
}else{ }else{
newname = dirname(f->curtext, runestrdup(s), n); newname = dirname(f->curtext, runestrdup(s), n);
r = newname.r;
n = newname.nr; n = newname.nr;
r = runemalloc(n+1);
runemove(r, newname.r, n);
free(newname.r);
} }
fc.f = f; fc.f = f;
fc.r = r; fc.r = r;

View file

@ -218,7 +218,7 @@ elogapply(File *f)
Buflog b; Buflog b;
Rune *buf; Rune *buf;
uint i, n, up, mod; uint i, n, up, mod;
uint q0, q1, tq0, tq1; uint tq0, tq1;
Buffer *log; Buffer *log;
Text *t; Text *t;
@ -230,14 +230,14 @@ elogapply(File *f)
mod = FALSE; mod = FALSE;
/* /*
* The edit commands have already updated the selection in t->q0, t->q1. * The edit commands have already updated the selection in t->q0, t->q1,
* (At least, they are supposed to have updated them. * but using coordinates relative to the unmodified buffer. As we apply the log,
* We still keep finding commands that don't do it right.) * we have to update the coordinates to be relative to the modified buffer.
* The textinsert and textdelete calls below will update it again, so save the * Textinsert and textdelete will do this for us; our only work is to apply the
* current setting and restore it at the end. * convention that an insertion at t->q0==t->q1 is intended to select the
* inserted text.
*/ */
q0 = t->q0;
q1 = t->q1;
/* /*
* We constrain the addresses in here (with textconstrain()) because * We constrain the addresses in here (with textconstrain()) because
* overlapping changes will generate bogus addresses. We will warn * overlapping changes will generate bogus addresses. We will warn
@ -256,8 +256,8 @@ elogapply(File *f)
case Replace: case Replace:
if(tracelog) if(tracelog)
warning(nil, "elog replace %d %d\n", warning(nil, "elog replace %d %d (%d %d)\n",
b.q0, b.q0+b.nd); b.q0, b.q0+b.nd, t->q0, t->q1);
if(!mod){ if(!mod){
mod = TRUE; mod = TRUE;
filemark(f); filemark(f);
@ -272,12 +272,14 @@ elogapply(File *f)
bufread(log, up+i, buf, n); bufread(log, up+i, buf, n);
textinsert(t, tq0+i, buf, n, TRUE); textinsert(t, tq0+i, buf, n, TRUE);
} }
if(t->q0 == b.q0 && t->q1 == b.q0)
t->q1 += b.nr;
break; break;
case Delete: case Delete:
if(tracelog) if(tracelog)
warning(nil, "elog delete %d %d\n", warning(nil, "elog delete %d %d (%d %d)\n",
b.q0, b.q0+b.nd); b.q0, b.q0+b.nd, t->q0, t->q1);
if(!mod){ if(!mod){
mod = TRUE; mod = TRUE;
filemark(f); filemark(f);
@ -288,8 +290,8 @@ elogapply(File *f)
case Insert: case Insert:
if(tracelog) if(tracelog)
warning(nil, "elog insert %d %d\n", warning(nil, "elog insert %d %d (%d %d)\n",
b.q0, b.q0+b.nr); b.q0, b.q0+b.nr, t->q0, t->q1);
if(!mod){ if(!mod){
mod = TRUE; mod = TRUE;
filemark(f); filemark(f);
@ -303,6 +305,8 @@ elogapply(File *f)
bufread(log, up+i, buf, n); bufread(log, up+i, buf, n);
textinsert(t, tq0+i, buf, n, TRUE); textinsert(t, tq0+i, buf, n, TRUE);
} }
if(t->q0 == b.q0 && t->q1 == b.q0)
t->q1 += b.nr;
break; break;
/* case Filename: /* case Filename:
@ -323,28 +327,16 @@ elogapply(File *f)
bufdelete(log, up, log->nc); bufdelete(log, up, log->nc);
} }
fbuffree(buf); fbuffree(buf);
if(warned){
/*
* Changes were out of order, so the q0 and q1
* computed while generating those changes are not
* to be trusted.
*/
q1 = min(q1, f->b.nc);
q0 = min(q0, q1);
}
elogterm(f); elogterm(f);
/* /*
* The q0 and q1 are supposed to be fine (see comment * Bad addresses will cause bufload to crash, so double check.
* above, where we saved them), but bad addresses * If changes were out of order, we expect problems so don't complain further.
* will cause bufload to crash, so double check.
*/ */
if(q0 > f->b.nc || q1 > f->b.nc || q0 > q1){ if(t->q0 > f->b.nc || t->q1 > f->b.nc || t->q0 > t->q1){
warning(nil, "elogapply: can't happen %d %d %d\n", q0, q1, f->b.nc); if(!warned)
q1 = min(q1, f->b.nc); warning(nil, "elogapply: can't happen %d %d %d\n", t->q0, t->q1, f->b.nc);
q0 = min(q0, q1); t->q1 = min(t->q1, f->b.nc);
t->q0 = min(t->q0, t->q1);
} }
t->q0 = q0;
t->q1 = q1;
} }