diff options
-rwxr-xr-x | ChangeLog | 12 | ||||
-rw-r--r-- | awk.h | 8 | ||||
-rw-r--r-- | field.c | 2 | ||||
-rw-r--r-- | interpret.h | 14 | ||||
-rw-r--r-- | re.c | 12 |
5 files changed, 39 insertions, 9 deletions
@@ -1,3 +1,15 @@ +2018-09-26 Arnold D. Robbins <arnold@skeeve.com> + + Add more lint checks. + + * awk.h (POP_ARRAY): Add boolean parameter to check for untyped + value and include lint warning. + * interpret.h (r_interpret): Adjust all calls to POP_ARRAY. + * field.c (do_split): Improve lint warning text for empty + third argument. + * re.c (make_regexp): Add lint check for '\0' in contents of + regexp to be matched (dynamic or otherwise). + 2018-09-23 Steven Packard <spackard1@bloomberg.net> * awk.h: Add `#if !defined(__SUNPRO_C)' around check for non-ANSI @@ -1771,9 +1771,15 @@ extern uintmax_t adjust_uint(uintmax_t n); /* POP_ARRAY --- get the array at the top of the stack */ static inline NODE * -POP_ARRAY() +POP_ARRAY(bool check_for_untyped) { NODE *t = POP(); + static bool warned = false; + + if (do_lint && ! warned && check_for_untyped && t->type == Node_var_new) { + warned = true; + lintwarn(_("behavior of `for' loop on untyped variable is not defined by POSIX")); + } return (t->type == Node_var_array) ? t : force_array(t, true); } @@ -1038,7 +1038,7 @@ do_split(int nargs) if (do_lint && ! warned) { warned = true; - lintwarn(_("split: null string for third arg is a gawk extension")); + lintwarn(_("split: null string for third arg is a non-standard extension")); } } else if (fs->stlen == 1 && (sep->re_flags & CONSTANT) == 0) { if (fs->stptr[0] == ' ') { diff --git a/interpret.h b/interpret.h index fed0078c..4381a929 100644 --- a/interpret.h +++ b/interpret.h @@ -248,7 +248,7 @@ uninitialized_scalar: case Op_subscript: t2 = mk_sub(pc->sub_count); - t1 = POP_ARRAY(); + t1 = POP_ARRAY(false); if (do_lint && in_array(t1, t2) == NULL) { t2 = force_string(t2); @@ -295,7 +295,7 @@ uninitialized_scalar: case Op_sub_array: t2 = mk_sub(pc->sub_count); - t1 = POP_ARRAY(); + t1 = POP_ARRAY(false); r = in_array(t1, t2); if (r == NULL) { r = make_array(); @@ -321,7 +321,7 @@ uninitialized_scalar: case Op_subscript_lhs: t2 = mk_sub(pc->sub_count); - t1 = POP_ARRAY(); + t1 = POP_ARRAY(false); if (do_lint && in_array(t1, t2) == NULL) { t2 = force_string(t2); if (pc->do_reference) @@ -884,19 +884,19 @@ mod: break; case Op_K_delete: - t1 = POP_ARRAY(); + t1 = POP_ARRAY(false); do_delete(t1, pc->expr_count); stack_adj(-pc->expr_count); break; case Op_K_delete_loop: - t1 = POP_ARRAY(); + t1 = POP_ARRAY(false); lhs = POP_ADDRESS(); /* item */ do_delete_loop(t1, lhs); break; case Op_in_array: - t1 = POP_ARRAY(); + t1 = POP_ARRAY(false); t2 = mk_sub(pc->expr_count); r = node_Boolean[(in_array(t1, t2) != NULL)]; DEREF(t2); @@ -915,7 +915,7 @@ mod: bool saved_end = false; /* get the array */ - array = POP_ARRAY(); + array = POP_ARRAY(true); /* sanity: check if empty */ num_elems = assoc_length(array); @@ -51,6 +51,12 @@ make_regexp(const char *s, size_t len, bool ignorecase, bool dfa, bool canfatal) static bool no_dfa = false; int i; static struct dfa* dfaregs[2] = { NULL, NULL }; + static bool nul_warned = false; + + if (do_lint && ! nul_warned && memchr(s, '\0', len) != NULL) { + nul_warned = true; + lintwarn(_("behavior of matching a regexp containing NUL characters is not defined by POSIX")); + } /* * The number of bytes in the current multibyte character. @@ -148,6 +154,12 @@ make_regexp(const char *s, size_t len, bool ignorecase, bool dfa, bool canfatal) && strchr("()|*+?.^$\\[]", c2) != NULL) *dest++ = '\\'; *dest++ = (char) c2; + if (do_lint + && ! nul_warned + && c2 == '\0') { + nul_warned = true; + lintwarn(_("behavior of matching a regexp containing NUL characters is not defined by POSIX")); + } break; case '8': case '9': /* a\9b not valid */ |