Bug #25382: Passing NULL to an UDF called from stored procedures
crashes server Check for null value is reliable only after calling some of the val_xxx() methods. If the val_xxx() method is not called the null_value flag will be set only for certain types of NULL values (like SQL constant NULLs for example). This caused a crash while trying to dereference a NULL pointer that is returned by val_str() for NULL values. Fixed by swapping the order of val_xxx() and null_value check.
This commit is contained in:
parent
12c6e9d2b0
commit
20d94f1105
@ -240,3 +240,37 @@ drop table bug18761;
|
||||
select is_const((1,2,3));
|
||||
ERROR 21000: Operand should contain 1 column(s)
|
||||
drop function if exists is_const;
|
||||
CREATE FUNCTION metaphon RETURNS STRING SONAME "UDF_EXAMPLE_LIB";
|
||||
CREATE FUNCTION myfunc_double RETURNS REAL SONAME "UDF_EXAMPLE_LIB";
|
||||
CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "UDF_EXAMPLE_LIB";
|
||||
create function f1(p1 varchar(255))
|
||||
returns varchar(255)
|
||||
begin
|
||||
return metaphon(p1);
|
||||
end//
|
||||
create function f2(p1 varchar(255))
|
||||
returns double
|
||||
begin
|
||||
return myfunc_double(p1);
|
||||
end//
|
||||
create function f3(p1 varchar(255))
|
||||
returns double
|
||||
begin
|
||||
return myfunc_int(p1);
|
||||
end//
|
||||
select f3(NULL);
|
||||
f3(NULL)
|
||||
0
|
||||
select f2(NULL);
|
||||
f2(NULL)
|
||||
NULL
|
||||
select f1(NULL);
|
||||
f1(NULL)
|
||||
NULL
|
||||
drop function f1;
|
||||
drop function f2;
|
||||
drop function f3;
|
||||
drop function metaphon;
|
||||
drop function myfunc_double;
|
||||
drop function myfunc_int;
|
||||
End of 5.0 tests.
|
||||
|
@ -242,3 +242,50 @@ drop table bug18761;
|
||||
select is_const((1,2,3));
|
||||
|
||||
drop function if exists is_const;
|
||||
|
||||
#
|
||||
# Bug #25382: Passing NULL to an UDF called from stored procedures
|
||||
# crashes server
|
||||
#
|
||||
--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
|
||||
eval CREATE FUNCTION metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_LIB";
|
||||
|
||||
--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
|
||||
eval CREATE FUNCTION myfunc_double RETURNS REAL SONAME "$UDF_EXAMPLE_LIB";
|
||||
|
||||
--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
|
||||
eval CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "$UDF_EXAMPLE_LIB";
|
||||
|
||||
delimiter //;
|
||||
create function f1(p1 varchar(255))
|
||||
returns varchar(255)
|
||||
begin
|
||||
return metaphon(p1);
|
||||
end//
|
||||
|
||||
create function f2(p1 varchar(255))
|
||||
returns double
|
||||
begin
|
||||
return myfunc_double(p1);
|
||||
end//
|
||||
|
||||
create function f3(p1 varchar(255))
|
||||
returns double
|
||||
begin
|
||||
return myfunc_int(p1);
|
||||
end//
|
||||
|
||||
delimiter ;//
|
||||
|
||||
select f3(NULL);
|
||||
select f2(NULL);
|
||||
select f1(NULL);
|
||||
|
||||
drop function f1;
|
||||
drop function f2;
|
||||
drop function f3;
|
||||
drop function metaphon;
|
||||
drop function myfunc_double;
|
||||
drop function myfunc_int;
|
||||
|
||||
--echo End of 5.0 tests.
|
||||
|
@ -2729,25 +2729,28 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func,
|
||||
|
||||
if (arguments[i]->const_item())
|
||||
{
|
||||
if (arguments[i]->null_value)
|
||||
continue;
|
||||
|
||||
switch (arguments[i]->result_type())
|
||||
{
|
||||
case STRING_RESULT:
|
||||
case DECIMAL_RESULT:
|
||||
{
|
||||
String *res= arguments[i]->val_str(&buffers[i]);
|
||||
if (arguments[i]->null_value)
|
||||
continue;
|
||||
f_args.args[i]= (char*) res->ptr();
|
||||
break;
|
||||
}
|
||||
case INT_RESULT:
|
||||
*((longlong*) to)= arguments[i]->val_int();
|
||||
if (arguments[i]->null_value)
|
||||
continue;
|
||||
f_args.args[i]= to;
|
||||
to+= ALIGN_SIZE(sizeof(longlong));
|
||||
break;
|
||||
case REAL_RESULT:
|
||||
*((double*) to)= arguments[i]->val_real();
|
||||
if (arguments[i]->null_value)
|
||||
continue;
|
||||
f_args.args[i]= to;
|
||||
to+= ALIGN_SIZE(sizeof(double));
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user