svn commit: r216706 - head/bin/sh

Jilles Tjoelker jilles at FreeBSD.org
Sun Dec 26 13:25:48 UTC 2010


Author: jilles
Date: Sun Dec 26 13:25:47 2010
New Revision: 216706
URL: http://svn.freebsd.org/changeset/base/216706

Log:
  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).

Modified:
  head/bin/sh/exec.c
  head/bin/sh/expand.c
  head/bin/sh/memalloc.c
  head/bin/sh/memalloc.h
  head/bin/sh/parser.c

Modified: head/bin/sh/exec.c
==============================================================================
--- head/bin/sh/exec.c	Sun Dec 26 13:20:10 2010	(r216705)
+++ head/bin/sh/exec.c	Sun Dec 26 13:25:47 2010	(r216706)
@@ -190,9 +190,8 @@ padvance(const char **path, const char *
 	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;

Modified: head/bin/sh/expand.c
==============================================================================
--- head/bin/sh/expand.c	Sun Dec 26 13:20:10 2010	(r216705)
+++ head/bin/sh/expand.c	Sun Dec 26 13:25:47 2010	(r216706)
@@ -502,13 +502,14 @@ expbackq(union node *cmd, int quoted, in
 			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);
 			}
 		}
 	}

Modified: head/bin/sh/memalloc.c
==============================================================================
--- head/bin/sh/memalloc.c	Sun Dec 26 13:20:10 2010	(r216705)
+++ head/bin/sh/memalloc.c	Sun Dec 26 13:25:47 2010	(r216706)
@@ -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 *

Modified: head/bin/sh/memalloc.h
==============================================================================
--- head/bin/sh/memalloc.h	Sun Dec 26 13:20:10 2010	(r216705)
+++ head/bin/sh/memalloc.h	Sun Dec 26 13:25:47 2010	(r216706)
@@ -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

Modified: head/bin/sh/parser.c
==============================================================================
--- head/bin/sh/parser.c	Sun Dec 26 13:20:10 2010	(r216705)
+++ head/bin/sh/parser.c	Sun Dec 26 13:25:47 2010	(r216706)
@@ -1093,9 +1093,8 @@ done:
                 popfile();
 		tokpushback = 0;
 	}
-	while (stackblocksize() <= savelen)
-		growstackblock();
 	STARTSTACKSTR(out);
+	CHECKSTRSPACE(savelen + 1, out);
 	INTOFF;
 	if (str) {
 		memcpy(out, str, savelen);


More information about the svn-src-all mailing list