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:
parent
8ea0b3bb2f
commit
d8f32e7287
@ -190,9 +190,8 @@ padvance(const char **path, const char *name)
|
|||||||
for (p = start; *p && *p != ':' && *p != '%'; p++)
|
for (p = start; *p && *p != ':' && *p != '%'; p++)
|
||||||
; /* nothing */
|
; /* nothing */
|
||||||
len = p - start + strlen(name) + 2; /* "2" is for '/' and '\0' */
|
len = p - start + strlen(name) + 2; /* "2" is for '/' and '\0' */
|
||||||
while (stackblocksize() < len)
|
STARTSTACKSTR(q);
|
||||||
growstackblock();
|
CHECKSTRSPACE(len, q);
|
||||||
q = stackblock();
|
|
||||||
if (p != start) {
|
if (p != start) {
|
||||||
memcpy(q, start, p - start);
|
memcpy(q, start, p - start);
|
||||||
q += p - start;
|
q += p - start;
|
||||||
|
@ -502,13 +502,14 @@ expbackq(union node *cmd, int quoted, int flag)
|
|||||||
if (lastc == '\n') {
|
if (lastc == '\n') {
|
||||||
nnl++;
|
nnl++;
|
||||||
} else {
|
} else {
|
||||||
|
CHECKSTRSPACE(nnl + 2, dest);
|
||||||
while (nnl > 0) {
|
while (nnl > 0) {
|
||||||
nnl--;
|
nnl--;
|
||||||
STPUTC('\n', dest);
|
USTPUTC('\n', dest);
|
||||||
}
|
}
|
||||||
if (quotes && syntax[(int)lastc] == CCTL)
|
if (quotes && syntax[(int)lastc] == CCTL)
|
||||||
STPUTC(CTLESC, dest);
|
USTPUTC(CTLESC, dest);
|
||||||
STPUTC(lastc, dest);
|
USTPUTC(lastc, dest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -218,8 +218,8 @@ popstackmark(struct stackmark *mark)
|
|||||||
* part of the block that has been used.
|
* part of the block that has been used.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
static void
|
||||||
growstackblock(void)
|
growstackblock(int min)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
int newlen;
|
int newlen;
|
||||||
@ -229,8 +229,15 @@ growstackblock(void)
|
|||||||
struct stack_block *oldstackp;
|
struct stack_block *oldstackp;
|
||||||
struct stackmark *xmark;
|
struct stackmark *xmark;
|
||||||
|
|
||||||
newlen = (stacknleft == 0) ? MINSIZE : stacknleft * 2 + 100;
|
if (min < stacknleft)
|
||||||
newlen = ALIGN(newlen);
|
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;
|
oldspace = stacknxt;
|
||||||
oldlen = stacknleft;
|
oldlen = stacknleft;
|
||||||
|
|
||||||
@ -257,6 +264,7 @@ growstackblock(void)
|
|||||||
}
|
}
|
||||||
INTON;
|
INTON;
|
||||||
} else {
|
} else {
|
||||||
|
newlen -= ALIGN(sizeof(struct stack_block));
|
||||||
p = stalloc(newlen);
|
p = stalloc(newlen);
|
||||||
if (oldlen != 0)
|
if (oldlen != 0)
|
||||||
memcpy(p, oldspace, oldlen);
|
memcpy(p, oldspace, oldlen);
|
||||||
@ -295,9 +303,9 @@ grabstackblock(int len)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
growstrstackblock(int n)
|
growstrstackblock(int n, int min)
|
||||||
{
|
{
|
||||||
growstackblock();
|
growstackblock(min);
|
||||||
sstrnleft = stackblocksize() - n;
|
sstrnleft = stackblocksize() - n;
|
||||||
return stackblock() + n;
|
return stackblock() + n;
|
||||||
}
|
}
|
||||||
@ -308,7 +316,7 @@ growstackstr(void)
|
|||||||
int len;
|
int len;
|
||||||
|
|
||||||
len = stackblocksize();
|
len = stackblocksize();
|
||||||
return growstrstackblock(len);
|
return (growstrstackblock(len, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -317,12 +325,12 @@ growstackstr(void)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
char *
|
char *
|
||||||
makestrspace(void)
|
makestrspace(int min)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
len = stackblocksize() - sstrnleft;
|
len = stackblocksize() - sstrnleft;
|
||||||
return growstrstackblock(len);
|
return (growstrstackblock(len, min));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -339,11 +347,10 @@ ungrabstackstr(char *s, char *p)
|
|||||||
char *
|
char *
|
||||||
stputbin(const char *data, int len, char *p)
|
stputbin(const char *data, int len, char *p)
|
||||||
{
|
{
|
||||||
int i;
|
CHECKSTRSPACE(len, p);
|
||||||
|
memcpy(p, data, len);
|
||||||
for (i = 0; i < len; i++)
|
sstrnleft -= len;
|
||||||
STPUTC(data[i], p);
|
return (p + len);
|
||||||
return (p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
|
@ -55,10 +55,9 @@ pointer stalloc(int);
|
|||||||
void stunalloc(pointer);
|
void stunalloc(pointer);
|
||||||
void setstackmark(struct stackmark *);
|
void setstackmark(struct stackmark *);
|
||||||
void popstackmark(struct stackmark *);
|
void popstackmark(struct stackmark *);
|
||||||
void growstackblock(void);
|
|
||||||
void grabstackblock(int);
|
void grabstackblock(int);
|
||||||
char *growstackstr(void);
|
char *growstackstr(void);
|
||||||
char *makestrspace(void);
|
char *makestrspace(int);
|
||||||
void ungrabstackstr(char *, char *);
|
void ungrabstackstr(char *, char *);
|
||||||
char *stputbin(const char *data, int len, char *p);
|
char *stputbin(const char *data, int len, char *p);
|
||||||
char *stputs(const char *data, char *p);
|
char *stputs(const char *data, char *p);
|
||||||
@ -69,7 +68,7 @@ char *stputs(const char *data, char *p);
|
|||||||
#define stackblocksize() stacknleft
|
#define stackblocksize() stacknleft
|
||||||
#define STARTSTACKSTR(p) p = stackblock(), sstrnleft = stackblocksize()
|
#define STARTSTACKSTR(p) p = stackblock(), sstrnleft = stackblocksize()
|
||||||
#define STPUTC(c, p) (--sstrnleft >= 0? (*p++ = (c)) : (p = growstackstr(), --sstrnleft, *p++ = (c)))
|
#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))
|
#define USTPUTC(c, p) (--sstrnleft, *p++ = (c))
|
||||||
/*
|
/*
|
||||||
* STACKSTRNUL's use is where we want to be able to turn a stack
|
* STACKSTRNUL's use is where we want to be able to turn a stack
|
||||||
|
@ -1093,9 +1093,8 @@ done:
|
|||||||
popfile();
|
popfile();
|
||||||
tokpushback = 0;
|
tokpushback = 0;
|
||||||
}
|
}
|
||||||
while (stackblocksize() <= savelen)
|
|
||||||
growstackblock();
|
|
||||||
STARTSTACKSTR(out);
|
STARTSTACKSTR(out);
|
||||||
|
CHECKSTRSPACE(savelen + 1, out);
|
||||||
INTOFF;
|
INTOFF;
|
||||||
if (str) {
|
if (str) {
|
||||||
memcpy(out, str, savelen);
|
memcpy(out, str, savelen);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user