shithub: trueawk

Download patch

ref: 1d836ff681967fa858902f2328f2dda83848cc23
parent: 3222d96844719666e9e37630666821c0a06cdc48
parent: f70e36869ea55f9c19d328d4e910fa6a8d77d6da
author: onetrueawk <bwkster@gmail.com>
date: Mon Jan 21 09:17:03 EST 2019

Merge branch 'master' into assign-expr

--- a/b.c
+++ b/b.c
@@ -823,7 +823,15 @@
 				if (cc->cc_name != NULL && prestr[1 + cc->cc_namelen] == ':' &&
 				    prestr[2 + cc->cc_namelen] == ']') {
 					prestr += cc->cc_namelen + 3;
-					for (i = 0; i < NCHARS; i++) {
+					/*
+					 * BUG: We begin at 1, instead of 0, since we
+					 * would otherwise prematurely terminate the
+					 * string for classes like [[:cntrl:]]. This
+					 * means that we can't match the NUL character,
+					 * not without first adapting the entire
+					 * program to track each string's length.
+					 */
+					for (i = 1; i < NCHARS; i++) {
 						if (!adjbuf((char **) &buf, &bufsz, bp-buf+1, 100, (char **) &bp, "relex2"))
 						    FATAL("out of space for reg expr %.10s...", lastre);
 						if (cc->cc_func(i)) {
--- a/bugs-fixed/README
+++ b/bugs-fixed/README
@@ -30,4 +30,12 @@
 print "22" rather than "12".
 
 9. missing-precision: When using the format string "%*s", the precision
-argument was used without checking if it was present first.
\ No newline at end of file
+argument was used without checking if it was present first.
+
+10. missing-precision: When using the format string "%*s", the precision
+argument was used without checking if it was present first.
+
+11. fmt-overflow: The buffer used for OFMT/CONVFMT conversions was written
+to with sprintf(), which meant that some conversions could write past the
+end.
+
--- /dev/null
+++ b/bugs-fixed/fmt-overflow.awk
@@ -1,0 +1,1 @@
+BEGIN { OFMT = "%.1000f"; print 1.25; }
--- /dev/null
+++ b/bugs-fixed/fmt-overflow.ok
@@ -1,0 +1,1 @@
+1.2500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
--- a/lex.c
+++ b/lex.c
@@ -198,6 +198,7 @@
 		yylval.i = c;
 		switch (c) {
 		case '\n':	/* {EOL} */
+			lineno++;
 			RET(NL);
 		case '\r':	/* assume \n is coming */
 		case ' ':	/* {WS}+ */
@@ -213,6 +214,7 @@
 		case '\\':
 			if (peek() == '\n') {
 				input();
+				lineno++;
 			} else if (peek() == '\r') {
 				input(); input();	/* \n */
 				lineno++;
@@ -370,10 +372,11 @@
 		case '\n':
 		case '\r':
 		case 0:
+			*bp = '\0';
 			SYNTAX( "non-terminated string %.10s...", buf );
-			lineno++;
 			if (c == 0)	/* hopeless */
 				FATAL( "giving up" );
+			lineno++;
 			break;
 		case '\\':
 			c = input();
@@ -515,6 +518,7 @@
 		if (!adjbuf(&buf, &bufsz, bp-buf+3, 500, &bp, "regexpr"))
 			FATAL("out of space for reg expr %.10s...", buf);
 		if (c == '\n') {
+			*bp = '\0';
 			SYNTAX( "newline in regular expression %.10s...", buf ); 
 			unput('\n');
 			break;
@@ -553,19 +557,19 @@
 			lexprog++;
 	} else				/* awk -f ... */
 		c = pgetc();
-	if (c == '\n')
-		lineno++;
-	else if (c == EOF)
+	if (c == EOF)
 		c = 0;
 	if (ep >= ebuf + sizeof ebuf)
 		ep = ebuf;
-	return *ep++ = c;
+	*ep = c;
+	if (c != 0) {
+		ep++;
+	}
+	return (c);
 }
 
 void unput(int c)	/* put lexical character back on input */
 {
-	if (c == '\n')
-		lineno--;
 	if (yysptr >= yysbuf + sizeof(yysbuf))
 		FATAL("pushed back too much: %.20s...", yysbuf);
 	*yysptr++ = c;
--- a/lib.c
+++ b/lib.c
@@ -59,7 +59,7 @@
 {
 	if ( (record = (char *) malloc(n)) == NULL
 	  || (fields = (char *) malloc(n+1)) == NULL
-	  || (fldtab = (Cell **) malloc((nfields+1) * sizeof(Cell *))) == NULL
+	  || (fldtab = (Cell **) malloc((nfields+2) * sizeof(Cell *))) == NULL
 	  || (fldtab[0] = (Cell *) malloc(sizeof(Cell))) == NULL )
 		FATAL("out of space for $0 and fields");
 	*fldtab[0] = dollar0;
--- a/main.c
+++ b/main.c
@@ -88,7 +88,7 @@
 			exit(0);
 			break;
 		}
-		if (strncmp(argv[1], "--", 2) == 0) {	/* explicit end of args */
+		if (strcmp(argv[1], "--") == 0) {	/* explicit end of args */
 			argc--;
 			argv++;
 			break;
--- a/tran.c
+++ b/tran.c
@@ -395,7 +395,7 @@
 
 static char *get_str_val(Cell *vp, char **fmt)        /* get string val of a Cell */
 {
-	char s[100];	/* BUG: unchecked */
+	char s[256];
 	double dtemp;
 
 	if ((vp->tval & (NUM | STR)) == 0)
@@ -434,9 +434,9 @@
 		if (freeable(vp)) \
 			xfree(vp->sval); \
 		if (modf(vp->fval, &dtemp) == 0)	/* it's integral */ \
-			sprintf(s, "%.30g", vp->fval); \
+			snprintf(s, sizeof (s), "%.30g", vp->fval); \
 		else \
-			sprintf(s, *fmt, vp->fval); \
+			snprintf(s, sizeof (s), *fmt, vp->fval); \
 		vp->sval = tostring(s); \
 		vp->tval &= ~DONTFREE; \
 		vp->tval |= STR; \
--