aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2021-06-29 12:16:36 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2021-06-29 12:16:36 +0200
commit6872c193a935df47facf717c15a32f93b43c6bcf (patch)
tree6710abc0886289331f56a36a983389d7a18b2fc4
parent686287b5da98508dd03fb295745c82d00440131e (diff)
downloadbusybox-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.c22
-rwxr-xr-xtestsuite/awk.tests11
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
74prg='
75BEGIN {
76 v=1
77 a=2
78 print v (a)
79}'
80testing "'v (a)' is not a function call, it is a concatenation" \
81 "awk '$prg' 2>&1" \
82 "12\n" \
83 "" ""
84
74 85
75optional DESKTOP 86optional DESKTOP
76testing "awk hex const 1" "awk '{ print or(0xffffffff,1) }'" "4294967295\n" "" "\n" 87testing "awk hex const 1" "awk '{ print or(0xffffffff,1) }'" "4294967295\n" "" "\n"