Snap for 8730993 from 990cac9c8728bc00e0b8676c5579f37876c0dee1 to mainline-tzdata3-release

Change-Id: Ibbb3d214027218d640805b2ebddc0237070d9713
diff --git a/FIXES b/FIXES
index 8e49fe9..516458e 100644
--- a/FIXES
+++ b/FIXES
@@ -25,38 +25,6 @@
 This file lists all bug fixes, changes, etc., made since the AWK book
 was sent to the printers in August, 1987.
 
-December 8, 2021:
-	The error handling in closefile and closeall was mangled. Long
-	standing warnings had been made fatal and some fatal errors went
-	undetected. Thanks to Miguel Pineiro Jr. <mpj@pineiro.cc>.
-
-Nov 03, 2021:
-        getline accesses uninitialized data after getrec()
-	returns 0 on EOF and leaves the contents of buf unchanged.
-	Thanks to Volodymyr Gubarkov, and Todd C Miller.
-
-Oct 12, 2021:
-	The fix for #83 changed the code to insert 2 chars, but the
-	call to adjbuf just above it only allows for 1 char. This can
-	cause a heap buffer overflow.
-
-July 27, 2021:
-	As per IEEE Std 1003.1-2008, -F "str" is now consistent with
-	-v FS="str" when str is null. Thanks to Warner Losh.
-
-July 24, 2021:
-	Fix readrec's definition of a record. This fixes an issue
-	with NetBSD's RS regular expression support that can cause
-	an infinite read loop. Thanks to Miguel Pineiro Jr.
-
-	Fix regular expression RS ^-anchoring. RS ^-anchoring needs to
-	know if it is reading the first record of a file. This change
-	restores a missing line that was overlooked when porting NetBSD's
-	RS regex functionality. Thanks to Miguel Pineiro Jr.
-
-	Fix size computation in replace_repeat() for special case
-	REPEAT_WITH_Q. Thanks to Todd C. Miller.
-
 February 15, 2021:
 	Small fix so that awk will compile again with g++. Thanks to
 	Arnold Robbins.
diff --git a/METADATA b/METADATA
index 052f466..49d2ed8 100644
--- a/METADATA
+++ b/METADATA
@@ -5,11 +5,11 @@
     type: GIT
     value: "https://github.com/onetrueawk/awk.git"
   }
-  version: "075624a72ab15649f255a3a1dabfd7cb7766a7d7"
+  version: "c0f4e97e4561ff42544e92512bbaf3d7d1f6a671"
   license_type: NOTICE
   last_upgrade_date {
-    year: 2022
-    month: 3
-    day: 7
+    year: 2021
+    month: 4
+    day: 1
   }
 }
diff --git a/README.md b/README.md
index d9cd62c..b8089b3 100644
--- a/README.md
+++ b/README.md
@@ -35,7 +35,7 @@
 distribute `FIXES` with it.
 
 If you find errors, please report them
-to the current maintainer, ozan.yigit@gmail.com.
+to bwk@cs.princeton.edu.
 Please _also_ open an issue in the GitHub issue tracker, to make
 it easy to track issues.
 Thanks.
@@ -90,7 +90,7 @@
 If your system does not have `yacc` or `bison` (the GNU
 equivalent), you need to install one of them first.
 
-NOTE: This version uses ISO/IEC C99, as you should also.  We have
+NOTE: This version uses ANSI C (C 99), as you should also.  We have
 compiled this without any changes using `gcc -Wall` and/or local C
 compilers on a variety of systems, but new systems or compilers
 may raise some new complaint; reports of difficulties are
@@ -107,18 +107,13 @@
 More generally, turning on optimization can significantly improve
 `awk`'s speed, perhaps by 1/3 for highest levels.
 
-## A Note About Releases
-
-We don't usually do releases. 
-
 ## A Note About Maintenance
 
-NOTICE! Maintenance of this program is on a ''best effort''
+NOTICE! Maintenance of this program is on a ``best effort''
 basis.  We try to get to issues and pull requests as quickly
 as we can.  Unfortunately, however, keeping this program going
 is not at the top of our priority list.
 
 #### Last Updated
 
-Sun 23 Jan 2022 03:48:01 PM EST
-
+Fri Dec 25 16:53:34 EST 2020
diff --git a/b.c b/b.c
index 6fb7343..f889ee5 100644
--- a/b.c
+++ b/b.c
@@ -935,7 +935,7 @@
 	if (special_case == REPEAT_PLUS_APPENDED) {
 		size++;		/* for the final + */
 	} else if (special_case == REPEAT_WITH_Q) {
-		size += init_q + (atomlen+1)* (n_q_reps-init_q);
+		size += init_q + (atomlen+1)* n_q_reps;
 	} else if (special_case == REPEAT_ZERO) {
 		size += 2;	/* just a null ERE: () */
 	}
@@ -964,8 +964,11 @@
 		}
 	}
 	memcpy(&buf[j], reptok+reptoklen, suffix_length);
-	j += suffix_length;
-	buf[j] = '\0';
+	if (special_case == REPEAT_ZERO) {
+		buf[j+suffix_length] = '\0';
+	} else {
+		buf[size] = '\0';
+	}
 	/* free old basestr */
 	if (firstbasestr != basestr) {
 		if (basestr)
@@ -1101,7 +1104,7 @@
 					 * program to track each string's length.
 					 */
 					for (i = 1; i <= UCHAR_MAX; i++) {
-						if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, "relex2"))
+						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)) {
 							/* escape backslash */
diff --git a/bugs-fixed/getline-corruption.awk b/bugs-fixed/getline-corruption.awk
deleted file mode 100644
index 461e551..0000000
--- a/bugs-fixed/getline-corruption.awk
+++ /dev/null
@@ -1,5 +0,0 @@
-BEGIN { 
-	getline l
-	getline l
-	print (s=substr(l,1,10)) " len=" length(s)
-}
diff --git a/bugs-fixed/getline-corruption.in b/bugs-fixed/getline-corruption.in
deleted file mode 100644
index 7898192..0000000
--- a/bugs-fixed/getline-corruption.in
+++ /dev/null
@@ -1 +0,0 @@
-a
diff --git a/bugs-fixed/getline-corruption.ok b/bugs-fixed/getline-corruption.ok
deleted file mode 100644
index 3efb545..0000000
--- a/bugs-fixed/getline-corruption.ok
+++ /dev/null
@@ -1 +0,0 @@
-a len=1
diff --git a/lib.c b/lib.c
index c7709f7..18adbd2 100644
--- a/lib.c
+++ b/lib.c
@@ -176,7 +176,6 @@
 				infile = stdin;
 			else if ((infile = fopen(file, "r")) == NULL)
 				FATAL("can't open file %s", file);
-			innew = true;
 			setfval(fnrloc, 0.0);
 		}
 		c = readrec(&buf, &bufsize, infile, innew);
@@ -242,7 +241,6 @@
 		}
 		if (found)
 			setptr(patbeg, '\0');
-		isrec = (found == 0 && *buf == '\0') ? false : true;
 	} else {
 		if ((sep = *rs) == 0) {
 			sep = '\n';
@@ -272,10 +270,10 @@
 		if (!adjbuf(&buf, &bufsize, 1+rr-buf, recsize, &rr, "readrec 3"))
 			FATAL("input record `%.30s...' too long", buf);
 		*rr = 0;
-		isrec = (c == EOF && rr == buf) ? false : true;
 	}
 	*pbuf = buf;
 	*pbufsize = bufsize;
+	isrec = *buf || !feof(inf);
 	DPRINTF("readrec saw <%s>, returns %d\n", buf, isrec);
 	return isrec;
 }
diff --git a/main.c b/main.c
index 986f1a3..f393634 100644
--- a/main.c
+++ b/main.c
@@ -22,7 +22,7 @@
 THIS SOFTWARE.
 ****************************************************************/
 
-const char	*version = "version 20211208";
+const char	*version = "version 20210215";
 
 #define DEBUG
 #include <stdio.h>
@@ -91,7 +91,9 @@
 	/* wart: t=>\t */
 	if (p[0] == 't' && p[1] == '\0')
 		return "\t";
-	return p;
+	else if (p[0] != '\0')
+		return p;
+	return NULL;
 }
 
 static char *
@@ -167,6 +169,8 @@
  			break;
 		case 'F':	/* set field separator */
 			fs = setfs(getarg(&argc, &argv, "no field separator"));
+			if (fs == NULL)
+				WARNING("field separator FS is empty");
 			break;
 		case 'v':	/* -v a=1 to be done NOW.  one -v for each */
 			vn = getarg(&argc, &argv, "no variable name");
diff --git a/run.c b/run.c
index f5c19a1..da4f555 100644
--- a/run.c
+++ b/run.c
@@ -447,15 +447,13 @@
 			n = getrec(&record, &recsize, true);
 		else {			/* getline var */
 			n = getrec(&buf, &bufsize, false);
-			if (n > 0) {
-				x = execute(a[0]);
-				setsval(x, buf);
-				if (is_number(x->sval, & result)) {
-					x->fval = result;
-					x->tval |= NUM;
-				}
-				tempfree(x);
+			x = execute(a[0]);
+			setsval(x, buf);
+			if (is_number(x->sval, & result)) {
+				x->fval = result;
+				x->tval |= NUM;
 			}
+			tempfree(x);
 		}
 	}
 	setfval(r, (Awkfloat) n);
@@ -1860,8 +1858,8 @@
 	return "???";
 }
 
-Cell *closefile(Node **a, int n)
-{
+ Cell *closefile(Node **a, int n)
+ {
  	Cell *x;
 	size_t i;
 	bool stat;
@@ -1872,15 +1870,8 @@
  	for (i = 0; i < nfiles; i++) {
 		if (!files[i].fname || strcmp(x->sval, files[i].fname) != 0)
 			continue;
-		if (files[i].mode == GT || files[i].mode == '|')
-			fflush(files[i].fp);
-		if (ferror(files[i].fp)) {
-			if ((files[i].mode == GT && files[i].fp != stderr)
-			  || files[i].mode == '|')
-				FATAL("write error on %s", files[i].fname);
-			else
-				WARNING("i/o error occurred on %s", files[i].fname);
-		}
+		if (ferror(files[i].fp))
+			FATAL("i/o error occurred on %s", files[i].fname);
 		if (files[i].fp == stdin || files[i].fp == stdout ||
 		    files[i].fp == stderr)
 			stat = freopen("/dev/null", "r+", files[i].fp) == NULL;
@@ -1889,7 +1880,7 @@
 		else
 			stat = fclose(files[i].fp) == EOF;
 		if (stat)
-			WARNING("i/o error occurred closing %s", files[i].fname);
+			FATAL("i/o error occurred closing %s", files[i].fname);
 		if (i > 2)	/* don't do /dev/std... */
 			xfree(files[i].fname);
 		files[i].fname = NULL;	/* watch out for ref thru this */
@@ -1900,7 +1891,7 @@
  	x = gettemp();
 	setfval(x, (Awkfloat) (stat ? -1 : 0));
  	return(x);
-}
+ }
 
 void closeall(void)
 {
@@ -1910,24 +1901,18 @@
 	for (i = 0; i < nfiles; i++) {
 		if (! files[i].fp)
 			continue;
-		if (files[i].mode == GT || files[i].mode == '|')
-			fflush(files[i].fp);
-		if (ferror(files[i].fp)) {
-			if ((files[i].mode == GT && files[i].fp != stderr)
-			  || files[i].mode == '|')
-				FATAL("write error on %s", files[i].fname);
-			else
-				WARNING("i/o error occurred on %s", files[i].fname);
-		}
-		if (files[i].fp == stdin || files[i].fp == stdout ||
-		    files[i].fp == stderr)
+		if (ferror(files[i].fp))
+			FATAL( "i/o error occurred on %s", files[i].fname );
+		if (files[i].fp == stdin)
 			continue;
 		if (files[i].mode == '|' || files[i].mode == LE)
 			stat = pclose(files[i].fp) == -1;
+		else if (files[i].fp == stdout || files[i].fp == stderr)
+			stat = fflush(files[i].fp) == EOF;
 		else
 			stat = fclose(files[i].fp) == EOF;
 		if (stat)
-			WARNING("i/o error occurred while closing %s", files[i].fname);
+			FATAL( "i/o error occurred while closing %s", files[i].fname );
 	}
 }
 
diff --git a/testdir/T.misc b/testdir/T.misc
index ad34ab8..dff57db 100755
--- a/testdir/T.misc
+++ b/testdir/T.misc
Binary files differ