Snap for 8270536 from 900b24f7a45b3996b5a154a77fa6dfc680e3aa8c to tm-release

Change-Id: I29ce86c1991a16b217dba39b4189ad300e74f1f3
diff --git a/FIXES b/FIXES
index 8a2befc..8e49fe9 100644
--- a/FIXES
+++ b/FIXES
@@ -25,6 +25,21 @@
 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.
diff --git a/METADATA b/METADATA
index 631fe7b..052f466 100644
--- a/METADATA
+++ b/METADATA
@@ -5,11 +5,11 @@
     type: GIT
     value: "https://github.com/onetrueawk/awk.git"
   }
-  version: "f9affa922c5e074990a999d486d4bc823590fd93"
+  version: "075624a72ab15649f255a3a1dabfd7cb7766a7d7"
   license_type: NOTICE
   last_upgrade_date {
-    year: 2021
-    month: 8
-    day: 10
+    year: 2022
+    month: 3
+    day: 7
   }
 }
diff --git a/README.md b/README.md
index 76ae3d4..d9cd62c 100644
--- a/README.md
+++ b/README.md
@@ -35,7 +35,7 @@
 distribute `FIXES` with it.
 
 If you find errors, please report them
-to bwk@cs.princeton.edu.
+to the current maintainer, ozan.yigit@gmail.com.
 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 ANSI C (C 99), as you should also.  We have
+NOTE: This version uses ISO/IEC C99, 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
@@ -109,7 +109,7 @@
 
 ## A Note About Releases
 
-We don't do releases. 
+We don't usually do releases. 
 
 ## A Note About Maintenance
 
@@ -120,4 +120,5 @@
 
 #### Last Updated
 
-Sat Jul 25 14:00:07 EDT 2021
+Sun 23 Jan 2022 03:48:01 PM EST
+
diff --git a/b.c b/b.c
index 8042366..6fb7343 100644
--- a/b.c
+++ b/b.c
@@ -1101,7 +1101,7 @@
 					 * program to track each string's length.
 					 */
 					for (i = 1; i <= UCHAR_MAX; i++) {
-						if (!adjbuf((char **) &buf, &bufsz, bp-buf+1, 100, (char **) &bp, "relex2"))
+						if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 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
new file mode 100644
index 0000000..461e551
--- /dev/null
+++ b/bugs-fixed/getline-corruption.awk
@@ -0,0 +1,5 @@
+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
new file mode 100644
index 0000000..7898192
--- /dev/null
+++ b/bugs-fixed/getline-corruption.in
@@ -0,0 +1 @@
+a
diff --git a/bugs-fixed/getline-corruption.ok b/bugs-fixed/getline-corruption.ok
new file mode 100644
index 0000000..3efb545
--- /dev/null
+++ b/bugs-fixed/getline-corruption.ok
@@ -0,0 +1 @@
+a len=1
diff --git a/main.c b/main.c
index 1e1385e..986f1a3 100644
--- a/main.c
+++ b/main.c
@@ -22,7 +22,7 @@
 THIS SOFTWARE.
 ****************************************************************/
 
-const char	*version = "version 20210724";
+const char	*version = "version 20211208";
 
 #define DEBUG
 #include <stdio.h>
diff --git a/run.c b/run.c
index da4f555..f5c19a1 100644
--- a/run.c
+++ b/run.c
@@ -447,13 +447,15 @@
 			n = getrec(&record, &recsize, true);
 		else {			/* getline var */
 			n = getrec(&buf, &bufsize, false);
-			x = execute(a[0]);
-			setsval(x, buf);
-			if (is_number(x->sval, & result)) {
-				x->fval = result;
-				x->tval |= NUM;
+			if (n > 0) {
+				x = execute(a[0]);
+				setsval(x, buf);
+				if (is_number(x->sval, & result)) {
+					x->fval = result;
+					x->tval |= NUM;
+				}
+				tempfree(x);
 			}
-			tempfree(x);
 		}
 	}
 	setfval(r, (Awkfloat) n);
@@ -1858,8 +1860,8 @@
 	return "???";
 }
 
- Cell *closefile(Node **a, int n)
- {
+Cell *closefile(Node **a, int n)
+{
  	Cell *x;
 	size_t i;
 	bool stat;
@@ -1870,8 +1872,15 @@
  	for (i = 0; i < nfiles; i++) {
 		if (!files[i].fname || strcmp(x->sval, files[i].fname) != 0)
 			continue;
-		if (ferror(files[i].fp))
-			FATAL("i/o error occurred on %s", files[i].fname);
+		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)
 			stat = freopen("/dev/null", "r+", files[i].fp) == NULL;
@@ -1880,7 +1889,7 @@
 		else
 			stat = fclose(files[i].fp) == EOF;
 		if (stat)
-			FATAL("i/o error occurred closing %s", files[i].fname);
+			WARNING("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 */
@@ -1891,7 +1900,7 @@
  	x = gettemp();
 	setfval(x, (Awkfloat) (stat ? -1 : 0));
  	return(x);
- }
+}
 
 void closeall(void)
 {
@@ -1901,18 +1910,24 @@
 	for (i = 0; i < nfiles; i++) {
 		if (! files[i].fp)
 			continue;
-		if (ferror(files[i].fp))
-			FATAL( "i/o error occurred on %s", files[i].fname );
-		if (files[i].fp == stdin)
+		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)
 			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)
-			FATAL( "i/o error occurred while closing %s", files[i].fname );
+			WARNING("i/o error occurred while closing %s", files[i].fname);
 	}
 }