mirror of
https://github.com/MariaDB/server.git
synced 2025-07-27 18:02:13 +03:00
MDEV-17995 INET6_NTOA(ucs2_input) erroneously returns NULL
This commit is contained in:
@ -6383,3 +6383,15 @@ DEALLOCATE PREPARE stmt;
|
||||
#
|
||||
# End of 10.2 tests
|
||||
#
|
||||
#
|
||||
# Start of 10.4 tests
|
||||
#
|
||||
#
|
||||
# MDEV-17995 INET6_NTOA(ucs2_input) erroneously returns NULL
|
||||
#
|
||||
SELECT HEX(INET6_ATON('1::1')), HEX(INET6_ATON(CONVERT('1::1' USING ucs2)));
|
||||
HEX(INET6_ATON('1::1')) HEX(INET6_ATON(CONVERT('1::1' USING ucs2)))
|
||||
00010000000000000000000000000001 00010000000000000000000000000001
|
||||
#
|
||||
# End of 10.4 tests
|
||||
#
|
||||
|
@ -1094,3 +1094,18 @@ DEALLOCATE PREPARE stmt;
|
||||
--echo #
|
||||
--echo # End of 10.2 tests
|
||||
--echo #
|
||||
|
||||
--echo #
|
||||
--echo # Start of 10.4 tests
|
||||
--echo #
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-17995 INET6_NTOA(ucs2_input) erroneously returns NULL
|
||||
--echo #
|
||||
|
||||
SELECT HEX(INET6_ATON('1::1')), HEX(INET6_ATON(CONVERT('1::1' USING ucs2)));
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.4 tests
|
||||
--echo #
|
||||
|
@ -162,41 +162,6 @@ longlong Item_func_inet_bool_base::val_int()
|
||||
return calc_value(arg_str) ? 1 : 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
Check the function argument, handle errors properly.
|
||||
|
||||
@param [out] buffer Buffer for string operations.
|
||||
|
||||
@return The function value.
|
||||
*/
|
||||
|
||||
String *Item_func_inet_str_base::val_str_ascii(String *buffer)
|
||||
{
|
||||
DBUG_ASSERT(fixed);
|
||||
|
||||
// String argument expected
|
||||
if (unlikely(args[0]->result_type() != STRING_RESULT))
|
||||
{
|
||||
null_value= true;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
StringBuffer<STRING_BUFFER_USUAL_SIZE> tmp;
|
||||
String *arg_str= args[0]->val_str(&tmp);
|
||||
if (unlikely(!arg_str))
|
||||
{
|
||||
// Out-of memory happened. error has been reported.
|
||||
// Or: the underlying field is NULL
|
||||
null_value= true;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
null_value= !calc_value(arg_str, buffer);
|
||||
|
||||
return unlikely(null_value) ? NULL : buffer;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -673,6 +638,23 @@ static void ipv6_to_str(const in6_addr *ipv6, char *str)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
String *Item_func_inet6_aton::val_str(String *buffer)
|
||||
{
|
||||
DBUG_ASSERT(fixed);
|
||||
|
||||
// String argument expected
|
||||
if (unlikely(args[0]->result_type() != STRING_RESULT))
|
||||
{
|
||||
null_value= true;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Ascii_ptr_and_buffer<STRING_BUFFER_USUAL_SIZE> tmp(args[0]);
|
||||
null_value= tmp.is_null() || !calc_value(tmp.string(), buffer);
|
||||
return unlikely(null_value) ? NULL : buffer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Converts IP-address-string to IP-address-data.
|
||||
|
||||
@ -713,6 +695,32 @@ bool Item_func_inet6_aton::calc_value(const String *arg, String *buffer)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
Check the function argument, handle errors properly.
|
||||
|
||||
@param [out] buffer Buffer for string operations.
|
||||
|
||||
@return The function value.
|
||||
*/
|
||||
|
||||
String *Item_func_inet6_ntoa::val_str_ascii(String *buffer)
|
||||
{
|
||||
DBUG_ASSERT(fixed);
|
||||
|
||||
// Binary string argument expected
|
||||
if (unlikely(args[0]->result_type() != STRING_RESULT ||
|
||||
args[0]->collation.collation != &my_charset_bin))
|
||||
{
|
||||
null_value= true;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
String_ptr_and_buffer<STRING_BUFFER_USUAL_SIZE> tmp(args[0]);
|
||||
null_value= tmp.is_null() || !calc_value(tmp.string(), buffer);
|
||||
return unlikely(null_value) ? NULL : buffer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Converts IP-address-data to IP-address-string.
|
||||
|
||||
@ -724,11 +732,8 @@ bool Item_func_inet6_aton::calc_value(const String *arg, String *buffer)
|
||||
@retval true The string has been converted sucessfully.
|
||||
*/
|
||||
|
||||
bool Item_func_inet6_ntoa::calc_value(const String *arg, String *buffer)
|
||||
bool Item_func_inet6_ntoa::calc_value(const Binary_string *arg, String *buffer)
|
||||
{
|
||||
if (arg->charset() != &my_charset_bin)
|
||||
return false;
|
||||
|
||||
if ((int) arg->length() == IN_ADDR_SIZE)
|
||||
{
|
||||
char str[INET_ADDRSTRLEN];
|
||||
|
@ -91,35 +91,15 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
Item_func_inet_str_base implements common code for INET6/IP-related
|
||||
functions returning string value.
|
||||
*************************************************************************/
|
||||
|
||||
class Item_func_inet_str_base : public Item_str_ascii_func
|
||||
{
|
||||
public:
|
||||
inline Item_func_inet_str_base(THD *thd, Item *arg):
|
||||
Item_str_ascii_func(thd, arg)
|
||||
{ }
|
||||
|
||||
public:
|
||||
virtual String *val_str_ascii(String *buffer);
|
||||
|
||||
protected:
|
||||
virtual bool calc_value(const String *arg, String *buffer) = 0;
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
Item_func_inet6_aton implements INET6_ATON() SQL-function.
|
||||
*************************************************************************/
|
||||
|
||||
class Item_func_inet6_aton : public Item_func_inet_str_base
|
||||
class Item_func_inet6_aton : public Item_str_func
|
||||
{
|
||||
public:
|
||||
inline Item_func_inet6_aton(THD *thd, Item *ip_addr):
|
||||
Item_func_inet_str_base(thd, ip_addr)
|
||||
Item_str_func(thd, ip_addr)
|
||||
{ }
|
||||
|
||||
public:
|
||||
@ -136,8 +116,10 @@ public:
|
||||
Item *get_copy(THD *thd)
|
||||
{ return get_item_copy<Item_func_inet6_aton>(thd, this); }
|
||||
|
||||
String *val_str(String *to);
|
||||
|
||||
protected:
|
||||
virtual bool calc_value(const String *arg, String *buffer);
|
||||
bool calc_value(const String *arg, String *buffer);
|
||||
};
|
||||
|
||||
|
||||
@ -145,11 +127,11 @@ protected:
|
||||
Item_func_inet6_ntoa implements INET6_NTOA() SQL-function.
|
||||
*************************************************************************/
|
||||
|
||||
class Item_func_inet6_ntoa : public Item_func_inet_str_base
|
||||
class Item_func_inet6_ntoa : public Item_str_ascii_func
|
||||
{
|
||||
public:
|
||||
inline Item_func_inet6_ntoa(THD *thd, Item *ip_addr):
|
||||
Item_func_inet_str_base(thd, ip_addr)
|
||||
Item_str_ascii_func(thd, ip_addr)
|
||||
{ }
|
||||
|
||||
public:
|
||||
@ -168,11 +150,12 @@ public:
|
||||
maybe_null= 1;
|
||||
return FALSE;
|
||||
}
|
||||
String *val_str_ascii(String *to);
|
||||
Item *get_copy(THD *thd)
|
||||
{ return get_item_copy<Item_func_inet6_ntoa>(thd, this); }
|
||||
|
||||
protected:
|
||||
virtual bool calc_value(const String *arg, String *buffer);
|
||||
bool calc_value(const Binary_string *arg, String *buffer);
|
||||
};
|
||||
|
||||
|
||||
|
@ -134,6 +134,15 @@ bool Type_handler_data::init()
|
||||
Type_handler_data *type_handler_data= NULL;
|
||||
|
||||
|
||||
String_ptr::String_ptr(Item *item, String *buffer)
|
||||
:m_string_ptr(item->val_str(buffer))
|
||||
{ }
|
||||
|
||||
|
||||
Ascii_ptr::Ascii_ptr(Item *item, String *buffer)
|
||||
:String_ptr(item->val_str_ascii(buffer))
|
||||
{ }
|
||||
|
||||
|
||||
void VDec::set(Item *item)
|
||||
{
|
||||
|
@ -110,6 +110,58 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class String_ptr
|
||||
{
|
||||
protected:
|
||||
String *m_string_ptr;
|
||||
public:
|
||||
String_ptr(String *str)
|
||||
:m_string_ptr(str)
|
||||
{ }
|
||||
String_ptr(Item *item, String *buffer);
|
||||
const String *string() const { return m_string_ptr; }
|
||||
const char *ptr() const
|
||||
{
|
||||
DBUG_ASSERT(m_string_ptr);
|
||||
return m_string_ptr->ptr();
|
||||
}
|
||||
uint32 length() const
|
||||
{
|
||||
DBUG_ASSERT(m_string_ptr);
|
||||
return m_string_ptr->length();
|
||||
}
|
||||
bool is_null() const { return m_string_ptr == NULL; }
|
||||
};
|
||||
|
||||
|
||||
class Ascii_ptr: public String_ptr
|
||||
{
|
||||
public:
|
||||
Ascii_ptr(Item *item, String *buffer);
|
||||
};
|
||||
|
||||
|
||||
template<size_t buff_sz>
|
||||
class String_ptr_and_buffer: public StringBuffer<buff_sz>,
|
||||
public String_ptr
|
||||
{
|
||||
public:
|
||||
String_ptr_and_buffer(Item *item)
|
||||
:String_ptr(item, this)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
template<size_t buff_sz>
|
||||
class Ascii_ptr_and_buffer: public StringBuffer<buff_sz>,
|
||||
public Ascii_ptr
|
||||
{
|
||||
public:
|
||||
Ascii_ptr_and_buffer(Item *item)
|
||||
:Ascii_ptr(item, this)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
class Dec_ptr
|
||||
{
|
||||
|
Reference in New Issue
Block a user