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)
This commit is contained in:
Warner Losh 2025-02-05 09:26:01 -07:00
parent 1dbcd9a15c
commit 2a777f2030
7 changed files with 33 additions and 18 deletions

View file

@ -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.

View file

@ -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;

View file

@ -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

View file

@ -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>

View file

@ -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");

View file

@ -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 }

View file

@ -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