diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2021-06-29 12:16:36 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-06-29 12:16:36 +0200 |
commit | 6872c193a935df47facf717c15a32f93b43c6bcf (patch) | |
tree | 6710abc0886289331f56a36a983389d7a18b2fc4 | |
parent | 686287b5da98508dd03fb295745c82d00440131e (diff) | |
download | busybox-w32-6872c193a935df47facf717c15a32f93b43c6bcf.tar.gz busybox-w32-6872c193a935df47facf717c15a32f93b43c6bcf.tar.bz2 busybox-w32-6872c193a935df47facf717c15a32f93b43c6bcf.zip |
awk: fix parsing of expressions such as "v (a)"
function old new delta
next_token 812 825 +13
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | editors/awk.c | 22 | ||||
-rwxr-xr-x | testsuite/awk.tests | 11 |
2 files changed, 29 insertions, 4 deletions
diff --git a/editors/awk.c b/editors/awk.c index 34bcc1798..ce860dc04 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
@@ -1231,11 +1231,24 @@ static uint32_t next_token(uint32_t expected) | |||
1231 | while (isalnum_(*p)) | 1231 | while (isalnum_(*p)) |
1232 | p++; | 1232 | p++; |
1233 | end_of_name = p; | 1233 | end_of_name = p; |
1234 | tc = TC_VARIABLE; | 1234 | |
1235 | /* also consume whitespace between functionname and bracket */ | 1235 | if (last_token_class == TC_FUNCDECL) |
1236 | if (!(expected & TC_VARIABLE) || (expected & TC_ARRAY)) | 1236 | /* eat space in "function FUNC (...) {...}" declaration */ |
1237 | //TODO: why if variable can be here (but not array ref), skipping is not allowed? Example where it matters? | ||
1238 | p = skip_spaces(p); | 1237 | p = skip_spaces(p); |
1238 | else if (expected & TC_ARRAY) { | ||
1239 | /* eat space between array name and [ */ | ||
1240 | char *s = skip_spaces(p); | ||
1241 | if (*s == '[') /* array ref, not just a name? */ | ||
1242 | p = s; | ||
1243 | } | ||
1244 | /* else: do NOT consume whitespace after variable name! | ||
1245 | * gawk allows definition "function FUNC (p) {...}" - note space, | ||
1246 | * but disallows the call "FUNC (p)" because it isn't one - | ||
1247 | * expression "v (a)" should NOT be parsed as TC_FUNCTION: | ||
1248 | * it is a valid concatenation if "v" is a variable, | ||
1249 | * not a function name (and type of name is not known at parse time). | ||
1250 | */ | ||
1251 | |||
1239 | if (*p == '(') { | 1252 | if (*p == '(') { |
1240 | p++; | 1253 | p++; |
1241 | tc = TC_FUNCTION; | 1254 | tc = TC_FUNCTION; |
@@ -1245,6 +1258,7 @@ static uint32_t next_token(uint32_t expected) | |||
1245 | tc = TC_ARRAY; | 1258 | tc = TC_ARRAY; |
1246 | debug_printf_parse("%s: token found:'%s' TC_ARRAY\n", __func__, t_string); | 1259 | debug_printf_parse("%s: token found:'%s' TC_ARRAY\n", __func__, t_string); |
1247 | } else { | 1260 | } else { |
1261 | tc = TC_VARIABLE; | ||
1248 | debug_printf_parse("%s: token found:'%s' TC_VARIABLE\n", __func__, t_string); | 1262 | debug_printf_parse("%s: token found:'%s' TC_VARIABLE\n", __func__, t_string); |
1249 | if (end_of_name == p) { | 1263 | if (end_of_name == p) { |
1250 | /* there is no space for trailing NUL in t_string! | 1264 | /* there is no space for trailing NUL in t_string! |
diff --git a/testsuite/awk.tests b/testsuite/awk.tests index cf9b722dc..6e35d33dd 100755 --- a/testsuite/awk.tests +++ b/testsuite/awk.tests | |||
@@ -71,6 +71,17 @@ testing "awk properly handles undefined function" \ | |||
71 | "L1\n\nawk: cmd. line:5: Call to undefined function\n" \ | 71 | "L1\n\nawk: cmd. line:5: Call to undefined function\n" \ |
72 | "" "" | 72 | "" "" |
73 | 73 | ||
74 | prg=' | ||
75 | BEGIN { | ||
76 | v=1 | ||
77 | a=2 | ||
78 | print v (a) | ||
79 | }' | ||
80 | testing "'v (a)' is not a function call, it is a concatenation" \ | ||
81 | "awk '$prg' 2>&1" \ | ||
82 | "12\n" \ | ||
83 | "" "" | ||
84 | |||
74 | 85 | ||
75 | optional DESKTOP | 86 | optional DESKTOP |
76 | testing "awk hex const 1" "awk '{ print or(0xffffffff,1) }'" "4294967295\n" "" "\n" | 87 | testing "awk hex const 1" "awk '{ print or(0xffffffff,1) }'" "4294967295\n" "" "\n" |