git: 2a777f20309f - stable/14 - ota: Merge One True Awk 20250116 bsd-feature 2dce54b053d4

From: Warner Losh <imp_at_FreeBSD.org>
Date: Thu, 06 Feb 2025 15:11:12 UTC
The branch stable/14 has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=2a777f20309f4b4361efefdd4071f2a895d884de

commit 2a777f20309f4b4361efefdd4071f2a895d884de
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2025-02-05 16:26:01 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2025-02-06 15:10:46 +0000

    ota:  Merge One True Awk 20250116 bsd-feature 2dce54b053d4
    
    Jan 14, 2025
            Fix incorrect error line number issues. unput has
            no business managing lineno. Thanks to Ozan Yigit.
    
    Jan 05, 2025
            Fix hex detection in is_valid_number.
            Fix indirect field specification with non-numeric string
            eg. $("foo") in indirect. This is not illegal.
            Thanks to Arnold Robbins.
    
    Jan 01, 2025
            Fixed openfile to not try to read from a directory.
            Thanks to Arnold Robbins.
    
    Sponsored by:           Netflix
    
    (cherry picked from commit dd78d987cb38ef162d40aad86229f1dc19884f78)
---
 contrib/one-true-awk/FIXES            | 14 ++++++++++++++
 contrib/one-true-awk/lex.c            |  7 -------
 contrib/one-true-awk/lib.c            |  2 +-
 contrib/one-true-awk/main.c           |  2 +-
 contrib/one-true-awk/run.c            | 15 ++++++++++-----
 contrib/one-true-awk/testdir/T.errmsg |  3 ---
 contrib/one-true-awk/testdir/T.misc   |  8 +++++++-
 7 files changed, 33 insertions(+), 18 deletions(-)

diff --git a/contrib/one-true-awk/FIXES b/contrib/one-true-awk/FIXES
index ad8bce2645fd..b3bf38f0aa1c 100644
--- a/contrib/one-true-awk/FIXES
+++ b/contrib/one-true-awk/FIXES
@@ -25,6 +25,20 @@ THIS SOFTWARE.
 This file lists all bug fixes, changes, etc., made since the 
 second edition of the AWK book was published in September 2023.
 
+Jan 14, 2025
+	Fix incorrect error line number issues. unput has
+	no business managing lineno. Thanks to Ozan Yigit.
+
+Jan 05, 2025
+	Fix hex detection in is_valid_number.
+	Fix indirect field specification with non-numeric string
+	eg. $("foo") in indirect. This is not illegal.
+	Thanks to Arnold Robbins.
+
+Jan 01, 2025
+	Fixed openfile to not try to read from a directory.
+	Thanks to Arnold Robbins.
+
 Jul 28, 2024
 	Fixed readcsvrec resize segfault when reading csv records longer
 	than 8k. Thanks to Ozan Yigit.
diff --git a/contrib/one-true-awk/lex.c b/contrib/one-true-awk/lex.c
index c135db4dfb67..c97c16ea6567 100644
--- a/contrib/one-true-awk/lex.c
+++ b/contrib/one-true-awk/lex.c
@@ -225,11 +225,6 @@ int yylex(void)
 			while ((c = input()) != '\n' && c != 0)
 				;
 			unput(c);
-			/*
-			 * Next line is a hack, it compensates for
-			 * unput's treatment of \n.
-			 */
-			lineno++;
 			break;
 		case ';':
 			RET(';');
@@ -629,8 +624,6 @@ int input(void)	/* get next lexical input character */
 
 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;
diff --git a/contrib/one-true-awk/lib.c b/contrib/one-true-awk/lib.c
index c2ed4f2607ac..27ebca8e7601 100644
--- a/contrib/one-true-awk/lib.c
+++ b/contrib/one-true-awk/lib.c
@@ -897,7 +897,7 @@ bool is_valid_number(const char *s, bool trailing_stuff_ok,
  */
 #if 0
 	/* no hex floating point, sorry */
-	if (s[0] == '0' && tolower(s[1]) == 'x')
+	if (s[0] == '0' && tolower(s[1]) == 'x' && isxdigit(s[2]))
 		return false;
 #endif
 
diff --git a/contrib/one-true-awk/main.c b/contrib/one-true-awk/main.c
index 7d3ef84a580f..361c23e70861 100644
--- a/contrib/one-true-awk/main.c
+++ b/contrib/one-true-awk/main.c
@@ -22,7 +22,7 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 THIS SOFTWARE.
 ****************************************************************/
 
-const char	*version = "version 20240728";
+const char	*version = "version 20250116";
 
 #define DEBUG
 #include <stdio.h>
diff --git a/contrib/one-true-awk/run.c b/contrib/one-true-awk/run.c
index 286a601f3311..eaddfdecbdd3 100644
--- a/contrib/one-true-awk/run.c
+++ b/contrib/one-true-awk/run.c
@@ -35,6 +35,7 @@ THIS SOFTWARE.
 #include <stdlib.h>
 #include <time.h>
 #include <sys/types.h>
+#include <sys/stat.h>
 #include <sys/wait.h>
 #include "awk.h"
 #include "awkgram.tab.h"
@@ -957,16 +958,12 @@ Cell *indirect(Node **a, int n)	/* $( a[0] ) */
 	Awkfloat val;
 	Cell *x;
 	int m;
-	char *s;
 
 	x = execute(a[0]);
 	val = getfval(x);	/* freebsd: defend against super large field numbers */
 	if ((Awkfloat)INT_MAX < val)
 		FATAL("trying to access out of range field %s", x->nval);
 	m = (int) val;
-	if (m == 0 && !is_number(s = getsval(x), NULL))	/* suspicion! */
-		FATAL("illegal field $(%s), name \"%s\"", s, x->nval);
-		/* BUG: can x->nval ever be null??? */
 	tempfree(x);
 	x = fieldadr(m);
 	x->ctype = OCELL;	/* BUG?  why are these needed? */
@@ -2373,9 +2370,11 @@ FILE *openfile(int a, const char *us, bool *pnewflag)
 	size_t i;
 	int m;
 	FILE *fp = NULL;
+	struct stat sbuf;
 
 	if (*s == '\0')
 		FATAL("null file name in print or getline");
+
 	for (i = 0; i < nfiles; i++)
 		if (files[i].fname && strcmp(s, files[i].fname) == 0 &&
 		    (a == files[i].mode || (a==APPEND && files[i].mode==GT) ||
@@ -2386,7 +2385,6 @@ FILE *openfile(int a, const char *us, bool *pnewflag)
 		}
 	if (a == FFLUSH)	/* didn't find it, so don't create it! */
 		return NULL;
-
 	for (i = 0; i < nfiles; i++)
 		if (files[i].fp == NULL)
 			break;
@@ -2400,7 +2398,14 @@ FILE *openfile(int a, const char *us, bool *pnewflag)
 		nfiles = nnf;
 		files = nf;
 	}
+
 	fflush(stdout);	/* force a semblance of order */
+
+	/* don't try to read or write a directory */
+	if (a == LT || a == GT || a == APPEND)
+		if (stat(s, &sbuf) == 0 && S_ISDIR(sbuf.st_mode))
+				return NULL;
+
 	m = a;
 	if (a == GT) {
 		fp = fopen(s, "w");
diff --git a/contrib/one-true-awk/testdir/T.errmsg b/contrib/one-true-awk/testdir/T.errmsg
index ee2450acd1f5..6609223df3f7 100755
--- a/contrib/one-true-awk/testdir/T.errmsg
+++ b/contrib/one-true-awk/testdir/T.errmsg
@@ -100,9 +100,6 @@ non-terminated string
 { print "abc
 }
 
-illegal field $(foo)
-BEGIN { print $"foo" }
-
 next is illegal inside a function
 BEGIN { f() }
 function f() { next }
diff --git a/contrib/one-true-awk/testdir/T.misc b/contrib/one-true-awk/testdir/T.misc
index b8ed3c1c45f9..b233d167789e 100755
--- a/contrib/one-true-awk/testdir/T.misc
+++ b/contrib/one-true-awk/testdir/T.misc
@@ -415,8 +415,14 @@ $awk 'BEGIN \
 		print "hello, world"
 	}
 }}}' >foo1 2>foo2
-grep 'source line 4' foo2 >/dev/null 2>&1 || echo 'BAD: T.misc continuation line number'
+grep 'source line 5' foo2 >/dev/null 2>&1 || echo 'BAD: T.misc continuation line number'
 
+$awk 'BEGIN {
+	if () {
+		print "foo"
+	}
+}' >foo1 2>foo2
+grep 'syntax error at source line 2' foo2 >/dev/null 2>&1 || echo 'BAD: T.misc syntax error line number'
 
 echo 111 222 333 >foo
 $awk '{ f[1]=1; f[2]=2; print $f[1], $f[1]++, $f[2], f[1], f[2] }' foo >foo2