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>
1_31_stable
Brian Foley 2019-01-01 13:40:59 -08:00 committed by Denys Vlasenko
parent dac15a10ac
commit 08a514c097
2 changed files with 20 additions and 10 deletions

View File

@ -281,12 +281,15 @@ typedef struct tsplitter_s {
#define OF_STR2 0x080000 #define OF_STR2 0x080000
#define OF_NUM1 0x100000 #define OF_NUM1 0x100000
#define OF_CHECKED 0x200000 #define OF_CHECKED 0x200000
#define OF_REQUIRED 0x400000
/* combined operator flags */ /* combined operator flags */
#define xx 0 #define xx 0
#define xV OF_RES2 #define xV OF_RES2
#define xS (OF_RES2 | OF_STR2) #define xS (OF_RES2 | OF_STR2)
#define Vx OF_RES1 #define Vx OF_RES1
#define Rx (OF_RES1 | OF_NUM1 | OF_REQUIRED)
#define VV (OF_RES1 | OF_RES2) #define VV (OF_RES1 | OF_RES2)
#define Nx (OF_RES1 | OF_NUM1) #define Nx (OF_RES1 | OF_NUM1)
#define NV (OF_RES1 | OF_NUM1 | OF_RES2) #define NV (OF_RES1 | OF_NUM1 | OF_RES2)
@ -425,7 +428,7 @@ static const uint32_t tokeninfo[] = {
0, 0,
0, /* \n */ 0, /* \n */
ST_IF, ST_DO, ST_FOR, OC_BREAK, 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_PRINTF, OC_NEXT, OC_NEXTFILE,
OC_RETURN|Vx, OC_EXIT|Nx, OC_RETURN|Vx, OC_EXIT|Nx,
ST_WHILE, 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_UNEXP_TOKEN[] ALIGN1 = "Unexpected token";
static const char EMSG_DIV_BY_ZERO[] ALIGN1 = "Division by zero"; 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_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_NOT_ARRAY[] ALIGN1 = "Not an array";
static const char EMSG_POSSIBLE_ERROR[] ALIGN1 = "Possible syntax error"; static const char EMSG_POSSIBLE_ERROR[] ALIGN1 = "Possible syntax error";
static const char EMSG_UNDEF_FUNC[] ALIGN1 = "Call to undefined function"; static const char EMSG_UNDEF_FUNC[] ALIGN1 = "Call to undefined function";
@ -1426,7 +1429,11 @@ static void chain_expr(uint32_t info)
node *n; node *n;
n = chain_node(info); n = chain_node(info);
n->l.n = parse_expr(TC_OPTERM | TC_GRPTERM); 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) if (t_tclass & TC_GRPTERM)
rollback_token(); rollback_token();
} }

View File

@ -336,10 +336,13 @@ testing "awk continue" \
'BEGIN { if (1) continue; else a = 1 }' 'BEGIN { if (1) continue; else a = 1 }'
testing "awk handles invalid for loop" \ 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" \ 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 "description" "command" "result" "infile" "stdin"
testing 'awk negative field access' \ testing 'awk negative field access' \