summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordkatz@damien-katzs-computer.local <>2007-08-05 21:37:55 -0400
committerdkatz@damien-katzs-computer.local <>2007-08-05 21:37:55 -0400
commita933f28a937dd8e6b547a68c94b1baedd3a5ff2d (patch)
tree9172987b105bf8879768d7b8a20358ca9da23be1
parent3fe2098964a0c6b8c5bc2534db260dcdddb7d246 (diff)
downloadmariadb-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.result24
-rw-r--r--mysql-test/t/udf.test36
-rw-r--r--sql/item_func.cc3
-rw-r--r--sql/udf_example.c35
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 */