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:
parent
960e7e9fd4
commit
e0dffd814f
@ -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));
|
||||
|
@ -39,7 +39,6 @@ struct stackmark {
|
||||
struct stack_block *stackp;
|
||||
char *stacknxt;
|
||||
int stacknleft;
|
||||
struct stackmark *marknext;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user