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
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++) 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;

View File

@ -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);
} }
} }
} }

View File

@ -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 *

View File

@ -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

View File

@ -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);