MySQL 9.1.0
Source Code Documentation
mysql::binlog::event::Event_reader Class Reference

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 >
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 >
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 >
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
 

Detailed Description

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.

Constructor & Destructor Documentation

◆ Event_reader()

mysql::binlog::event::Event_reader::Event_reader ( const char *  buffer,
unsigned long long  length 
)
inline

Event_reader constructor.

It sets the cursor to the first position of the buffer.

Parameters
[in]bufferbuffer holding a serialized event
[in]lengthknown buffer length.

Member Function Documentation

◆ alloc_and_memcpy()

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.

Parameters
[out]destinationthe destination buffer.
[in]lengththe amount of bytes to allocate and read from the buffer (and to move forward).
[in]flagsflags to pass to MySQL server my_malloc() function.

◆ alloc_and_strncpy()

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.

Parameters
[out]destinationthe destination buffer.
[in]lengththe amount of bytes to allocate and read from the buffer (and to forward).
[in]flagsflags to pass to MySQL server my_malloc() function.

◆ assign()

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.

Parameters
[out]destinationthe vector be filled.
[in]lengththe amount of bytes to read from the cursor (and to move forward).

◆ available_to_read()

unsigned long long mysql::binlog::event::Event_reader::available_to_read ( )
inline

Returns the amount of bytes still available to read from cursor position.

Returns
the amount of bytes still available to read.

◆ buffer()

const char * mysql::binlog::event::Event_reader::buffer ( )
inline

Returns the Event_reader buffer pointer.

Returns
the Event_reader buffer pointer.

◆ can_read()

bool mysql::binlog::event::Event_reader::can_read ( unsigned long long  bytes)
inline

Returns if the Event_reader can read a given amount of bytes from cursor position.

Parameters
bytesthe amount of bytes expected to be read.
Return values
trueif the Event_reader can read the specified amount of bytes.
falseif the Event_reader cannot read the specified amount of bytes.

◆ forward()

const char * mysql::binlog::event::Event_reader::forward ( unsigned long long  bytes)
inline

Moves the buffer position forward to a given relative position and returns the pointer to the buffer on the specified position.

Parameters
bytesthe amount of bytes to move forward.
Return values
pointera pointer to the new buffer position.
nullptrif the cursor is out of buffer boundaries.

◆ get_error()

const char * mysql::binlog::event::Event_reader::get_error ( )
inline

Returns the pointer to the error message.

Returns
the pointer to the error message when Event_reader is in error state, or a nullptr otherwise.

◆ go_to()

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.

Parameters
positionthe position to jump to.
Return values
pointera pointer to the new cursor position.
nullptrif the position is out of buffer boundaries.

◆ has_error()

bool mysql::binlog::event::Event_reader::has_error ( )
inline

Returns if the Event_reader is in an error state or not.

Return values
trueif the Event_reader is in error state.
falseif the Event_reader is not in error state.

◆ length()

unsigned long long mysql::binlog::event::Event_reader::length ( )
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.

Returns
the Event_reader buffer length.

◆ letoh() [1/5]

int32_t mysql::binlog::event::Event_reader::letoh ( int32_t  value)
inlineprivate

Wrapper to le32toh to be used by read function.

Parameters
[in]valuethe value to be converted.
Returns
the converted value.

◆ letoh() [2/5]

int64_t mysql::binlog::event::Event_reader::letoh ( int64_t  value)
inlineprivate

Wrapper to le64toh to be used by read function.

Parameters
[in]valuethe value to be converted.
Returns
the converted value.

◆ letoh() [3/5]

uint16_t mysql::binlog::event::Event_reader::letoh ( uint16_t  value)
inlineprivate

Wrapper to le16toh to be used by read function.

Parameters
[in]valuethe value to be converted.
Returns
the converted value.

◆ letoh() [4/5]

uint32_t mysql::binlog::event::Event_reader::letoh ( uint32_t  value)
inlineprivate

Wrapper to le32toh to be used by read function.

Parameters
[in]valuethe value to be converted.
Returns
the converted value.

◆ letoh() [5/5]

uint64_t mysql::binlog::event::Event_reader::letoh ( uint64_t  value)
inlineprivate

Wrapper to le64toh to be used by read function.

Parameters
[in]valuethe value to be converted.
Returns
the converted value.

◆ memcpy() [1/2]

template<class T >
T mysql::binlog::event::Event_reader::memcpy ( )
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.

Return values
valuethe T copied from the cursor position.
0if the cursor was out of buffer boundaries.

◆ memcpy() [2/2]

template<typename T >
void mysql::binlog::event::Event_reader::memcpy ( destination,
size_t  length 
)
inline

Copies from the cursor to an already existent (and allocated) buffer and moves forward the cursor.

Parameters
[out]destinationa pointer to the destination buffer.
[in]lengththe amount of bytes to read from the buffer (and to move forward).

◆ net_field_length_ll()

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.

Returns
the packed value.

◆ position()

unsigned long long mysql::binlog::event::Event_reader::position ( )
inline

Returns the current Event_reader cursor position in bytes.

Return values
m_limitif cursor position is invalid.
positioncurrent Event_reader cursor position (if valid).

◆ ptr() [1/2]

const char * mysql::binlog::event::Event_reader::ptr ( )
inline

Returns a pointer to the Event_reader cursor (next position to be read by the Event_reader functions).

Returns
the pointer to the Event_reader cursor.

◆ ptr() [2/2]

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.

Parameters
[in]lengththe amount of bytes to move the cursor forward.
Returns
the pointer to the Event_reader cursor before forwarding it.

◆ read()

template<typename T >
T mysql::binlog::event::Event_reader::read ( unsigned char  bytes = sizeof(T))
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).

Parameters
[in]bytesthe amount of bytes to read from the buffer (and to move forward). When not specified, will use sizeof(T).
Return values
valuethe T copied from the cursor position.
0if the cursor was out of buffer boundaries or there was no memory to allocate to the new string..

◆ read_data_map()

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.

Parameters
[in]map_lenthe length of the certification info map (and to move forward).
[out]mapthe certification info map to be filled.

◆ read_data_set()

void mysql::binlog::event::Event_reader::read_data_set ( uint32_t  set_len,
std::list< const char * > *  set 
)

Reads a transaction context data set.

Parameters
[in]set_lenlength of the set object (and to move forward).
[out]setpointer to the set object to be filled.

◆ read_str_at_most_255_bytes()

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.

Parameters
[out]destinationthe destination pointer.
[out]lengththe amount of bytes to allocate and read from the buffer (and to move forward).

◆ set_error()

void mysql::binlog::event::Event_reader::set_error ( const char *  error)

Sets Event_reader error state by setting the error message.

Parameters
[in]errorpointer to the error message.

◆ set_length()

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.

Parameters
[in]lengththe new Event_reader buffer length.

◆ shrink_limit()

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.

Parameters
[in]bytesthe amount of bytes to shrink the Event_reader buffer length.

◆ strncpyz()

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.

Parameters
[out]destinationthe destination buffer.
[in]max_lengththe max length to copy from the cursor.
[in]dest_lengththe max length supported by the destination buffer.

◆ strndup()

template<typename T >
T mysql::binlog::event::Event_reader::strndup ( size_t  length)
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().

Parameters
[in]lengththe amount of bytes to read from the buffer (and to move forward).
Return values
pointerthe T pointer from the cursor position.
nullptrif the cursor was out of buffer boundaries.

Member Data Documentation

◆ m_buffer

const char* mysql::binlog::event::Event_reader::m_buffer
private

◆ m_error

const char* mysql::binlog::event::Event_reader::m_error
private

◆ m_length

unsigned long long mysql::binlog::event::Event_reader::m_length
private

◆ m_limit

unsigned long long mysql::binlog::event::Event_reader::m_limit
private

◆ m_ptr

const char* mysql::binlog::event::Event_reader::m_ptr
private

The documentation for this class was generated from the following files: