MySQL 9.1.0
Source Code Documentation
|
Event_reader class purpose is to avoid out-of-buffer reads when deserializing binary log events and increase robustness when dealing with corrupted event buffers. More...
#include <event_reader.h>
Public Member Functions | |
Event_reader (const char *buffer, unsigned long long length) | |
Event_reader constructor. More... | |
bool | has_error () |
Returns if the Event_reader is in an error state or not. More... | |
const char * | get_error () |
Returns the pointer to the error message. More... | |
void | set_error (const char *error) |
Sets Event_reader error state by setting the error message. More... | |
unsigned long long | length () |
Returns the Event_reader buffer length. More... | |
void | set_length (unsigned long long length) |
Sets Event_reader buffer length and limit. More... | |
void | shrink_limit (unsigned long long bytes) |
Shrinks the Event_reader buffer limit. More... | |
const char * | buffer () |
Returns the Event_reader buffer pointer. More... | |
const char * | ptr () |
Returns a pointer to the Event_reader cursor (next position to be read by the Event_reader functions). More... | |
const char * | ptr (unsigned long long length) |
Returns a pointer to the Event_reader cursor (next position to be read) and moves the cursor forward. More... | |
unsigned long long | position () |
Returns the current Event_reader cursor position in bytes. More... | |
unsigned long long | available_to_read () |
Returns the amount of bytes still available to read from cursor position. More... | |
bool | can_read (unsigned long long bytes) |
Returns if the Event_reader can read a given amount of bytes from cursor position. More... | |
const char * | go_to (unsigned long long position) |
Moves cursor to a given absolute buffer position and returns the pointer to the cursor. More... | |
const char * | forward (unsigned long long bytes) |
Moves the buffer position forward to a given relative position and returns the pointer to the buffer on the specified position. More... | |
template<class T > | |
T | memcpy () |
Copies a basic type - bool, char, int, long, double, etc - from the buffer, moves the cursor forward the number of bytes returned by sizeof(T)) and returns the copied value. More... | |
template<typename T > | |
T | read (unsigned char bytes=sizeof(T)) |
Copies a basic arithmetic type - uint8_t, [u]int16_t, [u]int32_t, [u]int64_t - from the buffer, moves the cursor forward using specified bytes parameter (or the number of bytes returned by sizeof(T) when not specified) and returns the copied value transformed from little endian if necessary). More... | |
template<typename T > | |
T | strndup (size_t length) |
Returns a pointer to a new string which is a duplicate of the input string. More... | |
template<typename T > | |
void | memcpy (T destination, size_t length) |
Copies from the cursor to an already existent (and allocated) buffer and moves forward the cursor. More... | |
void | alloc_and_memcpy (unsigned char **destination, size_t length, int flags) |
Allocates memory to a destination buffer, copies from the cursor to the destination buffer using memcpy() and moves forward the cursor. More... | |
void | alloc_and_strncpy (char **destination, size_t length, int flags) |
Allocates memory to a destination buffer, copies from the cursor to the destination buffer using strncpy() and moves forward the cursor. More... | |
void | read_str_at_most_255_bytes (const char **destination, uint8_t *length) |
Reads string from cursor. More... | |
uint64_t | net_field_length_ll () |
Reads a packed value. More... | |
void | read_data_set (uint32_t set_len, std::list< const char * > *set) |
Reads a transaction context data set. More... | |
void | read_data_map (uint32_t map_len, std::map< std::string, std::string > *map) |
Reads a view change certification map. More... | |
void | strncpyz (char *destination, size_t max_length, size_t dest_length) |
Copy a string into the destination buffer up to a max length. More... | |
void | assign (std::vector< uint8_t > *destination, size_t length) |
Fills a vector with a sequence of bytes from the cursor. More... | |
Private Member Functions | |
uint16_t | letoh (uint16_t value) |
Wrapper to le16toh to be used by read function. More... | |
int32_t | letoh (int32_t value) |
Wrapper to le32toh to be used by read function. More... | |
uint32_t | letoh (uint32_t value) |
Wrapper to le32toh to be used by read function. More... | |
int64_t | letoh (int64_t value) |
Wrapper to le64toh to be used by read function. More... | |
uint64_t | letoh (uint64_t value) |
Wrapper to le64toh to be used by read function. More... | |
Private Attributes | |
const char * | m_buffer |
const char * | m_ptr |
unsigned long long | m_length |
unsigned long long | m_limit |
const char * | m_error |
Event_reader class purpose is to avoid out-of-buffer reads when deserializing binary log events and increase robustness when dealing with corrupted event buffers.
The Event_reader is composed by a pointer to the beginning of the serialized event buffer (m_buffer), a variable containing the buffer length (m_length), a cursor pointer that tells the current position to be read from the buffer (m_ptr) and the buffer limit the reader shall respect (m_limit <= m_length).
All buffer reading functions shall move the cursor forward.
Before reading from the buffer, the Event_reader will check if the amount of bytes expected to be read are less or equal to the remaining bytes to read:
remaining = m_limit - (m_ptr - m_buffer)
When there are no enough bytes to read from the buffer, Event_reader enters in error state, so its owner can take an action.
|
inline |
Event_reader constructor.
It sets the cursor to the first position of the buffer.
[in] | buffer | buffer holding a serialized event |
[in] | length | known buffer length. |
void mysql::binlog::event::Event_reader::alloc_and_memcpy | ( | unsigned char ** | destination, |
size_t | length, | ||
int | flags | ||
) |
Allocates memory to a destination buffer, copies from the cursor to the destination buffer using memcpy() and moves forward the cursor.
This function is useful for pairs of fields when a first field describes the second field size and the deserialization procedure must allocate a buffer for the second field and then copy the event buffer content to the new allocated buffer.
Before implementing this function and the Event_reader, the deserialization process did like:
memcpy(length, ptr, sizeof(length); ptr+=sizeof(length); field = malloc(length); memcpy(field, ptr, length);
Allocating the memory for the field before knowing if the content can be read from the event buffer is a mistake, as it might allocate a very large amount of memory that will not be used.
So, alloc_and_memcpy ensures that it will only allocate memory for the field if it can be read from the event buffer, avoiding allocating a memory that will not be used.
[out] | destination | the destination buffer. |
[in] | length | the amount of bytes to allocate and read from the buffer (and to move forward). |
[in] | flags | flags to pass to MySQL server my_malloc() function. |
void mysql::binlog::event::Event_reader::alloc_and_strncpy | ( | char ** | destination, |
size_t | length, | ||
int | flags | ||
) |
Allocates memory to a destination buffer, copies from the cursor to the destination buffer using strncpy() and moves forward the cursor.
See comments on alloc_and_memcpy() for more details.
[out] | destination | the destination buffer. |
[in] | length | the amount of bytes to allocate and read from the buffer (and to forward). |
[in] | flags | flags to pass to MySQL server my_malloc() function. |
void mysql::binlog::event::Event_reader::assign | ( | std::vector< uint8_t > * | destination, |
size_t | length | ||
) |
Fills a vector with a sequence of bytes from the cursor.
[out] | destination | the vector be filled. |
[in] | length | the amount of bytes to read from the cursor (and to move forward). |
|
inline |
Returns the amount of bytes still available to read from cursor position.
|
inline |
Returns the Event_reader buffer pointer.
|
inline |
Returns if the Event_reader can read a given amount of bytes from cursor position.
bytes | the amount of bytes expected to be read. |
true | if the Event_reader can read the specified amount of bytes. |
false | if the Event_reader cannot read the specified amount of bytes. |
|
inline |
Moves the buffer position forward to a given relative position and returns the pointer to the buffer on the specified position.
bytes | the amount of bytes to move forward. |
pointer | a pointer to the new buffer position. |
nullptr | if the cursor is out of buffer boundaries. |
|
inline |
Returns the pointer to the error message.
const char * mysql::binlog::event::Event_reader::go_to | ( | unsigned long long | position | ) |
Moves cursor to a given absolute buffer position and returns the pointer to the cursor.
position | the position to jump to. |
pointer | a pointer to the new cursor position. |
nullptr | if the position is out of buffer boundaries. |
|
inline |
Returns if the Event_reader is in an error state or not.
true | if the Event_reader is in error state. |
false | if the Event_reader is not in error state. |
|
inline |
Returns the Event_reader buffer length.
Note: the buffer length might be larger than reader allowed buffer limit, but the Event_reader will enter error state when trying to read above the limit.
Example: an event buffer may contain the serialized event + checksum. The event reader object will be configured with a buffer length that contains both the serialized event and the checksum information, but once Log_event_footer is instantiated, it shall adjust the event reader buffer limit to the buffer position right before the checksum. This will avoid some event deserialization relying on event buffer size to assume the checksum as serialized event content.
|
inlineprivate |
Wrapper to le32toh to be used by read function.
[in] | value | the value to be converted. |
|
inlineprivate |
Wrapper to le64toh to be used by read function.
[in] | value | the value to be converted. |
|
inlineprivate |
Wrapper to le16toh to be used by read function.
[in] | value | the value to be converted. |
|
inlineprivate |
Wrapper to le32toh to be used by read function.
[in] | value | the value to be converted. |
|
inlineprivate |
Wrapper to le64toh to be used by read function.
[in] | value | the value to be converted. |
|
inline |
Copies a basic type - bool, char, int, long, double, etc - from the buffer, moves the cursor forward the number of bytes returned by sizeof(T)) and returns the copied value.
value | the T copied from the cursor position. |
0 | if the cursor was out of buffer boundaries. |
|
inline |
Copies from the cursor to an already existent (and allocated) buffer and moves forward the cursor.
[out] | destination | a pointer to the destination buffer. |
[in] | length | the amount of bytes to read from the buffer (and to move forward). |
uint64_t mysql::binlog::event::Event_reader::net_field_length_ll | ( | ) |
Reads a packed value.
This function can move the cursor forward by 1, 3, 4 or 9 bytes depending on the value to be returned.
|
inline |
Returns the current Event_reader cursor position in bytes.
m_limit | if cursor position is invalid. |
position | current Event_reader cursor position (if valid). |
|
inline |
Returns a pointer to the Event_reader cursor (next position to be read by the Event_reader functions).
const char * mysql::binlog::event::Event_reader::ptr | ( | unsigned long long | length | ) |
Returns a pointer to the Event_reader cursor (next position to be read) and moves the cursor forward.
This function is used when the buffer contains a field of a known size and the deserialization procedure must keep the pointer to the field but moving the cursor to after it.
[in] | length | the amount of bytes to move the cursor forward. |
|
inline |
Copies a basic arithmetic type - uint8_t, [u]int16_t, [u]int32_t, [u]int64_t - from the buffer, moves the cursor forward using specified bytes parameter (or the number of bytes returned by sizeof(T) when not specified) and returns the copied value transformed from little endian if necessary).
[in] | bytes | the amount of bytes to read from the buffer (and to move forward). When not specified, will use sizeof(T). |
value | the T copied from the cursor position. |
0 | if the cursor was out of buffer boundaries or there was no memory to allocate to the new string.. |
void mysql::binlog::event::Event_reader::read_data_map | ( | uint32_t | map_len, |
std::map< std::string, std::string > * | map | ||
) |
Reads a view change certification map.
[in] | map_len | the length of the certification info map (and to move forward). |
[out] | map | the certification info map to be filled. |
void mysql::binlog::event::Event_reader::read_data_set | ( | uint32_t | set_len, |
std::list< const char * > * | set | ||
) |
Reads a transaction context data set.
[in] | set_len | length of the set object (and to move forward). |
[out] | set | pointer to the set object to be filled. |
void mysql::binlog::event::Event_reader::read_str_at_most_255_bytes | ( | const char ** | destination, |
uint8_t * | length | ||
) |
Reads string from cursor.
Reads in the following format: 1) Reads length stored on cursor first index. Moves cursor forward 1 byte. 2) Set destination pointer to the cursor. Moves cursor forward length bytes.
[out] | destination | the destination pointer. |
[out] | length | the amount of bytes to allocate and read from the buffer (and to move forward). |
void mysql::binlog::event::Event_reader::set_error | ( | const char * | error | ) |
Sets Event_reader error state by setting the error message.
[in] | error | pointer to the error message. |
void mysql::binlog::event::Event_reader::set_length | ( | unsigned long long | length | ) |
Sets Event_reader buffer length and limit.
The length of the buffer should only be set to values greater or equal to the current buffer length. Trying to set the length to less than current buffer length will make the Event_buffer to enter error state.
The length is initially set in Event_reader constructor to LOG_EVENT_MINIMAL_HEADER_LEN by the Log_event_header when instantiating it. This should be enough to read the event header and determine the correct buffer length. The Log_event_header will adjust the Event_reader length by calling this function based on the value of event data_written header field.
[in] | length | the new Event_reader buffer length. |
void mysql::binlog::event::Event_reader::shrink_limit | ( | unsigned long long | bytes | ) |
Shrinks the Event_reader buffer limit.
This function is used by Log_event_footer to remove the checksum payload (if necessary) from the serialized event size, as many event types rely on the serialized event size to determine the size of some fields.
[in] | bytes | the amount of bytes to shrink the Event_reader buffer length. |
void mysql::binlog::event::Event_reader::strncpyz | ( | char * | destination, |
size_t | max_length, | ||
size_t | dest_length | ||
) |
Copy a string into the destination buffer up to a max length.
[out] | destination | the destination buffer. |
[in] | max_length | the max length to copy from the cursor. |
[in] | dest_length | the max length supported by the destination buffer. |
|
inline |
Returns a pointer to a new string which is a duplicate of the input string.
The terminating null character is added. See: bapi_strndup().
[in] | length | the amount of bytes to read from the buffer (and to move forward). |
pointer | the T pointer from the cursor position. |
nullptr | if the cursor was out of buffer boundaries. |
|
private |
|
private |
|
private |
|
private |
|
private |