From 4c13972fdd40af0b34ee55703b631fc763398801 Mon Sep 17 00:00:00 2001 From: Nikita Pettik <korablev@tarantool.org> Date: Fri, 22 Nov 2019 19:29:08 +0300 Subject: [PATCH] sql: fix possible null dereference in sql_expr_coll() Some built-in functions can accept different number of arguments. Check of argument count for such functions takes place right before its execution. So it is possible that expression-list representing arguments for built-in function is NULL. On the other hand, in sql_expr_coll() (which returns collation of expression) it is assumed that if function features SQL_FUNC_DERIVEDCOLL flag (it implies that resulting collation depends on collation of arguments) then it has at least one argument. The last assumption is wrong considering for example SUBSTR() function: it may have 1 or 2 arguments, so check of argument count doesn't occur during compilation. Hence, if it is required to calculate collation for SUBSTR() function and there's no arguments, Tarantool crashes due to null-dereference. This patch fixes this bug with one additional check in sql_expr_coll(). --- src/box/sql/expr.c | 3 ++- test/sql/collation.result | 9 +++++++++ test/sql/collation.test.lua | 5 +++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c index 648b7170ee..0bdcfe5764 100644 --- a/src/box/sql/expr.c +++ b/src/box/sql/expr.c @@ -332,7 +332,8 @@ sql_expr_coll(Parse *parse, Expr *p, bool *is_explicit_coll, uint32_t *coll_id, sql_func_by_signature(p->u.zToken, arg_count); if (func == NULL) break; - if (sql_func_flag_is_set(func, SQL_FUNC_DERIVEDCOLL)) { + if (sql_func_flag_is_set(func, SQL_FUNC_DERIVEDCOLL) && + arg_count > 0) { /* * Now we use quite straightforward * approach assuming that resulting diff --git a/test/sql/collation.result b/test/sql/collation.result index 11962ef472..fbc7ce9aa1 100644 --- a/test/sql/collation.result +++ b/test/sql/collation.result @@ -292,6 +292,15 @@ box.execute("SELECT * FROM t WHERE a COLLATE \"binary\" = c COLLATE \"unicode\"; - null - Illegal mix of collations ... +-- Make sure that using function featuring variable arguemnts +-- length and resulting collation which depends on arguments +-- is processed correctly. +-- +box.execute("SELECT * FROM t WHERE a COLLATE \"binary\" = substr();") +--- +- null +- 'Wrong number of arguments is passed to SUBSTR(): expected 1 or 2, got 0' +... -- Compound queries perform implicit comparisons between values. -- Hence, rules for collations compatibilities are the same. -- diff --git a/test/sql/collation.test.lua b/test/sql/collation.test.lua index 1be28b3ff2..a013253cdd 100644 --- a/test/sql/collation.test.lua +++ b/test/sql/collation.test.lua @@ -80,6 +80,11 @@ box.execute("SELECT * FROM t WHERE b = c;") box.execute("SELECT * FROM t WHERE b COLLATE \"binary\" = c;") box.execute("SELECT * FROM t WHERE a = c;") box.execute("SELECT * FROM t WHERE a COLLATE \"binary\" = c COLLATE \"unicode\";") +-- Make sure that using function featuring variable arguemnts +-- length and resulting collation which depends on arguments +-- is processed correctly. +-- +box.execute("SELECT * FROM t WHERE a COLLATE \"binary\" = substr();") -- Compound queries perform implicit comparisons between values. -- Hence, rules for collations compatibilities are the same. -- GitLab