Commit 4752a039 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-17995 INET6_NTOA(ucs2_input) erroneously returns NULL

parent 5c0730e0
...@@ -6383,3 +6383,15 @@ DEALLOCATE PREPARE stmt; ...@@ -6383,3 +6383,15 @@ DEALLOCATE PREPARE stmt;
# #
# End of 10.2 tests # 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; ...@@ -1094,3 +1094,18 @@ DEALLOCATE PREPARE stmt;
--echo # --echo #
--echo # End of 10.2 tests --echo # End of 10.2 tests
--echo # --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() ...@@ -162,41 +162,6 @@ longlong Item_func_inet_bool_base::val_int()
return calc_value(arg_str) ? 1 : 0; 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) ...@@ -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. Converts IP-address-string to IP-address-data.
...@@ -713,6 +695,32 @@ bool Item_func_inet6_aton::calc_value(const String *arg, String *buffer) ...@@ -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. Converts IP-address-data to IP-address-string.
...@@ -724,11 +732,8 @@ bool Item_func_inet6_aton::calc_value(const String *arg, String *buffer) ...@@ -724,11 +732,8 @@ bool Item_func_inet6_aton::calc_value(const String *arg, String *buffer)
@retval true The string has been converted sucessfully. @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) if ((int) arg->length() == IN_ADDR_SIZE)
{ {
char str[INET_ADDRSTRLEN]; char str[INET_ADDRSTRLEN];
......
...@@ -91,35 +91,15 @@ class Item_func_inet_bool_base : public Item_bool_func ...@@ -91,35 +91,15 @@ class Item_func_inet_bool_base : public Item_bool_func
}; };
/*************************************************************************
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. 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: public:
inline Item_func_inet6_aton(THD *thd, Item *ip_addr): 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: public:
...@@ -136,8 +116,10 @@ class Item_func_inet6_aton : public Item_func_inet_str_base ...@@ -136,8 +116,10 @@ class Item_func_inet6_aton : public Item_func_inet_str_base
Item *get_copy(THD *thd) Item *get_copy(THD *thd)
{ return get_item_copy<Item_func_inet6_aton>(thd, this); } { return get_item_copy<Item_func_inet6_aton>(thd, this); }
String *val_str(String *to);
protected: protected:
virtual bool calc_value(const String *arg, String *buffer); bool calc_value(const String *arg, String *buffer);
}; };
...@@ -145,11 +127,11 @@ class Item_func_inet6_aton : public Item_func_inet_str_base ...@@ -145,11 +127,11 @@ class Item_func_inet6_aton : public Item_func_inet_str_base
Item_func_inet6_ntoa implements INET6_NTOA() SQL-function. 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: public:
inline Item_func_inet6_ntoa(THD *thd, Item *ip_addr): 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: public:
...@@ -168,11 +150,12 @@ class Item_func_inet6_ntoa : public Item_func_inet_str_base ...@@ -168,11 +150,12 @@ class Item_func_inet6_ntoa : public Item_func_inet_str_base
maybe_null= 1; maybe_null= 1;
return FALSE; return FALSE;
} }
String *val_str_ascii(String *to);
Item *get_copy(THD *thd) Item *get_copy(THD *thd)
{ return get_item_copy<Item_func_inet6_ntoa>(thd, this); } { return get_item_copy<Item_func_inet6_ntoa>(thd, this); }
protected: 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() ...@@ -134,6 +134,15 @@ bool Type_handler_data::init()
Type_handler_data *type_handler_data= NULL; 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) void VDec::set(Item *item)
{ {
......
...@@ -110,6 +110,58 @@ class NativeBuffer: public Native ...@@ -110,6 +110,58 @@ class NativeBuffer: public Native
}; };
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 class Dec_ptr
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment