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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
b645b639
Commit
b645b639
authored
Oct 21, 2012
by
Nuno Carvalho
Browse files
Options
Browse Files
Download
Plain Diff
BUG#14629727: USER_VAR_EVENT IS MISSING RANGE CHECKS
Merge bundle on mysql-5.5.
parents
4828c75a
922792fd
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
86 additions
and
7 deletions
+86
-7
sql/log_event.cc
sql/log_event.cc
+40
-5
sql/log_event.h
sql/log_event.h
+2
-2
sql/sql_priv.h
sql/sql_priv.h
+44
-0
No files found.
sql/log_event.cc
View file @
b645b639
...
@@ -1299,7 +1299,7 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
...
@@ -1299,7 +1299,7 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
ev
=
new
Rand_log_event
(
buf
,
description_event
);
ev
=
new
Rand_log_event
(
buf
,
description_event
);
break
;
break
;
case
USER_VAR_EVENT
:
case
USER_VAR_EVENT
:
ev
=
new
User_var_log_event
(
buf
,
description_event
);
ev
=
new
User_var_log_event
(
buf
,
event_len
,
description_event
);
break
;
break
;
case
FORMAT_DESCRIPTION_EVENT
:
case
FORMAT_DESCRIPTION_EVENT
:
ev
=
new
Format_description_log_event
(
buf
,
event_len
,
description_event
);
ev
=
new
Format_description_log_event
(
buf
,
event_len
,
description_event
);
...
@@ -5812,19 +5812,35 @@ void User_var_log_event::pack_info(Protocol* protocol)
...
@@ -5812,19 +5812,35 @@ void User_var_log_event::pack_info(Protocol* protocol)
User_var_log_event
::
User_var_log_event
::
User_var_log_event
(
const
char
*
buf
,
User_var_log_event
(
const
char
*
buf
,
uint
event_len
,
const
Format_description_log_event
*
description_event
)
const
Format_description_log_event
*
description_event
)
:
Log_event
(
buf
,
description_event
)
:
Log_event
(
buf
,
description_event
)
#ifndef MYSQL_CLIENT
#ifndef MYSQL_CLIENT
,
deferred
(
false
)
,
deferred
(
false
)
#endif
#endif
{
{
bool
error
=
false
;
const
char
*
buf_start
=
buf
;
/* The Post-Header is empty. The Variable Data part begins immediately. */
/* The Post-Header is empty. The Variable Data part begins immediately. */
const
char
*
start
=
buf
;
const
char
*
start
=
buf
;
buf
+=
description_event
->
common_header_len
+
buf
+=
description_event
->
common_header_len
+
description_event
->
post_header_len
[
USER_VAR_EVENT
-
1
];
description_event
->
post_header_len
[
USER_VAR_EVENT
-
1
];
name_len
=
uint4korr
(
buf
);
name_len
=
uint4korr
(
buf
);
name
=
(
char
*
)
buf
+
UV_NAME_LEN_SIZE
;
name
=
(
char
*
)
buf
+
UV_NAME_LEN_SIZE
;
/*
We don't know yet is_null value, so we must assume that name_len
may have the bigger value possible, is_null= True and there is no
payload for val.
*/
if
(
0
==
name_len
||
!
valid_buffer_range
<
uint
>
(
name_len
,
buf_start
,
name
,
event_len
-
UV_VAL_IS_NULL
))
{
error
=
true
;
goto
err
;
}
buf
+=
UV_NAME_LEN_SIZE
+
name_len
;
buf
+=
UV_NAME_LEN_SIZE
+
name_len
;
is_null
=
(
bool
)
*
buf
;
is_null
=
(
bool
)
*
buf
;
flags
=
User_var_log_event
::
UNDEF_F
;
// defaults to UNDEF_F
flags
=
User_var_log_event
::
UNDEF_F
;
// defaults to UNDEF_F
...
@@ -5837,6 +5853,14 @@ User_var_log_event(const char* buf,
...
@@ -5837,6 +5853,14 @@ User_var_log_event(const char* buf,
}
}
else
else
{
{
if
(
!
valid_buffer_range
<
uint
>
(
UV_VAL_IS_NULL
+
UV_VAL_TYPE_SIZE
+
UV_CHARSET_NUMBER_SIZE
+
UV_VAL_LEN_SIZE
,
buf_start
,
buf
,
event_len
))
{
error
=
true
;
goto
err
;
}
type
=
(
Item_result
)
buf
[
UV_VAL_IS_NULL
];
type
=
(
Item_result
)
buf
[
UV_VAL_IS_NULL
];
charset_number
=
uint4korr
(
buf
+
UV_VAL_IS_NULL
+
UV_VAL_TYPE_SIZE
);
charset_number
=
uint4korr
(
buf
+
UV_VAL_IS_NULL
+
UV_VAL_TYPE_SIZE
);
val_len
=
uint4korr
(
buf
+
UV_VAL_IS_NULL
+
UV_VAL_TYPE_SIZE
+
val_len
=
uint4korr
(
buf
+
UV_VAL_IS_NULL
+
UV_VAL_TYPE_SIZE
+
...
@@ -5844,6 +5868,12 @@ User_var_log_event(const char* buf,
...
@@ -5844,6 +5868,12 @@ User_var_log_event(const char* buf,
val
=
(
char
*
)
(
buf
+
UV_VAL_IS_NULL
+
UV_VAL_TYPE_SIZE
+
val
=
(
char
*
)
(
buf
+
UV_VAL_IS_NULL
+
UV_VAL_TYPE_SIZE
+
UV_CHARSET_NUMBER_SIZE
+
UV_VAL_LEN_SIZE
);
UV_CHARSET_NUMBER_SIZE
+
UV_VAL_LEN_SIZE
);
if
(
!
valid_buffer_range
<
uint
>
(
val_len
,
buf_start
,
val
,
event_len
))
{
error
=
true
;
goto
err
;
}
/**
/**
We need to check if this is from an old server
We need to check if this is from an old server
that did not pack information for flags.
that did not pack information for flags.
...
@@ -5865,6 +5895,10 @@ User_var_log_event(const char* buf,
...
@@ -5865,6 +5895,10 @@ User_var_log_event(const char* buf,
val_len
);
val_len
);
}
}
}
}
err:
if
(
error
)
name
=
0
;
}
}
...
@@ -6014,8 +6048,9 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
...
@@ -6014,8 +6048,9 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
char
*
hex_str
;
char
*
hex_str
;
CHARSET_INFO
*
cs
;
CHARSET_INFO
*
cs
;
if
(
!
(
hex_str
=
(
char
*
)
my_alloca
(
2
*
val_len
+
1
+
2
)))
// 2 hex digits / byte
hex_str
=
(
char
*
)
my_malloc
(
2
*
val_len
+
1
+
2
,
MYF
(
MY_WME
));
// 2 hex digits / byte
break
;
// no error, as we are 'void'
if
(
!
hex_str
)
return
;
str_to_hex
(
hex_str
,
val
,
val_len
);
str_to_hex
(
hex_str
,
val
,
val_len
);
/*
/*
For proper behaviour when mysqlbinlog|mysql, we need to explicitely
For proper behaviour when mysqlbinlog|mysql, we need to explicitely
...
@@ -6033,7 +6068,7 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
...
@@ -6033,7 +6068,7 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
my_b_printf
(
&
cache
,
":=_%s %s COLLATE `%s`%s
\n
"
,
my_b_printf
(
&
cache
,
":=_%s %s COLLATE `%s`%s
\n
"
,
cs
->
csname
,
hex_str
,
cs
->
name
,
cs
->
csname
,
hex_str
,
cs
->
name
,
print_event_info
->
delimiter
);
print_event_info
->
delimiter
);
my_
a
free
(
hex_str
);
my_free
(
hex_str
);
}
}
break
;
break
;
case
ROW_RESULT
:
case
ROW_RESULT
:
...
...
sql/log_event.h
View file @
b645b639
...
@@ -2577,7 +2577,7 @@ public:
...
@@ -2577,7 +2577,7 @@ public:
void
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
);
void
print
(
FILE
*
file
,
PRINT_EVENT_INFO
*
print_event_info
);
#endif
#endif
User_var_log_event
(
const
char
*
buf
,
User_var_log_event
(
const
char
*
buf
,
uint
event_len
,
const
Format_description_log_event
*
description_event
);
const
Format_description_log_event
*
description_event
);
~
User_var_log_event
()
{}
~
User_var_log_event
()
{}
Log_event_type
get_type_code
()
{
return
USER_VAR_EVENT
;}
Log_event_type
get_type_code
()
{
return
USER_VAR_EVENT
;}
...
@@ -2591,7 +2591,7 @@ public:
...
@@ -2591,7 +2591,7 @@ public:
bool
is_deferred
()
{
return
deferred
;
}
bool
is_deferred
()
{
return
deferred
;
}
void
set_deferred
()
{
deferred
=
true
;
}
void
set_deferred
()
{
deferred
=
true
;
}
#endif
#endif
bool
is_valid
()
const
{
return
1
;
}
bool
is_valid
()
const
{
return
name
!=
0
;
}
private:
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
...
...
sql/sql_priv.h
View file @
b645b639
...
@@ -151,6 +151,50 @@
...
@@ -151,6 +151,50 @@
*/
*/
#define OPTION_ALLOW_BATCH (ULL(1) << 36) // THD, intern (slave)
#define OPTION_ALLOW_BATCH (ULL(1) << 36) // THD, intern (slave)
/*
Check how many bytes are available on buffer.
@param buf_start Pointer to buffer start.
@param buf_current Pointer to the current position on buffer.
@param buf_len Buffer length.
@return Number of bytes available on event buffer.
*/
template
<
class
T
>
T
available_buffer
(
const
char
*
buf_start
,
const
char
*
buf_current
,
T
buf_len
)
{
return
buf_len
-
(
buf_current
-
buf_start
);
}
/* Explicit instantion to unsigned int. */
template
unsigned
int
available_buffer
<
unsigned
int
>(
const
char
*
,
const
char
*
,
unsigned
int
);
/*
Check if jump value is within buffer limits.
@param jump Number of positions we want to advance.
@param buf_start Pointer to buffer start
@param buf_current Pointer to the current position on buffer.
@param buf_len Buffer length.
@return True If jump value is within buffer limits.
False Otherwise.
*/
template
<
class
T
>
bool
valid_buffer_range
(
T
jump
,
const
char
*
buf_start
,
const
char
*
buf_current
,
T
buf_len
)
{
return
(
jump
<=
available_buffer
(
buf_start
,
buf_current
,
buf_len
));
}
/* Explicit instantion to unsigned int. */
template
bool
valid_buffer_range
<
unsigned
int
>(
unsigned
int
,
const
char
*
,
const
char
*
,
unsigned
int
);
/* The rest of the file is included in the server only */
/* The rest of the file is included in the server only */
#ifndef MYSQL_CLIENT
#ifndef MYSQL_CLIENT
...
...
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