diff options
-rw-r--r-- | FIXES | 15 | ||||
-rw-r--r-- | METADATA | 8 | ||||
-rw-r--r-- | README.md | 9 | ||||
-rw-r--r-- | b.c | 2 | ||||
-rw-r--r-- | bugs-fixed/getline-corruption.awk | 5 | ||||
-rw-r--r-- | bugs-fixed/getline-corruption.in | 1 | ||||
-rw-r--r-- | bugs-fixed/getline-corruption.ok | 1 | ||||
-rw-r--r-- | main.c | 2 | ||||
-rw-r--r-- | run.c | 51 |
9 files changed, 66 insertions, 28 deletions
@@ -25,6 +25,21 @@ THIS SOFTWARE. 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. @@ -5,11 +5,11 @@ third_party { 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 } } @@ -35,7 +35,7 @@ in `FIXES`. If you distribute this code further, please please please 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 @@ move this to some place like `/usr/bin/awk`. 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 @@ More generally, turning on optimization can significantly improve ## A Note About Releases -We don't do releases. +We don't usually do releases. ## A Note About Maintenance @@ -120,4 +120,5 @@ is not at the top of our priority list. #### Last Updated -Sat Jul 25 14:00:07 EDT 2021 +Sun 23 Jan 2022 03:48:01 PM EST + @@ -1101,7 +1101,7 @@ rescan: * 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 @@ -22,7 +22,7 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ****************************************************************/ -const char *version = "version 20210724"; +const char *version = "version 20211208"; #define DEBUG #include <stdio.h> @@ -447,13 +447,15 @@ Cell *awkgetline(Node **a, int n) /* get next line from specific input */ 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 @@ const char *filename(FILE *fp) return "???"; } - Cell *closefile(Node **a, int n) - { +Cell *closefile(Node **a, int n) +{ Cell *x; size_t i; bool stat; @@ -1870,8 +1872,15 @@ const char *filename(FILE *fp) 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 @@ const char *filename(FILE *fp) 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 @@ const char *filename(FILE *fp) x = gettemp(); setfval(x, (Awkfloat) (stat ? -1 : 0)); return(x); - } +} void closeall(void) { @@ -1901,18 +1910,24 @@ void closeall(void) 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); } } |