From e32b2740f7b6846335741577412cc3ae492633c8 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 5 Feb 2025 09:19:45 -0700 Subject: [PATCH] awk: Update to 20250116 bsd-feature 2dce54b053d4 Update to 20250116 upstream. This fixes issues with bad line numbers, hex numbers, an indirection in variable dereferencing and prevent openfile from reading directories. 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 --- FIXES | 14 ++++++++++++++ lex.c | 7 ------- lib.c | 2 +- main.c | 2 +- run.c | 15 ++++++++++----- testdir/T.errmsg | 3 --- testdir/T.misc | 8 +++++++- 7 files changed, 33 insertions(+), 18 deletions(-) diff --git a/FIXES b/FIXES index ad8bce2645f..b3bf38f0aa1 100644 --- a/FIXES +++ b/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/lex.c b/lex.c index c135db4dfb6..c97c16ea656 100644 --- a/lex.c +++ b/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/lib.c b/lib.c index a2731d63d12..486d7da3c38 100644 --- a/lib.c +++ b/lib.c @@ -889,7 +889,7 @@ bool is_valid_number(const char *s, bool trailing_stuff_ok, s++; /* 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; /* allow +nan, -nan, +inf, -inf, any other letter, no */ diff --git a/main.c b/main.c index 7d3ef84a580..361c23e7086 100644 --- a/main.c +++ b/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 diff --git a/run.c b/run.c index 286a601f331..eaddfdecbdd 100644 --- a/run.c +++ b/run.c @@ -35,6 +35,7 @@ THIS SOFTWARE. #include #include #include +#include #include #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/testdir/T.errmsg b/testdir/T.errmsg index ee2450acd1f..6609223df3f 100755 --- a/testdir/T.errmsg +++ b/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/testdir/T.misc b/testdir/T.misc index b8ed3c1c45f..b233d167789 100755 --- a/testdir/T.misc +++ b/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