aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 04:47:21 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 04:47:21 +0000
commitdfa7cf6f8d31c1fe8540e27b02fb3bfdb2d2e3d2 (patch)
treeebc9b2c64dfe5484d208a6e807a675ba29cec4d9
parentc2eddb76ee23f2916c08f327adfc6a6c1f45b895 (diff)
parent21572cbc2b9331989f5ee0b859ce47673c5fde5a (diff)
downloadone-true-awk-android14-mainline-conscrypt-release.tar.gz
Snap for 10453563 from 21572cbc2b9331989f5ee0b859ce47673c5fde5a to mainline-conscrypt-releaseaml_con_341614000aml_con_341511080aml_con_341410300aml_con_341310090aml_con_341110000android14-mainline-conscrypt-release
Change-Id: I90299b23279fad766e049cae52e4dc5c292775ce
-rw-r--r--Android.bp1
-rw-r--r--FIXES35
-rw-r--r--METADATA10
-rw-r--r--awk.h2
-rw-r--r--awkgram.y25
-rw-r--r--lex.c35
-rw-r--r--lib.c5
-rw-r--r--main.c2
-rw-r--r--makefile1
-rw-r--r--run.c28
-rwxr-xr-xtestdir/T.argv6
-rw-r--r--tran.c18
12 files changed, 108 insertions, 60 deletions
diff --git a/Android.bp b/Android.bp
index e7d53ac..3f89d6e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -46,7 +46,6 @@ cc_defaults {
// in stdio2.h, and this #defines it in awk.h
"-Wno-macro-redefined",
],
- c_std: "gnu11",
stl: "none",
yacc: {
flags: [
diff --git a/FIXES b/FIXES
index 8e49fe9..53c7841 100644
--- a/FIXES
+++ b/FIXES
@@ -23,7 +23,38 @@ THIS SOFTWARE.
****************************************************************/
This file lists all bug fixes, changes, etc., made since the AWK book
-was sent to the printers in August, 1987.
+was sent to the printers in August 1987.
+
+Dec 15, 2022:
+ Force hex escapes in strings to be no more than two characters,
+ as they already are in regular expressions. This brings internal
+ consistency, as well as consistency with gawk. Thanks to
+ Arnold Robbins.
+
+Sep 12, 2022:
+ adjbuf minlen error (cannot be 0) in cat, resulting in NULL pbuf.
+ discovered by todd miller. also use-after-free issue with
+ tempfree in cat, thanks to Miguel Pineiro Jr and valgrind.
+
+Aug 30, 2022:
+ Various leaks and use-after-free issues plugged/fixed.
+ Thanks to Miguel Pineiro Jr. <mpj@pineiro.cc>.
+
+May 23, 2022:
+ Memory leak when assigning a string to some of the built-in
+ variables. allocated string erroneously marked DONTFREE.
+ Thanks to Miguel Pineiro Jr. <mpj@pineiro.cc>.
+
+Mar 14, 2022:
+ Historic bug: command-line "name=value" assignment had been
+ truncating its entry in ARGV. (circa 1989) Thanks to
+ Miguel Pineiro Jr. <mpj@pineiro.cc>.
+
+Mar 3, 2022:
+ Fixed file management memory leak that appears to have been
+ there since the files array was first initialized with stdin,
+ stdout, and stderr (circa 1992). Thanks to Miguel Pineiro Jr.
+ <mpj@pineiro.cc>.
December 8, 2021:
The error handling in closefile and closeall was mangled. Long
@@ -309,7 +340,7 @@ Mar 3, 2019:
#12: Avoid undefined behaviour when using ctype(3) functions in
relex(). Thanks to GitHub user iamleot.
#31: Make getline handle numeric strings, and update FIXES. Thanks
- to GitHub user arnoldrobbins.
+ to GitHub user Arnold Robbins (arnoldrobbins)
#32: maketab: support build systems with read-only source. Thanks
to GitHub user enh.
diff --git a/METADATA b/METADATA
index 052f466..58b7076 100644
--- a/METADATA
+++ b/METADATA
@@ -1,3 +1,7 @@
+# This project was upgraded with external_updater.
+# Usage: tools/external_updater/updater.sh update one-true-awk
+# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md
+
name: "one-true-awk"
description: "This is the version of awk described in \'The AWK Programming Language\', by Al Aho, Brian Kernighan, and Peter Weinberger (Addison-Wesley, 1988, ISBN 0-201-07981-X)."
third_party {
@@ -5,11 +9,11 @@ third_party {
type: GIT
value: "https://github.com/onetrueawk/awk.git"
}
- version: "075624a72ab15649f255a3a1dabfd7cb7766a7d7"
+ version: "5e49ea4d1f71d9134734011f2151cae4dbec5e5f"
license_type: NOTICE
last_upgrade_date {
year: 2022
- month: 3
- day: 7
+ month: 12
+ day: 16
}
}
diff --git a/awk.h b/awk.h
index cc30249..ccd16c9 100644
--- a/awk.h
+++ b/awk.h
@@ -37,7 +37,7 @@ typedef double Awkfloat;
typedef unsigned char uschar;
-#define xfree(a) { if ((a) != NULL) { free((void *)(intptr_t)(a)); (a) = NULL; } }
+#define xfree(a) { free((void *)(intptr_t)(a)); (a) = NULL; }
/*
* We sometimes cheat writing read-only pointers to NUL-terminate them
* and then put back the original value
diff --git a/awkgram.y b/awkgram.y
index 8fc1709..7b2b397 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -206,9 +206,10 @@ ppattern:
{ $$ = op2(AND, notnull($1), notnull($3)); }
| ppattern MATCHOP reg_expr { $$ = op3($2, NIL, $1, (Node*)makedfa($3, 0)); }
| ppattern MATCHOP ppattern
- { if (constnode($3))
+ { if (constnode($3)) {
$$ = op3($2, NIL, $1, (Node*)makedfa(strnode($3), 0));
- else
+ free($3);
+ } else
$$ = op3($2, (Node *)1, $1, $3); }
| ppattern IN varname { $$ = op2(INTEST, $1, makearr($3)); }
| '(' plist ')' IN varname { $$ = op2(INTEST, $2, makearr($5)); }
@@ -233,9 +234,10 @@ pattern:
| pattern NE pattern { $$ = op2($2, $1, $3); }
| pattern MATCHOP reg_expr { $$ = op3($2, NIL, $1, (Node*)makedfa($3, 0)); }
| pattern MATCHOP pattern
- { if (constnode($3))
+ { if (constnode($3)) {
$$ = op3($2, NIL, $1, (Node*)makedfa(strnode($3), 0));
- else
+ free($3);
+ } else
$$ = op3($2, (Node *)1, $1, $3); }
| pattern IN varname { $$ = op2(INTEST, $1, makearr($3)); }
| '(' plist ')' IN varname { $$ = op2(INTEST, $2, makearr($5)); }
@@ -388,9 +390,10 @@ term:
| MATCHFCN '(' pattern comma reg_expr ')'
{ $$ = op3(MATCHFCN, NIL, $3, (Node*)makedfa($5, 1)); }
| MATCHFCN '(' pattern comma pattern ')'
- { if (constnode($5))
+ { if (constnode($5)) {
$$ = op3(MATCHFCN, NIL, $3, (Node*)makedfa(strnode($5), 1));
- else
+ free($5);
+ } else
$$ = op3(MATCHFCN, (Node *)1, $3, $5); }
| NUMBER { $$ = celltonode($1, CCON); }
| SPLIT '(' pattern comma varname comma pattern ')' /* string */
@@ -404,16 +407,18 @@ term:
| subop '(' reg_expr comma pattern ')'
{ $$ = op4($1, NIL, (Node*)makedfa($3, 1), $5, rectonode()); }
| subop '(' pattern comma pattern ')'
- { if (constnode($3))
+ { if (constnode($3)) {
$$ = op4($1, NIL, (Node*)makedfa(strnode($3), 1), $5, rectonode());
- else
+ free($3);
+ } else
$$ = op4($1, (Node *)1, $3, $5, rectonode()); }
| subop '(' reg_expr comma pattern comma var ')'
{ $$ = op4($1, NIL, (Node*)makedfa($3, 1), $5, $7); }
| subop '(' pattern comma pattern comma var ')'
- { if (constnode($3))
+ { if (constnode($3)) {
$$ = op4($1, NIL, (Node*)makedfa(strnode($3), 1), $5, $7);
- else
+ free($3);
+ } else
$$ = op4($1, (Node *)1, $3, $5, $7); }
| SUBSTR '(' pattern comma pattern comma pattern ')'
{ $$ = op3(SUBSTR, $3, $5, $7); }
diff --git a/lex.c b/lex.c
index 9d1ae06..a5feff4 100644
--- a/lex.c
+++ b/lex.c
@@ -416,19 +416,28 @@ int string(void)
break;
case 'x': /* hex \x0-9a-fA-F + */
- { char xbuf[100], *px;
- for (px = xbuf; (c = input()) != 0 && px-xbuf < 100-2; ) {
- if (isdigit(c)
- || (c >= 'a' && c <= 'f')
- || (c >= 'A' && c <= 'F'))
- *px++ = c;
- else
+ {
+ int i;
+
+ n = 0;
+ for (i = 1; i <= 2; i++) {
+ c = input();
+ if (c == 0)
+ break;
+ if (isxdigit(c)) {
+ c = tolower(c);
+ n *= 16;
+ if (isdigit(c))
+ n += (c - '0');
+ else
+ n += 10 + (c - 'a');
+ } else
break;
}
- *px = 0;
- unput(c);
- sscanf(xbuf, "%x", (unsigned int *) &n);
- *bp++ = n;
+ if (n)
+ *bp++ = n;
+ else
+ unput(c);
break;
}
@@ -525,7 +534,7 @@ int regexpr(void)
char *bp;
if (buf == NULL && (buf = (char *) malloc(bufsz)) == NULL)
- FATAL("out of space for rex expr");
+ FATAL("out of space for reg expr");
bp = buf;
for ( ; (c = input()) != '/' && c != 0; ) {
if (!adjbuf(&buf, &bufsz, bp-buf+3, 500, &bp, "regexpr"))
@@ -545,7 +554,7 @@ int regexpr(void)
*bp = 0;
if (c == 0)
SYNTAX("non-terminated regular expression %.10s...", buf);
- yylval.s = tostring(buf);
+ yylval.s = buf;
unput('/');
RET(REGEXPR);
}
diff --git a/lib.c b/lib.c
index c7709f7..ebe296f 100644
--- a/lib.c
+++ b/lib.c
@@ -297,12 +297,13 @@ char *getargv(int n) /* get ARGV[n] */
void setclvar(char *s) /* set var=value from s */
{
- char *p;
+ char *e, *p;
Cell *q;
double result;
for (p=s; *p != '='; p++)
;
+ e = p;
*p++ = 0;
p = qstring(p, '\0');
q = setsymtab(s, p, 0.0, STR, symtab);
@@ -312,6 +313,8 @@ void setclvar(char *s) /* set var=value from s */
q->tval |= NUM;
}
DPRINTF("command line set %s to |%s|\n", s, p);
+ free(p);
+ *e = '=';
}
diff --git a/main.c b/main.c
index 986f1a3..2ec513c 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 20211208";
+const char *version = "version 20221215";
#define DEBUG
#include <stdio.h>
diff --git a/makefile b/makefile
index 9ceaaad..df966ef 100644
--- a/makefile
+++ b/makefile
@@ -36,6 +36,7 @@ CC = $(HOSTCC) # change this is cross-compiling.
# By fiat, to make our lives easier, yacc is now defined to be bison.
# If you want something else, you're on your own.
+# YACC = yacc -d -b awkgram
YACC = bison -d
OFILES = b.o main.o parse.o proctab.o tran.o lib.o run.o lex.o
diff --git a/run.c b/run.c
index f5c19a1..483b9d9 100644
--- a/run.c
+++ b/run.c
@@ -971,8 +971,10 @@ int format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like co
}
*p = '\0';
free(fmt);
- for ( ; a; a = a->nnext) /* evaluate any remaining args */
- execute(a);
+ for ( ; a; a = a->nnext) { /* evaluate any remaining args */
+ x = execute(a);
+ tempfree(x);
+ }
*pbuf = buf;
*pbufsize = bufsize;
return p - buf;
@@ -1195,16 +1197,17 @@ Cell *cat(Node **a, int q) /* a[0] cat a[1] */
x = execute(a[0]);
n1 = strlen(getsval(x));
- adjbuf(&s, &ssz, n1, recsize, 0, "cat1");
+ adjbuf(&s, &ssz, n1 + 1, recsize, 0, "cat1");
memcpy(s, x->sval, n1);
+ tempfree(x);
+
y = execute(a[1]);
n2 = strlen(getsval(y));
adjbuf(&s, &ssz, n1 + n2 + 1, recsize, 0, "cat2");
memcpy(s + n1, y->sval, n2);
s[n1 + n2] = '\0';
- tempfree(x);
tempfree(y);
z = gettemp();
@@ -1266,6 +1269,7 @@ Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
y = execute(a[0]); /* source string */
origs = s = strdup(getsval(y));
+ tempfree(y);
arg3type = ptoi(a[3]);
if (a[2] == NULL) /* fs string */
fs = getsval(fsloc);
@@ -1386,7 +1390,6 @@ Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
}
}
tempfree(ap);
- tempfree(y);
xfree(origs);
xfree(origfs);
x = gettemp();
@@ -1712,8 +1715,10 @@ Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg lis
setfval(x, u);
if (nextarg != NULL) {
WARNING("warning: function has too many arguments");
- for ( ; nextarg; nextarg = nextarg->nnext)
- execute(nextarg);
+ for ( ; nextarg; nextarg = nextarg->nnext) {
+ y = execute(nextarg);
+ tempfree(y);
+ }
}
return(x);
}
@@ -1780,13 +1785,13 @@ static void stdinit(void) /* in case stdin, etc., are not constants */
if (files == NULL)
FATAL("can't allocate file memory for %zu files", nfiles);
files[0].fp = stdin;
- files[0].fname = "/dev/stdin";
+ files[0].fname = tostring("/dev/stdin");
files[0].mode = LT;
files[1].fp = stdout;
- files[1].fname = "/dev/stdout";
+ files[1].fname = tostring("/dev/stdout");
files[1].mode = GT;
files[2].fp = stderr;
- files[2].fname = "/dev/stderr";
+ files[2].fname = tostring("/dev/stderr");
files[2].mode = GT;
}
@@ -1890,8 +1895,7 @@ Cell *closefile(Node **a, int n)
stat = fclose(files[i].fp) == EOF;
if (stat)
WARNING("i/o error occurred closing %s", files[i].fname);
- if (i > 2) /* don't do /dev/std... */
- xfree(files[i].fname);
+ xfree(files[i].fname);
files[i].fname = NULL; /* watch out for ref thru this */
files[i].fp = NULL;
break;
diff --git a/testdir/T.argv b/testdir/T.argv
index b9a67ef..55e2754 100755
--- a/testdir/T.argv
+++ b/testdir/T.argv
@@ -97,6 +97,12 @@ echo '111
$awk '{print L $0}' L=11 foo0 L=22 foo0 >foo2
diff foo1 foo2 || echo 'BAD: T.argv (L=11 L=22)'
+echo >foo0
+echo 'name=value
+name=value' >foo1
+$awk 'BEGIN { print ARGV[1] } { print ARGV[1] }' name=value foo0 >foo2
+diff foo1 foo2 || echo 'BAD: T.argv assignment operand modified'
+
echo 3.345 >foo1
$awk 'BEGIN { print ARGV[1] + ARGV[2]}' 1 2.345 >foo2
diff foo1 foo2 || echo 'BAD: T.argv (ARGV[1] + ARGV[2])'
diff --git a/tran.c b/tran.c
index c6ae890..e1496cd 100644
--- a/tran.c
+++ b/tran.c
@@ -70,18 +70,6 @@ Cell *literal0;
extern Cell **fldtab;
-static void
-setfree(Cell *vp)
-{
- if (&vp->sval == FS || &vp->sval == RS ||
- &vp->sval == OFS || &vp->sval == ORS ||
- &vp->sval == OFMT || &vp->sval == CONVFMT ||
- &vp->sval == FILENAME || &vp->sval == SUBSEP)
- vp->tval |= DONTFREE;
- else
- vp->tval &= ~DONTFREE;
-}
-
void syminit(void) /* initialize symbol table with builtin vars */
{
literal0 = setsymtab("0", "0", 0.0, NUM|STR|CON|DONTFREE, symtab);
@@ -377,10 +365,9 @@ char *setsval(Cell *vp, const char *s) /* set string val of a Cell */
t = s ? tostring(s) : tostring(""); /* in case it's self-assign */
if (freeable(vp))
xfree(vp->sval);
- vp->tval &= ~(NUM|CONVC|CONVO);
+ vp->tval &= ~(NUM|DONTFREE|CONVC|CONVO);
vp->tval |= STR;
vp->fmt = NULL;
- setfree(vp);
DPRINTF("setsval %p: %s = \"%s (%p) \", t=%o r,f=%d,%d\n",
(void*)vp, NN(vp->nval), t, (void*)t, vp->tval, donerec, donefld);
vp->sval = t;
@@ -576,7 +563,6 @@ Cell *catstr(Cell *a, Cell *b) /* concatenate a and b */
char *qstring(const char *is, int delim) /* collect string up to next delim */
{
- const char *os = is;
int c, n;
const uschar *s = (const uschar *) is;
uschar *buf, *bp;
@@ -585,7 +571,7 @@ char *qstring(const char *is, int delim) /* collect string up to next delim */
FATAL( "out of space in qstring(%s)", s);
for (bp = buf; (c = *s) != delim; s++) {
if (c == '\n')
- SYNTAX( "newline in string %.20s...", os );
+ SYNTAX( "newline in string %.20s...", is );
else if (c != '\\')
*bp++ = c;
else { /* \something */