diff options
author | Warner Losh <imp@FreeBSD.org> | 2019-06-02 04:23:56 +0000 |
---|---|---|
committer | Warner Losh <imp@FreeBSD.org> | 2019-06-02 04:23:56 +0000 |
commit | 03ee4d05f1d963d60451e04ce505e4da116300db (patch) | |
tree | 9dcabc6cffafcb6b8195148feb519d575b0bf6ac /bugs-fixed | |
parent | 3a4488f93f2dc8fe9de757a418b74aa0aa4f9ed1 (diff) |
Notes
Diffstat (limited to 'bugs-fixed')
54 files changed, 334 insertions, 0 deletions
diff --git a/bugs-fixed/README b/bugs-fixed/README new file mode 100644 index 000000000000..2f27c1039873 --- /dev/null +++ b/bugs-fixed/README @@ -0,0 +1,57 @@ +List of bugs fixed. + +1. ofs-rebuild: OFS value used to rebuild the record was incorrect. +Fixed August 19, 2014. Revised fix August 2018. + +2. system-status: Instead of a floating-point division by 256, use +the wait(2) macros to create a reasonable exit status. Fixed March 12, 2016. + +3. space: Use provided xisblank() function instead of ispace() for +matching [[:blank:]]. + +4. a-format: Add POSIX standard %a and %A to supported formats. Check +at runtime that this format is available. + +5. decr-NF: Decrementing NF did not change $0. This is a decades-old +bug. There are interactions with the old and new value of OFS as well. +Most of the fix came from the NetBSD awk. + +6. string-conv: String conversions of scalars were sticky. Once a +conversion to string happened, even with OFMT, that value was used until +a new numeric value was assigned, even if OFMT differed from CONVFMT, +and also if CONVFMT changed. + +7. unary-plus: Unary plus on a string constant returned the string. +Instead, it should convert the value to numeric and give that value. + +8. concat-assign-same: Concatenation previously evaluated both sides of the +expression before doing its work, which, since assign() evaluates to the cell +being assigned to, meant that expressions like "print (a = 1) (a = 2)" would +print "22" rather than "12". + +9. missing-precision: When using the format string "%*s", the precision +argument was used without checking if it was present first. + +10. missing-precision: When using the format string "%*s", the precision +argument was used without checking if it was present first. + +11. fmt-overflow: The buffer used for OFMT/CONVFMT conversions was written +to with sprintf(), which meant that some conversions could write past the +end. + +12. numeric-subsep, numeric-fs, numeric-output-seps, numerics-rs: If SUBSEP, +FS, RS, OFS, or ORS were set to a numeric value, then their string values +wouldn't always be generated before being needed. + +13. subsep-overflow: The length of SUBSEP needs to be rechecked after +calling execute(), in case SUBSEP itself has been changed. + +14. split-fs-from-array: If the third argument to split() comes from the +array passed as the second argument, then split() would previously read +from the freed memory and possibly produce incorrect results (depending +on the system's malloc()/free() behaviour.) + +15. getline-numeric: The `getline xx < file' syntax did not check if +values were numeric, in discordance from POSIX. Test case adapted from +one posted by Ben Bacarisse <ben.usenet@bsb.me.uk> in comp.lang.awk, +January 2019. diff --git a/bugs-fixed/a-format.awk b/bugs-fixed/a-format.awk new file mode 100644 index 000000000000..5b7929ee3eea --- /dev/null +++ b/bugs-fixed/a-format.awk @@ -0,0 +1,3 @@ +BEGIN { + printf("%a\n", 42) +} diff --git a/bugs-fixed/a-format.bad b/bugs-fixed/a-format.bad new file mode 100644 index 000000000000..1281825b1111 --- /dev/null +++ b/bugs-fixed/a-format.bad @@ -0,0 +1,3 @@ +nawk: weird printf conversion %a + source line number 2 +%a42 diff --git a/bugs-fixed/a-format.ok b/bugs-fixed/a-format.ok new file mode 100644 index 000000000000..e421e2d01ba6 --- /dev/null +++ b/bugs-fixed/a-format.ok @@ -0,0 +1 @@ +0x1.5p+5 diff --git a/bugs-fixed/concat-assign-same.awk b/bugs-fixed/concat-assign-same.awk new file mode 100644 index 000000000000..ed19f35ca835 --- /dev/null +++ b/bugs-fixed/concat-assign-same.awk @@ -0,0 +1,4 @@ +BEGIN { + print (a = 1) (a = 2) (a = 3) (a = 4) (a = 5); + print (a = 1), (a = 2), (a = 3), (a = 4), (a = 5); +} diff --git a/bugs-fixed/concat-assign-same.bad b/bugs-fixed/concat-assign-same.bad new file mode 100644 index 000000000000..294725b28a97 --- /dev/null +++ b/bugs-fixed/concat-assign-same.bad @@ -0,0 +1,2 @@ +22345 +1 2 3 4 5 diff --git a/bugs-fixed/concat-assign-same.ok b/bugs-fixed/concat-assign-same.ok new file mode 100644 index 000000000000..447505259d02 --- /dev/null +++ b/bugs-fixed/concat-assign-same.ok @@ -0,0 +1,2 @@ +12345 +1 2 3 4 5 diff --git a/bugs-fixed/decr-NF.awk b/bugs-fixed/decr-NF.awk new file mode 100644 index 000000000000..7474991d196e --- /dev/null +++ b/bugs-fixed/decr-NF.awk @@ -0,0 +1,11 @@ +BEGIN { + $0 = "a b c d e f" + print NF + OFS = ":" + NF-- + print $0 + print NF + NF++ + print $0 + print NF +} diff --git a/bugs-fixed/decr-NF.bad b/bugs-fixed/decr-NF.bad new file mode 100644 index 000000000000..b634e065954c --- /dev/null +++ b/bugs-fixed/decr-NF.bad @@ -0,0 +1,5 @@ +6 +a b c d e f +5 +a b c d e f +6 diff --git a/bugs-fixed/decr-NF.ok b/bugs-fixed/decr-NF.ok new file mode 100644 index 000000000000..3359cf2312d1 --- /dev/null +++ b/bugs-fixed/decr-NF.ok @@ -0,0 +1,5 @@ +6 +a:b:c:d:e +5 +a:b:c:d:e: +6 diff --git a/bugs-fixed/fmt-overflow.awk b/bugs-fixed/fmt-overflow.awk new file mode 100644 index 000000000000..bf5877e4abac --- /dev/null +++ b/bugs-fixed/fmt-overflow.awk @@ -0,0 +1 @@ +BEGIN { OFMT = "%.1000f"; print 1.25; } diff --git a/bugs-fixed/fmt-overflow.ok b/bugs-fixed/fmt-overflow.ok new file mode 100644 index 000000000000..5f7449e68073 --- /dev/null +++ b/bugs-fixed/fmt-overflow.ok @@ -0,0 +1 @@ +1.2500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 diff --git a/bugs-fixed/fs-overflow.awk b/bugs-fixed/fs-overflow.awk new file mode 100644 index 000000000000..be10f5a46f0d --- /dev/null +++ b/bugs-fixed/fs-overflow.awk @@ -0,0 +1,13 @@ +function foo() { + a = ""; + for (i = 0; i < 10000; i++) { + a = a "c"; + } + return a; +} + +BEGIN { + FS = foo(); + $0="foo"; + print $1; +} diff --git a/bugs-fixed/getline-numeric.awk b/bugs-fixed/getline-numeric.awk new file mode 100644 index 000000000000..5571a9589a3d --- /dev/null +++ b/bugs-fixed/getline-numeric.awk @@ -0,0 +1,6 @@ +{ + print $0, ($0 <= 50 ? "<=" : ">"), 50 + getline dd < ARGV[1] + print dd, (dd <= 50 ? "<=" : ">"), 50 + if (dd == $0) print "same" +} diff --git a/bugs-fixed/getline-numeric.bad b/bugs-fixed/getline-numeric.bad new file mode 100644 index 000000000000..d911c774fa9a --- /dev/null +++ b/bugs-fixed/getline-numeric.bad @@ -0,0 +1,3 @@ +120 > 50 +120 <= 50 +same diff --git a/bugs-fixed/getline-numeric.in b/bugs-fixed/getline-numeric.in new file mode 100644 index 000000000000..52bd8e43afb0 --- /dev/null +++ b/bugs-fixed/getline-numeric.in @@ -0,0 +1 @@ +120 diff --git a/bugs-fixed/getline-numeric.ok b/bugs-fixed/getline-numeric.ok new file mode 100644 index 000000000000..f7efd3db506f --- /dev/null +++ b/bugs-fixed/getline-numeric.ok @@ -0,0 +1,3 @@ +120 > 50 +120 > 50 +same diff --git a/bugs-fixed/missing-precision.awk b/bugs-fixed/missing-precision.awk new file mode 100644 index 000000000000..4e7a74b2c964 --- /dev/null +++ b/bugs-fixed/missing-precision.awk @@ -0,0 +1 @@ +BEGIN { printf("%*s"); } diff --git a/bugs-fixed/missing-precision.ok b/bugs-fixed/missing-precision.ok new file mode 100644 index 000000000000..608b4fa48666 --- /dev/null +++ b/bugs-fixed/missing-precision.ok @@ -0,0 +1,2 @@ +./a.out: not enough args in printf(%*s) + source line number 1 diff --git a/bugs-fixed/negative-nf.awk b/bugs-fixed/negative-nf.awk new file mode 100644 index 000000000000..6caeee4602b5 --- /dev/null +++ b/bugs-fixed/negative-nf.awk @@ -0,0 +1 @@ +BEGIN { NF = -5; } diff --git a/bugs-fixed/negative-nf.ok b/bugs-fixed/negative-nf.ok new file mode 100644 index 000000000000..71c860468cc0 --- /dev/null +++ b/bugs-fixed/negative-nf.ok @@ -0,0 +1,2 @@ +./a.out: cannot set NF to a negative value + source line number 1 diff --git a/bugs-fixed/nf-self-assign.awk b/bugs-fixed/nf-self-assign.awk new file mode 100644 index 000000000000..6ae29eef916d --- /dev/null +++ b/bugs-fixed/nf-self-assign.awk @@ -0,0 +1,6 @@ +BEGIN { + $0="a b c"; + OFS=","; + NF = NF; + print; +} diff --git a/bugs-fixed/nf-self-assign.bad b/bugs-fixed/nf-self-assign.bad new file mode 100644 index 000000000000..3774da60e546 --- /dev/null +++ b/bugs-fixed/nf-self-assign.bad @@ -0,0 +1 @@ +a b c diff --git a/bugs-fixed/nf-self-assign.ok b/bugs-fixed/nf-self-assign.ok new file mode 100644 index 000000000000..b2ffb02521e6 --- /dev/null +++ b/bugs-fixed/nf-self-assign.ok @@ -0,0 +1 @@ +a,b,c diff --git a/bugs-fixed/numeric-fs.awk b/bugs-fixed/numeric-fs.awk new file mode 100644 index 000000000000..01e438d4aa28 --- /dev/null +++ b/bugs-fixed/numeric-fs.awk @@ -0,0 +1,5 @@ +BEGIN { + FS = 0; split("20202", a); print a[1]; + FS = 1; $0="31313"; print $1; + FS = 2; "echo 42424" | getline; print $1; +} diff --git a/bugs-fixed/numeric-fs.ok b/bugs-fixed/numeric-fs.ok new file mode 100644 index 000000000000..dcf37cd5e262 --- /dev/null +++ b/bugs-fixed/numeric-fs.ok @@ -0,0 +1,3 @@ +2 +3 +4 diff --git a/bugs-fixed/numeric-output-seps.awk b/bugs-fixed/numeric-output-seps.awk new file mode 100644 index 000000000000..daa0f72aa6ff --- /dev/null +++ b/bugs-fixed/numeric-output-seps.awk @@ -0,0 +1,8 @@ +BEGIN { + $0 = "a b c"; + OFS = 1; + ORS = 2; + NF = 2; + print; + print "d", "e"; +} diff --git a/bugs-fixed/numeric-output-seps.bad b/bugs-fixed/numeric-output-seps.bad new file mode 100644 index 000000000000..95310f78a7f3 --- /dev/null +++ b/bugs-fixed/numeric-output-seps.bad @@ -0,0 +1,2 @@ +a b +d e diff --git a/bugs-fixed/numeric-output-seps.ok b/bugs-fixed/numeric-output-seps.ok new file mode 100644 index 000000000000..de6b2026e539 --- /dev/null +++ b/bugs-fixed/numeric-output-seps.ok @@ -0,0 +1 @@ +a1b2d1e2
\ No newline at end of file diff --git a/bugs-fixed/numeric-rs.awk b/bugs-fixed/numeric-rs.awk new file mode 100644 index 000000000000..cc7a0a0c08c2 --- /dev/null +++ b/bugs-fixed/numeric-rs.awk @@ -0,0 +1,6 @@ +BEGIN { + RS = 1; + while ("echo a1b1c1d" | getline > 0) { + print $1; + } +} diff --git a/bugs-fixed/numeric-rs.bad b/bugs-fixed/numeric-rs.bad new file mode 100644 index 000000000000..2027bc6f27c9 --- /dev/null +++ b/bugs-fixed/numeric-rs.bad @@ -0,0 +1 @@ +a1b1c1d diff --git a/bugs-fixed/numeric-rs.ok b/bugs-fixed/numeric-rs.ok new file mode 100644 index 000000000000..d68dd4031d2a --- /dev/null +++ b/bugs-fixed/numeric-rs.ok @@ -0,0 +1,4 @@ +a +b +c +d diff --git a/bugs-fixed/numeric-subsep.awk b/bugs-fixed/numeric-subsep.awk new file mode 100644 index 000000000000..1252e4a99607 --- /dev/null +++ b/bugs-fixed/numeric-subsep.awk @@ -0,0 +1,5 @@ +BEGIN { + SUBSEP = 123.456; + a["hello", "world"] = "foo"; + print a["hello" SUBSEP "world"]; +} diff --git a/bugs-fixed/numeric-subsep.bad b/bugs-fixed/numeric-subsep.bad new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/bugs-fixed/numeric-subsep.bad @@ -0,0 +1 @@ + diff --git a/bugs-fixed/numeric-subsep.ok b/bugs-fixed/numeric-subsep.ok new file mode 100644 index 000000000000..257cc5642cb1 --- /dev/null +++ b/bugs-fixed/numeric-subsep.ok @@ -0,0 +1 @@ +foo diff --git a/bugs-fixed/ofs-rebuild.awk b/bugs-fixed/ofs-rebuild.awk new file mode 100644 index 000000000000..dd2700031524 --- /dev/null +++ b/bugs-fixed/ofs-rebuild.awk @@ -0,0 +1,17 @@ +# The bug here is that nawk should use the value of OFS that +# was current when $0 became invalid to rebuild the record. + +BEGIN { + OFS = ":" + $0 = "a b c d e f g" + $3 = "3333" + # Conceptually, $0 should now be "a:b:3333:d:e:f:g" + + # Change OFS after (conceptually) rebuilding the record + OFS = "<>" + + # Unmodifed nawk prints "a<>b<>3333<>d<>e<>f<>g" because + # it delays rebuilding $0 until it's needed, and then it uses + # the current value of OFS. Oops. + print +} diff --git a/bugs-fixed/ofs-rebuild.bad b/bugs-fixed/ofs-rebuild.bad new file mode 100644 index 000000000000..7570811e2c16 --- /dev/null +++ b/bugs-fixed/ofs-rebuild.bad @@ -0,0 +1 @@ +a<>b<>3333<>d<>e<>f<>g diff --git a/bugs-fixed/ofs-rebuild.ok b/bugs-fixed/ofs-rebuild.ok new file mode 100644 index 000000000000..26892181f91b --- /dev/null +++ b/bugs-fixed/ofs-rebuild.ok @@ -0,0 +1 @@ +a:b:3333:d:e:f:g diff --git a/bugs-fixed/space.awk b/bugs-fixed/space.awk new file mode 100644 index 000000000000..6aa87d2e6259 --- /dev/null +++ b/bugs-fixed/space.awk @@ -0,0 +1,22 @@ +BEGIN { + c[" "] = "\" \"" + c["\a"] = "\\a" + c["\b"] = "\\b" + c["\f"] = "\\f" + c["\n"] = "\\n" + c["\r"] = "\\r" + c["\t"] = "\\t" + c["\v"] = "\\v" + + sort = "LC_ALL=C sort" + + for (i in c) + printf("%s %s [[:space:]]\n", c[i], + i ~ /[[:space:]]/ ? "~" : "!~") | sort + + for (i in c) + printf("%s %s [[:blank:]]\n", c[i], + i ~ /[[:blank:]]/ ? "~" : "!~") | sort + + close(sort) +} diff --git a/bugs-fixed/space.bad b/bugs-fixed/space.bad new file mode 100644 index 000000000000..f92055fd0c26 --- /dev/null +++ b/bugs-fixed/space.bad @@ -0,0 +1,16 @@ +" " ~ [[:blank:]] +" " ~ [[:space:]] +\a !~ [[:blank:]] +\a !~ [[:space:]] +\b !~ [[:blank:]] +\b !~ [[:space:]] +\f ~ [[:blank:]] +\f ~ [[:space:]] +\n ~ [[:blank:]] +\n ~ [[:space:]] +\r ~ [[:blank:]] +\r ~ [[:space:]] +\t ~ [[:blank:]] +\t ~ [[:space:]] +\v ~ [[:blank:]] +\v ~ [[:space:]] diff --git a/bugs-fixed/space.ok b/bugs-fixed/space.ok new file mode 100644 index 000000000000..4278c5c9df3b --- /dev/null +++ b/bugs-fixed/space.ok @@ -0,0 +1,16 @@ +" " ~ [[:blank:]] +" " ~ [[:space:]] +\a !~ [[:blank:]] +\a !~ [[:space:]] +\b !~ [[:blank:]] +\b !~ [[:space:]] +\f !~ [[:blank:]] +\f ~ [[:space:]] +\n !~ [[:blank:]] +\n ~ [[:space:]] +\r !~ [[:blank:]] +\r ~ [[:space:]] +\t ~ [[:blank:]] +\t ~ [[:space:]] +\v !~ [[:blank:]] +\v ~ [[:space:]] diff --git a/bugs-fixed/split-fs-from-array.awk b/bugs-fixed/split-fs-from-array.awk new file mode 100644 index 000000000000..fce1607c2a97 --- /dev/null +++ b/bugs-fixed/split-fs-from-array.awk @@ -0,0 +1,5 @@ +BEGIN { + a[1] = "elephantie" + a[2] = "e" + print split(a[1],a,a[2]), a[2], a[3], split(a[2],a,a[2]) +} diff --git a/bugs-fixed/split-fs-from-array.ok b/bugs-fixed/split-fs-from-array.ok new file mode 100644 index 000000000000..9402b94f4fae --- /dev/null +++ b/bugs-fixed/split-fs-from-array.ok @@ -0,0 +1 @@ +4 l phanti 2 diff --git a/bugs-fixed/string-conv.awk b/bugs-fixed/string-conv.awk new file mode 100644 index 000000000000..a1f04aba354b --- /dev/null +++ b/bugs-fixed/string-conv.awk @@ -0,0 +1,13 @@ +BEGIN { + OFMT = ">>%.6g<<" + a = 12.1234 + print "a =", a + b = a "" + print "1 ->", b + CONVFMT = "%2.2f" + b = a "" + print "2 ->", b + CONVFMT = "%.12g" + b = a "" + print "3 ->", b +} diff --git a/bugs-fixed/string-conv.bad b/bugs-fixed/string-conv.bad new file mode 100644 index 000000000000..2ab95e87d0a8 --- /dev/null +++ b/bugs-fixed/string-conv.bad @@ -0,0 +1,4 @@ +a = >>12.1234<< +1 -> >>12.1234<< +2 -> >>12.1234<< +3 -> >>12.1234<< diff --git a/bugs-fixed/string-conv.ok b/bugs-fixed/string-conv.ok new file mode 100644 index 000000000000..7c097113207a --- /dev/null +++ b/bugs-fixed/string-conv.ok @@ -0,0 +1,4 @@ +a = >>12.1234<< +1 -> 12.1234 +2 -> 12.12 +3 -> 12.1234 diff --git a/bugs-fixed/subsep-overflow.awk b/bugs-fixed/subsep-overflow.awk new file mode 100644 index 000000000000..66c7c24db0e6 --- /dev/null +++ b/bugs-fixed/subsep-overflow.awk @@ -0,0 +1,24 @@ +function foo(c, n) { + s = ""; + for (i = 0; i < n; i++) { + s = s c; + } + return s; +} + +BEGIN { + str1 = foo("a", 4500); + str2 = foo("b", 9000); + + a[(SUBSEP = str1), (SUBSEP = str2), "c"] = 1; + + for (k in a) { + print length(k); + } + + print (((SUBSEP = str1), (SUBSEP = str2), "c") in a); + print (((SUBSEP = str1) SUBSEP (SUBSEP = str2) SUBSEP "c") in a); + delete a[(SUBSEP = str1), (SUBSEP = str2), "c"]; + print (((SUBSEP = str1), (SUBSEP = str2), "c") in a); + print (((SUBSEP = str1) SUBSEP (SUBSEP = str2) SUBSEP "c") in a); +} diff --git a/bugs-fixed/subsep-overflow.ok b/bugs-fixed/subsep-overflow.ok new file mode 100644 index 000000000000..ddbbd78707ee --- /dev/null +++ b/bugs-fixed/subsep-overflow.ok @@ -0,0 +1,5 @@ +27001 +1 +1 +0 +0 diff --git a/bugs-fixed/system-status.awk b/bugs-fixed/system-status.awk new file mode 100644 index 000000000000..8daf563e6f4f --- /dev/null +++ b/bugs-fixed/system-status.awk @@ -0,0 +1,19 @@ +# Unmodified nawk prints the 16 bit exit status divided by 256, but +# does so using floating point arithmetic, yielding strange results. +# +# The fix is to use the various macros defined for wait(2) and to +# use the signal number + 256 for death by signal, or signal number + 512 +# for death by signal with core dump. + +BEGIN { + status = system("exit 42") + print "normal status", status + + status = system("kill -HUP $$") + print "death by signal status", status + + status = system("kill -ABRT $$") + print "death by signal with core dump status", status + + system("rm -f core*") +} diff --git a/bugs-fixed/system-status.bad b/bugs-fixed/system-status.bad new file mode 100644 index 000000000000..a1317dba54a8 --- /dev/null +++ b/bugs-fixed/system-status.bad @@ -0,0 +1,3 @@ +normal status 42 +death by signal status 0.00390625 +death by signal with core dump status 0.523438 diff --git a/bugs-fixed/system-status.ok b/bugs-fixed/system-status.ok new file mode 100644 index 000000000000..737828f5ed7a --- /dev/null +++ b/bugs-fixed/system-status.ok @@ -0,0 +1,3 @@ +normal status 42 +death by signal status 257 +death by signal with core dump status 518 diff --git a/bugs-fixed/unary-plus.awk b/bugs-fixed/unary-plus.awk new file mode 100644 index 000000000000..ba6185b96704 --- /dev/null +++ b/bugs-fixed/unary-plus.awk @@ -0,0 +1,4 @@ +BEGIN { + print +"q" + print +"43.12345678912345678" +} diff --git a/bugs-fixed/unary-plus.bad b/bugs-fixed/unary-plus.bad new file mode 100644 index 000000000000..76f57d5d580c --- /dev/null +++ b/bugs-fixed/unary-plus.bad @@ -0,0 +1,2 @@ +q +43.12345678912345678 diff --git a/bugs-fixed/unary-plus.ok b/bugs-fixed/unary-plus.ok new file mode 100644 index 000000000000..90f97afc5c44 --- /dev/null +++ b/bugs-fixed/unary-plus.ok @@ -0,0 +1,2 @@ +0 +43.1235 |