Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
c84dde14
Commit
c84dde14
authored
Apr 05, 2019
by
Alexander Barkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MDEV-19184 Crash in IS_IPV6(_ucs2 0x0031)
parent
02d9b048
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
107 additions
and
35 deletions
+107
-35
mysql-test/main/ctype_ucs.result
mysql-test/main/ctype_ucs.result
+24
-0
mysql-test/main/ctype_ucs.test
mysql-test/main/ctype_ucs.test
+15
-0
sql/item_inetfunc.cc
sql/item_inetfunc.cc
+68
-35
No files found.
mysql-test/main/ctype_ucs.result
View file @
c84dde14
...
...
@@ -6393,5 +6393,29 @@ 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
#
# MDEV-19184 Crash in IS_IPV6(_ucs2 0x0031)
#
SET NAMES utf8;
SELECT IS_IPV6(_ucs2 0x0031);
IS_IPV6(_ucs2 0x0031)
0
SELECT IS_IPV4(_ucs2 0x0031);
IS_IPV4(_ucs2 0x0031)
0
SELECT IS_IPV6(_ucs2 0x003A003A);
IS_IPV6(_ucs2 0x003A003A)
1
SELECT IS_IPV4(_ucs2 0x00310030002E0030002E0030002E0031);
IS_IPV4(_ucs2 0x00310030002E0030002E0030002E0031)
1
SET NAMES utf8, collation_connection=ucs2_bin;
SELECT IS_IPV6('::');
IS_IPV6('::')
1
SELECT IS_IPV4('10.0.0.1');
IS_IPV4('10.0.0.1')
1
SET NAMES utf8;
#
# End of 10.4 tests
#
mysql-test/main/ctype_ucs.test
View file @
c84dde14
...
...
@@ -1105,6 +1105,21 @@ DEALLOCATE PREPARE stmt;
SELECT
HEX
(
INET6_ATON
(
'1::1'
)),
HEX
(
INET6_ATON
(
CONVERT
(
'1::1'
USING
ucs2
)));
--
echo
#
--
echo
# MDEV-19184 Crash in IS_IPV6(_ucs2 0x0031)
--
echo
#
SET
NAMES
utf8
;
SELECT
IS_IPV6
(
_ucs2
0x0031
);
SELECT
IS_IPV4
(
_ucs2
0x0031
);
SELECT
IS_IPV6
(
_ucs2
0x003A003A
);
SELECT
IS_IPV4
(
_ucs2
0x00310030002E0030002E0030002E0031
);
SET
NAMES
utf8
,
collation_connection
=
ucs2_bin
;
SELECT
IS_IPV6
(
'::'
);
SELECT
IS_IPV4
(
'10.0.0.1'
);
SET
NAMES
utf8
;
--
echo
#
--
echo
# End of 10.4 tests
...
...
sql/item_inetfunc.cc
View file @
c84dde14
...
...
@@ -22,9 +22,18 @@
///////////////////////////////////////////////////////////////////////////
static
const
size_t
IN_ADDR_SIZE
=
4
;
static
const
size_t
IN_ADDR_MAX_CHAR_LENGTH
=
15
;
static
const
size_t
IN6_ADDR_SIZE
=
16
;
static
const
size_t
IN6_ADDR_NUM_WORDS
=
IN6_ADDR_SIZE
/
2
;
/**
Non-abbreviated syntax is 8 groups, up to 4 digits each,
plus 7 delimiters between the groups.
Abbreviated syntax is even shorter.
*/
static
const
uint
IN6_ADDR_MAX_CHAR_LENGTH
=
8
*
4
+
7
;
static
const
char
HEX_DIGITS
[]
=
"0123456789abcdef"
;
///////////////////////////////////////////////////////////////////////////
...
...
@@ -143,7 +152,20 @@ class Inet4
{
char
m_buffer
[
IN_ADDR_SIZE
];
protected:
bool
str_to_ipv4
(
const
char
*
str
,
size_t
length
,
CHARSET_INFO
*
cs
);
bool
ascii_to_ipv4
(
const
char
*
str
,
size_t
length
);
bool
character_string_to_ipv4
(
const
char
*
str
,
size_t
str_length
,
CHARSET_INFO
*
cs
)
{
if
(
cs
->
state
&
MY_CS_NONASCII
)
{
char
tmp
[
IN_ADDR_MAX_CHAR_LENGTH
];
String_copier
copier
;
uint
length
=
copier
.
well_formed_copy
(
&
my_charset_latin1
,
tmp
,
sizeof
(
tmp
),
cs
,
str
,
str_length
);
return
ascii_to_ipv4
(
tmp
,
length
);
}
return
ascii_to_ipv4
(
str
,
str_length
);
}
bool
binary_to_ipv4
(
const
char
*
str
,
size_t
length
)
{
if
(
length
!=
sizeof
(
m_buffer
))
...
...
@@ -180,7 +202,7 @@ class Inet4_null: public Inet4, public Null_flag
public:
// Initialize from a text representation
Inet4_null
(
const
char
*
str
,
size_t
length
,
CHARSET_INFO
*
cs
)
:
Null_flag
(
str
_to_ipv4
(
str
,
length
,
cs
))
:
Null_flag
(
character_string
_to_ipv4
(
str
,
length
,
cs
))
{
}
Inet4_null
(
const
String
&
str
)
:
Inet4_null
(
str
.
ptr
(),
str
.
length
(),
str
.
charset
())
...
...
@@ -222,7 +244,20 @@ class Inet6
char
m_buffer
[
IN6_ADDR_SIZE
];
protected:
bool
make_from_item
(
Item
*
item
);
bool
str_to_ipv6
(
const
char
*
str
,
size_t
str_length
,
CHARSET_INFO
*
cs
);
bool
ascii_to_ipv6
(
const
char
*
str
,
size_t
str_length
);
bool
character_string_to_ipv6
(
const
char
*
str
,
size_t
str_length
,
CHARSET_INFO
*
cs
)
{
if
(
cs
->
state
&
MY_CS_NONASCII
)
{
char
tmp
[
IN6_ADDR_MAX_CHAR_LENGTH
];
String_copier
copier
;
uint
length
=
copier
.
well_formed_copy
(
&
my_charset_latin1
,
tmp
,
sizeof
(
tmp
),
cs
,
str
,
str_length
);
return
ascii_to_ipv6
(
tmp
,
length
);
}
return
ascii_to_ipv6
(
str
,
str_length
);
}
bool
binary_to_ipv6
(
const
char
*
str
,
size_t
length
)
{
if
(
length
!=
sizeof
(
m_buffer
))
...
...
@@ -264,7 +299,7 @@ class Inet6_null: public Inet6, public Null_flag
public:
// Initialize from a text representation
Inet6_null
(
const
char
*
str
,
size_t
length
,
CHARSET_INFO
*
cs
)
:
Null_flag
(
str
_to_ipv6
(
str
,
length
,
cs
))
:
Null_flag
(
character_string
_to_ipv6
(
str
,
length
,
cs
))
{
}
Inet6_null
(
const
String
&
str
)
:
Inet6_null
(
str
.
ptr
(),
str
.
length
(),
str
.
charset
())
...
...
@@ -343,20 +378,19 @@ bool Inet6::make_from_item(Item *item)
IPv4-part differently on different platforms.
*/
bool
Inet4
::
str_to_ipv4
(
const
char
*
str
,
size_t
str_length
,
CHARSET_INFO
*
cs
)
bool
Inet4
::
ascii_to_ipv4
(
const
char
*
str
,
size_t
str_length
)
{
DBUG_ASSERT
(
cs
->
mbminlen
==
1
);
if
(
str_length
<
7
)
{
DBUG_PRINT
(
"error"
,
(
"
str
_to_ipv4(%.*s): "
DBUG_PRINT
(
"error"
,
(
"
ascii
_to_ipv4(%.*s): "
"invalid IPv4 address: too short."
,
(
int
)
str_length
,
str
));
return
true
;
}
if
(
str_length
>
15
)
if
(
str_length
>
IN_ADDR_MAX_CHAR_LENGTH
)
{
DBUG_PRINT
(
"error"
,
(
"
str
_to_ipv4(%.*s): "
DBUG_PRINT
(
"error"
,
(
"
ascii
_to_ipv4(%.*s): "
"invalid IPv4 address: too long."
,
(
int
)
str_length
,
str
));
return
true
;
...
...
@@ -380,7 +414,7 @@ bool Inet4::str_to_ipv4(const char *str, size_t str_length, CHARSET_INFO *cs)
if
(
chars_in_group
>
3
)
{
DBUG_PRINT
(
"error"
,
(
"
str
_to_ipv4(%.*s): invalid IPv4 address: "
DBUG_PRINT
(
"error"
,
(
"
ascii
_to_ipv4(%.*s): invalid IPv4 address: "
"too many characters in a group."
,
(
int
)
str_length
,
str
));
return
true
;
...
...
@@ -390,7 +424,7 @@ bool Inet4::str_to_ipv4(const char *str, size_t str_length, CHARSET_INFO *cs)
if
(
byte_value
>
255
)
{
DBUG_PRINT
(
"error"
,
(
"
str
_to_ipv4(%.*s): invalid IPv4 address: "
DBUG_PRINT
(
"error"
,
(
"
ascii
_to_ipv4(%.*s): invalid IPv4 address: "
"invalid byte value."
,
(
int
)
str_length
,
str
));
return
true
;
...
...
@@ -400,7 +434,7 @@ bool Inet4::str_to_ipv4(const char *str, size_t str_length, CHARSET_INFO *cs)
{
if
(
chars_in_group
==
0
)
{
DBUG_PRINT
(
"error"
,
(
"
str
_to_ipv4(%.*s): invalid IPv4 address: "
DBUG_PRINT
(
"error"
,
(
"
ascii
_to_ipv4(%.*s): invalid IPv4 address: "
"too few characters in a group."
,
(
int
)
str_length
,
str
));
return
true
;
...
...
@@ -414,14 +448,14 @@ bool Inet4::str_to_ipv4(const char *str, size_t str_length, CHARSET_INFO *cs)
if
(
dot_count
>
3
)
{
DBUG_PRINT
(
"error"
,
(
"
str
_to_ipv4(%.*s): invalid IPv4 address: "
DBUG_PRINT
(
"error"
,
(
"
ascii
_to_ipv4(%.*s): invalid IPv4 address: "
"too many dots."
,
(
int
)
str_length
,
str
));
return
true
;
}
}
else
{
DBUG_PRINT
(
"error"
,
(
"
str
_to_ipv4(%.*s): invalid IPv4 address: "
DBUG_PRINT
(
"error"
,
(
"
ascii
_to_ipv4(%.*s): invalid IPv4 address: "
"invalid character at pos %d."
,
(
int
)
str_length
,
str
,
(
int
)
(
p
-
str
)));
return
true
;
...
...
@@ -430,14 +464,14 @@ bool Inet4::str_to_ipv4(const char *str, size_t str_length, CHARSET_INFO *cs)
if
(
c
==
'.'
)
{
DBUG_PRINT
(
"error"
,
(
"
str
_to_ipv4(%.*s): invalid IPv4 address: "
DBUG_PRINT
(
"error"
,
(
"
ascii
_to_ipv4(%.*s): invalid IPv4 address: "
"ending at '.'."
,
(
int
)
str_length
,
str
));
return
true
;
}
if
(
dot_count
!=
3
)
{
DBUG_PRINT
(
"error"
,
(
"
str
_to_ipv4(%.*s): invalid IPv4 address: "
DBUG_PRINT
(
"error"
,
(
"
ascii
_to_ipv4(%.*s): invalid IPv4 address: "
"too few groups."
,
(
int
)
str_length
,
str
));
return
true
;
...
...
@@ -445,7 +479,7 @@ bool Inet4::str_to_ipv4(const char *str, size_t str_length, CHARSET_INFO *cs)
ipv4_bytes
[
3
]
=
(
unsigned
char
)
byte_value
;
DBUG_PRINT
(
"info"
,
(
"
str
_to_ipv4(%.*s): valid IPv4 address: %d.%d.%d.%d"
,
DBUG_PRINT
(
"info"
,
(
"
ascii
_to_ipv4(%.*s): valid IPv4 address: %d.%d.%d.%d"
,
(
int
)
str_length
,
str
,
ipv4_bytes
[
0
],
ipv4_bytes
[
1
],
ipv4_bytes
[
2
],
ipv4_bytes
[
3
]));
...
...
@@ -468,20 +502,18 @@ bool Inet4::str_to_ipv4(const char *str, size_t str_length, CHARSET_INFO *cs)
IPv4-part differently on different platforms.
*/
bool
Inet6
::
str_to_ipv6
(
const
char
*
str
,
size_t
str_length
,
CHARSET_INFO
*
cs
)
bool
Inet6
::
ascii_to_ipv6
(
const
char
*
str
,
size_t
str_length
)
{
DBUG_ASSERT
(
cs
->
mbminlen
==
1
);
if
(
str_length
<
2
)
{
DBUG_PRINT
(
"error"
,
(
"
str
_to_ipv6(%.*s): invalid IPv6 address: too short."
,
DBUG_PRINT
(
"error"
,
(
"
ascii
_to_ipv6(%.*s): invalid IPv6 address: too short."
,
(
int
)
str_length
,
str
));
return
true
;
}
if
(
str_length
>
8
*
4
+
7
)
if
(
str_length
>
IN6_ADDR_MAX_CHAR_LENGTH
)
{
DBUG_PRINT
(
"error"
,
(
"
str
_to_ipv6(%.*s): invalid IPv6 address: too long."
,
DBUG_PRINT
(
"error"
,
(
"
ascii
_to_ipv6(%.*s): invalid IPv6 address: too long."
,
(
int
)
str_length
,
str
));
return
true
;
}
...
...
@@ -496,7 +528,7 @@ bool Inet6::str_to_ipv6(const char *str, size_t str_length, CHARSET_INFO *cs)
if
(
*
p
!=
':'
)
{
DBUG_PRINT
(
"error"
,
(
"
str
_to_ipv6(%.*s): invalid IPv6 address: "
DBUG_PRINT
(
"error"
,
(
"
ascii
_to_ipv6(%.*s): invalid IPv6 address: "
"can not start with ':x'."
,
(
int
)
str_length
,
str
));
return
true
;
}
...
...
@@ -522,7 +554,7 @@ bool Inet6::str_to_ipv6(const char *str, size_t str_length, CHARSET_INFO *cs)
{
if
(
gap_ptr
)
{
DBUG_PRINT
(
"error"
,
(
"
str
_to_ipv6(%.*s): invalid IPv6 address: "
DBUG_PRINT
(
"error"
,
(
"
ascii
_to_ipv6(%.*s): invalid IPv6 address: "
"too many gaps(::)."
,
(
int
)
str_length
,
str
));
return
true
;
}
...
...
@@ -533,14 +565,14 @@ bool Inet6::str_to_ipv6(const char *str, size_t str_length, CHARSET_INFO *cs)
if
(
!*
p
||
p
>=
str_end
)
{
DBUG_PRINT
(
"error"
,
(
"
str
_to_ipv6(%.*s): invalid IPv6 address: "
DBUG_PRINT
(
"error"
,
(
"
ascii
_to_ipv6(%.*s): invalid IPv6 address: "
"ending at ':'."
,
(
int
)
str_length
,
str
));
return
true
;
}
if
(
dst
+
2
>
ipv6_bytes_end
)
{
DBUG_PRINT
(
"error"
,
(
"
str
_to_ipv6(%.*s): invalid IPv6 address: "
DBUG_PRINT
(
"error"
,
(
"
ascii
_to_ipv6(%.*s): invalid IPv6 address: "
"too many groups (1)."
,
(
int
)
str_length
,
str
));
return
true
;
}
...
...
@@ -556,15 +588,16 @@ bool Inet6::str_to_ipv6(const char *str, size_t str_length, CHARSET_INFO *cs)
{
if
(
dst
+
IN_ADDR_SIZE
>
ipv6_bytes_end
)
{
DBUG_PRINT
(
"error"
,
(
"
str
_to_ipv6(%.*s): invalid IPv6 address: "
DBUG_PRINT
(
"error"
,
(
"
ascii
_to_ipv6(%.*s): invalid IPv6 address: "
"unexpected IPv4-part."
,
(
int
)
str_length
,
str
));
return
true
;
}
Inet4_null
tmp
(
group_start_ptr
,
(
size_t
)
(
str_end
-
group_start_ptr
),
cs
);
Inet4_null
tmp
(
group_start_ptr
,
(
size_t
)
(
str_end
-
group_start_ptr
),
&
my_charset_latin1
);
if
(
tmp
.
is_null
())
{
DBUG_PRINT
(
"error"
,
(
"
str
_to_ipv6(%.*s): invalid IPv6 address: "
DBUG_PRINT
(
"error"
,
(
"
ascii
_to_ipv6(%.*s): invalid IPv6 address: "
"invalid IPv4-part."
,
(
int
)
str_length
,
str
));
return
true
;
}
...
...
@@ -581,7 +614,7 @@ bool Inet6::str_to_ipv6(const char *str, size_t str_length, CHARSET_INFO *cs)
if
(
!
hdp
)
{
DBUG_PRINT
(
"error"
,
(
"
str
_to_ipv6(%.*s): invalid IPv6 address: "
DBUG_PRINT
(
"error"
,
(
"
ascii
_to_ipv6(%.*s): invalid IPv6 address: "
"invalid character at pos %d."
,
(
int
)
str_length
,
str
,
(
int
)
(
p
-
str
)));
return
true
;
...
...
@@ -589,7 +622,7 @@ bool Inet6::str_to_ipv6(const char *str, size_t str_length, CHARSET_INFO *cs)
if
(
chars_in_group
>=
4
)
{
DBUG_PRINT
(
"error"
,
(
"
str
_to_ipv6(%.*s): invalid IPv6 address: "
DBUG_PRINT
(
"error"
,
(
"
ascii
_to_ipv6(%.*s): invalid IPv6 address: "
"too many digits in group."
,
(
int
)
str_length
,
str
));
return
true
;
...
...
@@ -608,7 +641,7 @@ bool Inet6::str_to_ipv6(const char *str, size_t str_length, CHARSET_INFO *cs)
{
if
(
dst
+
2
>
ipv6_bytes_end
)
{
DBUG_PRINT
(
"error"
,
(
"
str
_to_ipv6(%.*s): invalid IPv6 address: "
DBUG_PRINT
(
"error"
,
(
"
ascii
_to_ipv6(%.*s): invalid IPv6 address: "
"too many groups (2)."
,
(
int
)
str_length
,
str
));
return
true
;
}
...
...
@@ -622,7 +655,7 @@ bool Inet6::str_to_ipv6(const char *str, size_t str_length, CHARSET_INFO *cs)
{
if
(
dst
==
ipv6_bytes_end
)
{
DBUG_PRINT
(
"error"
,
(
"
str
_to_ipv6(%.*s): invalid IPv6 address: "
DBUG_PRINT
(
"error"
,
(
"
ascii
_to_ipv6(%.*s): invalid IPv6 address: "
"no room for a gap (::)."
,
(
int
)
str_length
,
str
));
return
true
;
}
...
...
@@ -640,7 +673,7 @@ bool Inet6::str_to_ipv6(const char *str, size_t str_length, CHARSET_INFO *cs)
if
(
dst
<
ipv6_bytes_end
)
{
DBUG_PRINT
(
"error"
,
(
"
str
_to_ipv6(%.*s): invalid IPv6 address: "
DBUG_PRINT
(
"error"
,
(
"
ascii
_to_ipv6(%.*s): invalid IPv6 address: "
"too few groups."
,
(
int
)
str_length
,
str
));
return
true
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment