diff options
author | dkatz@damien-katzs-computer.local <> | 2007-08-05 21:37:55 -0400 |
---|---|---|
committer | dkatz@damien-katzs-computer.local <> | 2007-08-05 21:37:55 -0400 |
commit | a933f28a937dd8e6b547a68c94b1baedd3a5ff2d (patch) | |
tree | 9172987b105bf8879768d7b8a20358ca9da23be1 | |
parent | 3fe2098964a0c6b8c5bc2534db260dcdddb7d246 (diff) | |
download | mariadb-git-a933f28a937dd8e6b547a68c94b1baedd3a5ff2d.tar.gz |
Bug #29804 UDF parameters don't contain correct string length
Previously, UDF *_init functions were passed constant strings with erroneous lengths.
The length came from the containing variable's size, not the length of the value itself.
Now the *_init functions get the constant as a null terminated string with the correct
length supplied.
-rw-r--r-- | mysql-test/r/udf.result | 24 | ||||
-rw-r--r-- | mysql-test/t/udf.test | 36 | ||||
-rw-r--r-- | sql/item_func.cc | 3 | ||||
-rw-r--r-- | sql/udf_example.c | 35 |
4 files changed, 97 insertions, 1 deletions
diff --git a/mysql-test/r/udf.result b/mysql-test/r/udf.result index bba722e523c..f1e47905f5d 100644 --- a/mysql-test/r/udf.result +++ b/mysql-test/r/udf.result @@ -334,4 +334,28 @@ Qcache_queries_in_cache 0 drop table t1; drop function metaphon; set GLOBAL query_cache_size=default; +CREATE TABLE const_len_bug ( +str_const varchar(4000), +result1 varchar(4000), +result2 varchar(4000) +); +CREATE TRIGGER check_const_len_trigger BEFORE INSERT ON const_len_bug FOR EACH ROW BEGIN +set NEW.str_const = 'bar'; +set NEW.result2 = check_const_len(NEW.str_const); +END | +CREATE PROCEDURE check_const_len_sp (IN str_const VARCHAR(4000)) +BEGIN +DECLARE result VARCHAR(4000); +SET result = check_const_len(str_const); +insert into const_len_bug values(str_const, result, ""); +END | +CREATE FUNCTION check_const_len RETURNS string SONAME "UDF_EXAMPLE_LIB"; +CALL check_const_len_sp("foo"); +SELECT * from const_len_bug; +str_const result1 result2 +bar Correct length Correct length +DROP FUNCTION check_const_len; +DROP PROCEDURE check_const_len_sp; +DROP TRIGGER check_const_len_trigger; +DROP TABLE const_len_bug; End of 5.0 tests. diff --git a/mysql-test/t/udf.test b/mysql-test/t/udf.test index 07a4a2d870b..2f1d197cb9e 100644 --- a/mysql-test/t/udf.test +++ b/mysql-test/t/udf.test @@ -364,4 +364,40 @@ drop function metaphon; set GLOBAL query_cache_size=default; +# +# Bug #29804 UDF parameters don't contain correct string length +# + +CREATE TABLE const_len_bug ( + str_const varchar(4000), + result1 varchar(4000), + result2 varchar(4000) +); + +DELIMITER |; +CREATE TRIGGER check_const_len_trigger BEFORE INSERT ON const_len_bug FOR EACH ROW BEGIN + set NEW.str_const = 'bar'; + set NEW.result2 = check_const_len(NEW.str_const); +END | + +CREATE PROCEDURE check_const_len_sp (IN str_const VARCHAR(4000)) +BEGIN +DECLARE result VARCHAR(4000); +SET result = check_const_len(str_const); +insert into const_len_bug values(str_const, result, ""); +END | +DELIMITER ;| + +--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB +eval CREATE FUNCTION check_const_len RETURNS string SONAME "$UDF_EXAMPLE_LIB"; + +CALL check_const_len_sp("foo"); + +SELECT * from const_len_bug; + +DROP FUNCTION check_const_len; +DROP PROCEDURE check_const_len_sp; +DROP TRIGGER check_const_len_trigger; +DROP TABLE const_len_bug; + --echo End of 5.0 tests. diff --git a/sql/item_func.cc b/sql/item_func.cc index 9a26169ad30..4492b7519aa 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2916,7 +2916,8 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func, String *res= arguments[i]->val_str(&buffers[i]); if (arguments[i]->null_value) continue; - f_args.args[i]= (char*) res->ptr(); + f_args.args[i]= (char*) res->c_ptr(); + f_args.lengths[i]= res->length(); break; } case INT_RESULT: diff --git a/sql/udf_example.c b/sql/udf_example.c index b603464568e..5165a577555 100644 --- a/sql/udf_example.c +++ b/sql/udf_example.c @@ -1106,4 +1106,39 @@ char * is_const(UDF_INIT *initid, UDF_ARGS *args __attribute__((unused)), } +my_bool check_const_len_init(UDF_INIT *initid, UDF_ARGS *args, char *message) +{ + if (args->arg_count != 1) + { + strmov(message, "IS_CONST accepts only one argument"); + return 1; + } + if (args->args[0] == 0) + { + initid->ptr= "Not constant"; + } + else if(strlen(args->args[0]) == args->lengths[0]) + { + initid->ptr= "Correct length"; + } + else + { + initid->ptr= "Wrong length"; + } + initid->max_length = 100; + return 0; +} + +char * check_const_len(UDF_INIT *initid, UDF_ARGS *args __attribute__((unused)), + char *result, unsigned long *length, + char *is_null, char *error __attribute__((unused))) +{ + strmov(result, initid->ptr); + *length= strlen(result); + *is_null= 0; + return result; +} + + + #endif /* HAVE_DLOPEN */ |