diff options
author | Brian Foley <bpfoley@google.com> | 2019-01-01 13:40:59 -0800 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2019-01-21 12:55:49 +0100 |
commit | 08a514c097f1451678940a3178a9565b9d65a193 (patch) | |
tree | f86e7566847b02108eb243ad79f25345e6ba58ec | |
parent | dac15a10accc6921d1559d254ceed9fe9d092ddf (diff) | |
download | busybox-08a514c097f1451678940a3178a9565b9d65a193.tar.gz |
awk: Syntax error if delete isn't given an arg.
Unlike exit and return, delete strictly requires an arg, and derefs a
null pointer if executed without one.
Signed-off-by: Brian Foley <bpfoley@google.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | editors/awk.c | 23 | ||||
-rwxr-xr-x | testsuite/awk.tests | 7 |
2 files changed, 20 insertions, 10 deletions
diff --git a/editors/awk.c b/editors/awk.c index f2b8b13eb..90edec82c 100644 --- a/editors/awk.c +++ b/editors/awk.c @@ -275,18 +275,21 @@ typedef struct tsplitter_s { | TC_STRING | TC_NUMBER | TC_UOPPOST) #define TC_CONCAT2 (TC_OPERAND | TC_UOPPRE) -#define OF_RES1 0x010000 -#define OF_RES2 0x020000 -#define OF_STR1 0x040000 -#define OF_STR2 0x080000 -#define OF_NUM1 0x100000 -#define OF_CHECKED 0x200000 +#define OF_RES1 0x010000 +#define OF_RES2 0x020000 +#define OF_STR1 0x040000 +#define OF_STR2 0x080000 +#define OF_NUM1 0x100000 +#define OF_CHECKED 0x200000 +#define OF_REQUIRED 0x400000 + /* combined operator flags */ #define xx 0 #define xV OF_RES2 #define xS (OF_RES2 | OF_STR2) #define Vx OF_RES1 +#define Rx (OF_RES1 | OF_NUM1 | OF_REQUIRED) #define VV (OF_RES1 | OF_RES2) #define Nx (OF_RES1 | OF_NUM1) #define NV (OF_RES1 | OF_NUM1 | OF_RES2) @@ -425,7 +428,7 @@ static const uint32_t tokeninfo[] = { 0, 0, /* \n */ ST_IF, ST_DO, ST_FOR, OC_BREAK, - OC_CONTINUE, OC_DELETE|Vx, OC_PRINT, + OC_CONTINUE, OC_DELETE|Rx, OC_PRINT, OC_PRINTF, OC_NEXT, OC_NEXTFILE, OC_RETURN|Vx, OC_EXIT|Nx, ST_WHILE, @@ -593,7 +596,7 @@ static const char EMSG_UNEXP_EOS[] ALIGN1 = "Unexpected end of string"; static const char EMSG_UNEXP_TOKEN[] ALIGN1 = "Unexpected token"; static const char EMSG_DIV_BY_ZERO[] ALIGN1 = "Division by zero"; static const char EMSG_INV_FMT[] ALIGN1 = "Invalid format specifier"; -static const char EMSG_TOO_FEW_ARGS[] ALIGN1 = "Too few arguments for builtin"; +static const char EMSG_TOO_FEW_ARGS[] ALIGN1 = "Too few arguments"; static const char EMSG_NOT_ARRAY[] ALIGN1 = "Not an array"; static const char EMSG_POSSIBLE_ERROR[] ALIGN1 = "Possible syntax error"; static const char EMSG_UNDEF_FUNC[] ALIGN1 = "Call to undefined function"; @@ -1426,7 +1429,11 @@ static void chain_expr(uint32_t info) node *n; n = chain_node(info); + n->l.n = parse_expr(TC_OPTERM | TC_GRPTERM); + if ((info & OF_REQUIRED) && !n->l.n) + syntax_error(EMSG_TOO_FEW_ARGS); + if (t_tclass & TC_GRPTERM) rollback_token(); } diff --git a/testsuite/awk.tests b/testsuite/awk.tests index 9f353fc10..03fedf771 100755 --- a/testsuite/awk.tests +++ b/testsuite/awk.tests @@ -336,10 +336,13 @@ testing "awk continue" \ 'BEGIN { if (1) continue; else a = 1 }' testing "awk handles invalid for loop" \ - "awk '{ for() }' 2>&1" "awk: cmd. line:1: Unexpected token\n" "" "" + "awk -e '{ for() }' 2>&1" "awk: cmd. line:1: Unexpected token\n" "" "" testing "awk handles colon not preceded by ternary" \ - "awk 'foo:bar:' 2>&1" "awk: cmd. line:1: Unexpected token\n" "" "" + "awk -e foo:bar: 2>&1" "awk: cmd. line:1: Unexpected token\n" "" "" + +testing "awk errors on missing delete arg" \ + "awk -e '{delete}' 2>&1" "awk: cmd. line:1: Too few arguments\n" "" "" # testing "description" "command" "result" "infile" "stdin" testing 'awk negative field access' \ |