sh: Remove linked list of stack marks.

The linked list of stack marks may cause problems if the allocation stack is
used between an exception and a higher-level popstackmark(), as it may then
touch a stack mark that is local to a function which has returned.

Also, the adjustment compares to a pointer passed to realloc(), which is
undefined behaviour.

Instead of adjusting stack marks when reallocating stack blocks, ensure that
such an adjustment is never necessary by fixing a small piece of memory in
place at a stack mark. This also simplifies the code.

To avoid the problems reported in bin/175922, it remains necessary to call
setstackmark() after popstackmark() if the stack mark remains in use.
This commit is contained in:
jilles 2013-05-11 20:51:00 +00:00
parent 960e7e9fd4
commit e0dffd814f
2 changed files with 3 additions and 18 deletions

View File

@ -124,7 +124,6 @@ struct stack_block {
#define SPACE(sp) ((char*)(sp) + ALIGN(sizeof(struct stack_block)))
static struct stack_block *stackp;
static struct stackmark *markp;
char *stacknxt;
int stacknleft;
char *sstrend;
@ -186,8 +185,9 @@ setstackmark(struct stackmark *mark)
mark->stackp = stackp;
mark->stacknxt = stacknxt;
mark->stacknleft = stacknleft;
mark->marknext = markp;
markp = mark;
/* Ensure this block stays in place. */
if (stackp != NULL && stacknxt == SPACE(stackp))
stalloc(1);
}
@ -197,7 +197,6 @@ popstackmark(struct stackmark *mark)
struct stack_block *sp;
INTOFF;
markp = mark->marknext;
while (stackp != mark->stackp) {
sp = stackp;
stackp = sp->prev;
@ -229,7 +228,6 @@ growstackblock(int min)
int oldlen;
struct stack_block *sp;
struct stack_block *oldstackp;
struct stackmark *xmark;
if (min < stacknleft)
min = stacknleft;
@ -254,18 +252,6 @@ growstackblock(int min)
stacknxt = SPACE(sp);
stacknleft = newlen - (stacknxt - (char*)sp);
sstrend = stacknxt + stacknleft;
/*
* Stack marks pointing to the start of the old block
* must be relocated to point to the new block
*/
xmark = markp;
while (xmark != NULL && xmark->stackp == oldstackp) {
xmark->stackp = stackp;
xmark->stacknxt = stacknxt;
xmark->stacknleft = stacknleft;
xmark = xmark->marknext;
}
INTON;
} else {
newlen -= ALIGN(sizeof(struct stack_block));

View File

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