sh: Allow arbitrary large numbers in CHECKSTRSPACE.

Reduce "stack string" API somewhat and simplify code.
Add a check for integer overflow of the "stack string" length (probably
incomplete).
This commit is contained in:
Jilles Tjoelker 2010-12-26 13:25:47 +00:00
parent 8ea0b3bb2f
commit d8f32e7287
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=216706
5 changed files with 30 additions and 25 deletions

View File

@ -190,9 +190,8 @@ padvance(const char **path, const char *name)
for (p = start; *p && *p != ':' && *p != '%'; p++)
; /* nothing */
len = p - start + strlen(name) + 2; /* "2" is for '/' and '\0' */
while (stackblocksize() < len)
growstackblock();
q = stackblock();
STARTSTACKSTR(q);
CHECKSTRSPACE(len, q);
if (p != start) {
memcpy(q, start, p - start);
q += p - start;

View File

@ -502,13 +502,14 @@ expbackq(union node *cmd, int quoted, int flag)
if (lastc == '\n') {
nnl++;
} else {
CHECKSTRSPACE(nnl + 2, dest);
while (nnl > 0) {
nnl--;
STPUTC('\n', dest);
USTPUTC('\n', dest);
}
if (quotes && syntax[(int)lastc] == CCTL)
STPUTC(CTLESC, dest);
STPUTC(lastc, dest);
USTPUTC(CTLESC, dest);
USTPUTC(lastc, dest);
}
}
}

View File

@ -218,8 +218,8 @@ popstackmark(struct stackmark *mark)
* part of the block that has been used.
*/
void
growstackblock(void)
static void
growstackblock(int min)
{
char *p;
int newlen;
@ -229,8 +229,15 @@ growstackblock(void)
struct stack_block *oldstackp;
struct stackmark *xmark;
newlen = (stacknleft == 0) ? MINSIZE : stacknleft * 2 + 100;
newlen = ALIGN(newlen);
if (min < stacknleft)
min = stacknleft;
if (newlen >= INT_MAX / 2 - ALIGN(sizeof(struct stack_block)))
error("Out of space");
min += stacknleft;
min += ALIGN(sizeof(struct stack_block));
newlen = 512;
while (newlen < min)
newlen <<= 1;
oldspace = stacknxt;
oldlen = stacknleft;
@ -257,6 +264,7 @@ growstackblock(void)
}
INTON;
} else {
newlen -= ALIGN(sizeof(struct stack_block));
p = stalloc(newlen);
if (oldlen != 0)
memcpy(p, oldspace, oldlen);
@ -295,9 +303,9 @@ grabstackblock(int len)
*/
static char *
growstrstackblock(int n)
growstrstackblock(int n, int min)
{
growstackblock();
growstackblock(min);
sstrnleft = stackblocksize() - n;
return stackblock() + n;
}
@ -308,7 +316,7 @@ growstackstr(void)
int len;
len = stackblocksize();
return growstrstackblock(len);
return (growstrstackblock(len, 0));
}
@ -317,12 +325,12 @@ growstackstr(void)
*/
char *
makestrspace(void)
makestrspace(int min)
{
int len;
len = stackblocksize() - sstrnleft;
return growstrstackblock(len);
return (growstrstackblock(len, min));
}
@ -339,11 +347,10 @@ ungrabstackstr(char *s, char *p)
char *
stputbin(const char *data, int len, char *p)
{
int i;
for (i = 0; i < len; i++)
STPUTC(data[i], p);
return (p);
CHECKSTRSPACE(len, p);
memcpy(p, data, len);
sstrnleft -= len;
return (p + len);
}
char *

View File

@ -55,10 +55,9 @@ pointer stalloc(int);
void stunalloc(pointer);
void setstackmark(struct stackmark *);
void popstackmark(struct stackmark *);
void growstackblock(void);
void grabstackblock(int);
char *growstackstr(void);
char *makestrspace(void);
char *makestrspace(int);
void ungrabstackstr(char *, char *);
char *stputbin(const char *data, int len, char *p);
char *stputs(const char *data, char *p);
@ -69,7 +68,7 @@ char *stputs(const char *data, char *p);
#define stackblocksize() stacknleft
#define STARTSTACKSTR(p) p = stackblock(), sstrnleft = stackblocksize()
#define STPUTC(c, p) (--sstrnleft >= 0? (*p++ = (c)) : (p = growstackstr(), --sstrnleft, *p++ = (c)))
#define CHECKSTRSPACE(n, p) { if (sstrnleft < n) p = makestrspace(); }
#define CHECKSTRSPACE(n, p) { if (sstrnleft < n) p = makestrspace(n); }
#define USTPUTC(c, p) (--sstrnleft, *p++ = (c))
/*
* STACKSTRNUL's use is where we want to be able to turn a stack

View File

@ -1093,9 +1093,8 @@ parsebackq(char *out, struct nodelist **pbqlist,
popfile();
tokpushback = 0;
}
while (stackblocksize() <= savelen)
growstackblock();
STARTSTACKSTR(out);
CHECKSTRSPACE(savelen + 1, out);
INTOFF;
if (str) {
memcpy(out, str, savelen);