From submitter:

growstackblock() sometimes relocates a stack_block considered empty
without properly relocating stack marks referencing that block.
The first call to popstackmark() with the unrelocated stack mark
as argument then causes sh to abort.

Relocating the relevant stack marks seems to solve this problem.

The patch changes the semantics of popstackmark() somewhat.  It can
only be called once after a call to setstackmark(), thus cmdloop() in
main.c needs an extra call to setstackmark().

PR:		bin/19983
Submitted by:	Tor.Egge@fast.no
Reviewed by:	Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
This commit is contained in:
cracauer 2000-08-16 10:39:43 +00:00
parent fd45895ceb
commit 0a28a3436d
3 changed files with 22 additions and 1 deletions

View File

@ -253,12 +253,13 @@ cmdloop(top)
evaltree(n, 0);
}
popstackmark(&smark);
setstackmark(&smark);
if (evalskip == SKIPFILE) {
evalskip = 0;
break;
}
}
popstackmark(&smark); /* unnecessary */
popstackmark(&smark);
}

View File

@ -118,6 +118,7 @@ struct stack_block {
struct stack_block stackbase;
struct stack_block *stackp = &stackbase;
struct stackmark *markp;
char *stacknxt = stackbase.space;
int stacknleft = MINSIZE;
int sstrnleft;
@ -176,6 +177,8 @@ setstackmark(mark)
mark->stackp = stackp;
mark->stacknxt = stacknxt;
mark->stacknleft = stacknleft;
mark->marknext = markp;
markp = mark;
}
@ -186,6 +189,7 @@ popstackmark(mark)
struct stack_block *sp;
INTOFF;
markp = mark->marknext;
while (stackp != mark->stackp) {
sp = stackp;
stackp = sp->prev;
@ -215,6 +219,7 @@ growstackblock()
char *oldspace;
int oldlen;
struct stack_block *sp;
struct stack_block *oldstackp;
newlen = ALIGN(stacknleft * 2 + 100);
oldspace = stacknxt;
@ -222,6 +227,7 @@ growstackblock()
if (stacknxt == stackp->space && stackp != &stackbase) {
INTOFF;
oldstackp = stackp;
sp = stackp;
stackp = sp->prev;
sp = ckrealloc((pointer)sp, sizeof(struct stack_block) -
@ -230,6 +236,19 @@ growstackblock()
stackp = sp;
stacknxt = sp->space;
stacknleft = newlen;
{
/* Stack marks pointing to the start of the old block
* must be relocated to point to the new block
*/
struct stackmark *xmark;
xmark = markp;
while (xmark != NULL && xmark->stackp == oldstackp) {
xmark->stackp = stackp;
xmark->stacknxt = stacknxt;
xmark->stacknleft = stacknleft;
xmark = xmark->marknext;
}
}
INTON;
} else {
p = stalloc(newlen);

View File

@ -41,6 +41,7 @@ struct stackmark {
struct stack_block *stackp;
char *stacknxt;
int stacknleft;
struct stackmark *marknext;
};