MySQL 9.0.0
Source Code Documentation
event_reader.h
Go to the documentation of this file.
1/* Copyright (c) 2018, 2024, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is designed to work with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have either included with
13 the program or referenced in the documentation.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24/**
25 @file event_reader.h
26
27 @brief Contains the class responsible for deserializing fields of an event
28 previously stored in a buffer.
29*/
30
31#ifndef MYSQL_BINLOG_EVENT_EVENT_READER_H
32#define MYSQL_BINLOG_EVENT_EVENT_READER_H
33
34#include <list>
35#include <map>
36#include <string>
37#include <vector>
40
41/// @addtogroup GroupLibsMysqlBinlogEvent
42/// @{
43
44namespace mysql::binlog::event {
45
46#define PRINT_READER_STATUS(message) \
47 BAPI_PRINT("debug", (message ": m_buffer= %p, " \
48 "m_limit= %llu, " \
49 "m_length= %llu, " \
50 "position()= %llu", \
51 m_buffer, m_limit, m_length, Event_reader::position()))
52
53/**
54 Event_reader class purpose is to avoid out-of-buffer reads when deserializing
55 binary log events and increase robustness when dealing with corrupted event
56 buffers.
57
58 The Event_reader is composed by a pointer to the beginning of the serialized
59 event buffer (m_buffer), a variable containing the buffer length (m_length), a
60 cursor pointer that tells the current position to be read from the buffer
61 (m_ptr) and the buffer limit the reader shall respect (m_limit <= m_length).
62
63 All buffer reading functions shall move the cursor forward.
64
65 Before reading from the buffer, the Event_reader will check if the amount of
66 bytes expected to be read are less or equal to the remaining bytes to read:
67
68 remaining = m_limit - (m_ptr - m_buffer)
69
70 When there are no enough bytes to read from the buffer, Event_reader enters
71 in error state, so its owner can take an action.
72*/
73
75 public:
76 /**
77 Event_reader constructor.
78
79 It sets the cursor to the first position of the buffer.
80
81 @param[in] buffer buffer holding a serialized event
82 @param[in] length known buffer length.
83 */
84 Event_reader(const char *buffer, unsigned long long length)
90
91 /**
92 Returns if the Event_reader is in an error state or not.
93
94 @retval true if the Event_reader is in error state.
95 @retval false if the Event_reader is not in error state.
96 */
97 bool has_error() {
98 BAPI_PRINT("debug", ("m_error= %s", m_error ? m_error : "nullptr"));
99 return m_error != nullptr;
100 }
101
102 /**
103 Returns the pointer to the error message.
104
105 @return the pointer to the error message when Event_reader is in error
106 state, or a nullptr otherwise.
107 */
108 const char *get_error() { return m_error; }
109
110 /**
111 Sets Event_reader error state by setting the error message.
112
113 @param[in] error pointer to the error message.
114 */
115 void set_error(const char *error);
116
117 /**
118 Returns the Event_reader buffer length.
119
120 Note: the buffer length might be larger than reader allowed buffer limit,
121 but the Event_reader will enter error state when trying to read above the
122 limit.
123
124 Example: an event buffer may contain the serialized event + checksum. The
125 event reader object will be configured with a buffer length that contains
126 both the serialized event and the checksum information, but once
127 Log_event_footer is instantiated, it shall adjust the event reader buffer
128 limit to the buffer position right before the checksum. This will avoid some
129 event deserialization relying on event buffer size to assume the checksum as
130 serialized event content.
131
132 @return the Event_reader buffer length.
133 */
134 unsigned long long length() { return (m_length); }
135
136 /**
137 Sets Event_reader buffer length and limit.
138
139 The length of the buffer should only be set to values greater or equal to
140 the current buffer length. Trying to set the length to less than current
141 buffer length will make the Event_buffer to enter error state.
142
143 The length is initially set in Event_reader constructor to
144 LOG_EVENT_MINIMAL_HEADER_LEN by the Log_event_header when instantiating it.
145 This should be enough to read the event header and determine the correct
146 buffer length. The Log_event_header will adjust the Event_reader length by
147 calling this function based on the value of event data_written header field.
148
149 @param[in] length the new Event_reader buffer length.
150 */
151 void set_length(unsigned long long length);
152
153 /**
154 Shrinks the Event_reader buffer limit.
155
156 This function is used by Log_event_footer to remove the checksum payload (if
157 necessary) from the serialized event size, as many event types rely on the
158 serialized event size to determine the size of some fields.
159
160 @param[in] bytes the amount of bytes to shrink the Event_reader buffer
161 length.
162 */
163 void shrink_limit(unsigned long long bytes);
164
165 /**
166 Returns the Event_reader buffer pointer.
167
168 @return the Event_reader buffer pointer.
169 */
170 const char *buffer() { return m_buffer; }
171
172 /**
173 Returns a pointer to the Event_reader cursor (next position to be read by
174 the Event_reader functions).
175
176 @return the pointer to the Event_reader cursor.
177 */
178 const char *ptr() { return m_ptr; }
179
180 /**
181 Returns a pointer to the Event_reader cursor (next position to be read) and
182 moves the cursor forward.
183
184 This function is used when the buffer contains a field of a known size and
185 the deserialization procedure must keep the pointer to the field but moving
186 the cursor to after it.
187
188 @param[in] length the amount of bytes to move the cursor forward.
189
190 @return the pointer to the Event_reader cursor before forwarding it.
191 */
192 const char *ptr(unsigned long long length);
193
194 /**
195 Returns the current Event_reader cursor position in bytes.
196
197 @retval m_limit if cursor position is invalid.
198 @retval position current Event_reader cursor position (if valid).
199 */
200 unsigned long long position() {
201 return m_ptr >= m_buffer ? m_ptr - m_buffer : m_limit;
202 }
203
204 /**
205 Returns the amount of bytes still available to read from cursor position.
206
207 @return the amount of bytes still available to read.
208 */
209 unsigned long long available_to_read() {
211 return m_limit - position();
212 }
213
214 /**
215 Returns if the Event_reader can read a given amount of bytes from cursor
216 position.
217
218 @param bytes the amount of bytes expected to be read.
219
220 @retval true if the Event_reader can read the specified amount of bytes.
221 @retval false if the Event_reader cannot read the specified amount of bytes.
222 */
223 bool can_read(unsigned long long bytes) {
224 return (available_to_read() >= bytes);
225 }
226
227 /**
228 Moves cursor to a given absolute buffer position and returns the pointer to
229 the cursor.
230
231 @param position the position to jump to.
232
233 @retval pointer a pointer to the new cursor position.
234 @retval nullptr if the position is out of buffer boundaries.
235 */
236 const char *go_to(unsigned long long position);
237
238 /**
239 Moves the buffer position forward to a given relative position and returns
240 the pointer to the buffer on the specified position.
241
242 @param bytes the amount of bytes to move forward.
243
244 @retval pointer a pointer to the new buffer position.
245 @retval nullptr if the cursor is out of buffer boundaries.
246 */
247 const char *forward(unsigned long long bytes) {
248 BAPI_PRINT("debug", ("Event_reader::forward(%llu)", bytes));
249 return go_to((m_ptr - m_buffer) + bytes);
250 }
251
252 /**
253 Copies a basic type - bool, char, int, long, double, etc - from the buffer,
254 moves the cursor forward the number of bytes returned by sizeof(T)) and
255 returns the copied value.
256
257 @retval value the T copied from the cursor position.
258 @retval 0 if the cursor was out of buffer boundaries.
259 */
260 template <class T>
261 T memcpy() {
262 PRINT_READER_STATUS("Event_reader::memcpy");
263 if (!can_read(sizeof(T))) {
264 set_error("Cannot read from out of buffer bounds");
265 BAPI_PRINT("debug", ("Event_reader::memcpy(): "
266 "sizeof()= %zu",
267 sizeof(T)));
268 return 0;
269 }
270 T value = 0;
271 ::memcpy((char *)&value, m_ptr, sizeof(T));
272 m_ptr = m_ptr + sizeof(T);
273 return value;
274 }
275
276 /**
277 Copies a basic arithmetic type - uint8_t, [u]int16_t, [u]int32_t,
278 [u]int64_t - from the buffer, moves the cursor forward using specified bytes
279 parameter (or the number of bytes returned by sizeof(T) when not specified)
280 and returns the copied value transformed from little endian if necessary).
281
282 @param[in] bytes the amount of bytes to read from the buffer (and to move
283 forward). When not specified, will use sizeof(T).
284
285 @retval value the T copied from the cursor position.
286 @retval 0 if the cursor was out of buffer boundaries or there was no memory
287 to allocate to the new string..
288 */
289 template <typename T>
290 T read(unsigned char bytes = sizeof(T)) {
291 PRINT_READER_STATUS("Event_reader::read");
292 if (!can_read(bytes)) {
293 set_error("Cannot read from out of buffer bounds");
294 BAPI_PRINT("debug", ("Event_reader::read(): "
295 "sizeof()= %zu, bytes= %u",
296 sizeof(T), bytes));
297 return 0;
298 }
299 T value = 0;
300 ::memcpy((char *)&value, m_ptr, bytes);
301 m_ptr = m_ptr + bytes;
302 return (bytes > 1) ? letoh(value) : value;
303 }
304
305 /**
306 Returns a pointer to a new string which is a duplicate of the input string.
307 The terminating null character is added. See: bapi_strndup().
308
309 @param[in] length the amount of bytes to read from the buffer (and to move
310 forward).
311
312 @retval pointer the T pointer from the cursor position.
313 @retval nullptr if the cursor was out of buffer boundaries.
314 */
315 template <typename T>
316 T strndup(size_t length) {
317 PRINT_READER_STATUS("Event_reader::strndup");
318 if (!can_read(length)) {
319 BAPI_PRINT("debug", ("Event_reader::strndup(%zu)", length));
320 set_error("Cannot read from out of buffer bounds");
321 return nullptr;
322 }
323 T str;
324 str = reinterpret_cast<T>(bapi_strndup(m_ptr, length));
325 m_ptr = m_ptr + length;
326 return str;
327 }
328
329 /**
330 Copies from the cursor to an already existent (and allocated) buffer and
331 moves forward the cursor.
332
333 @param[out] destination a pointer to the destination buffer.
334 @param[in] length the amount of bytes to read from the buffer (and to move
335 forward).
336 */
337 template <typename T>
338 void memcpy(T destination, size_t length) {
339 PRINT_READER_STATUS("Event_reader::memcpy");
340 if (!can_read(length)) {
341 BAPI_PRINT("debug", ("Event_reader::memcpy(%zu)", length));
342 set_error("Cannot read from out of buffer bounds");
343 return;
344 }
345 ::memcpy(destination, m_ptr, length);
346 m_ptr = m_ptr + length;
347 }
348
349 /**
350 Allocates memory to a destination buffer, copies from the cursor to the
351 destination buffer using memcpy() and moves forward the cursor.
352
353 This function is useful for pairs of fields when a first field describes the
354 second field size and the deserialization procedure must allocate a buffer
355 for the second field and then copy the event buffer content to the new
356 allocated buffer.
357
358 Before implementing this function and the Event_reader, the deserialization
359 process did like:
360
361 memcpy(length, ptr, sizeof(length);
362 ptr+=sizeof(length);
363 field = malloc(length);
364 memcpy(field, ptr, length);
365
366 Allocating the memory for the field before knowing if the content can be
367 read from the event buffer is a mistake, as it might allocate a very large
368 amount of memory that will not be used.
369
370 So, alloc_and_memcpy ensures that it will only allocate memory for the field
371 if it can be read from the event buffer, avoiding allocating a memory that
372 will not be used.
373
374 @param[out] destination the destination buffer.
375 @param[in] length the amount of bytes to allocate and read from the buffer
376 (and to move forward).
377 @param[in] flags flags to pass to MySQL server my_malloc() function.
378 */
379 void alloc_and_memcpy(unsigned char **destination, size_t length, int flags);
380
381 /**
382 Allocates memory to a destination buffer, copies from the cursor to the
383 destination buffer using strncpy() and moves forward the cursor.
384
385 See comments on alloc_and_memcpy() for more details.
386
387 @param[out] destination the destination buffer.
388 @param[in] length the amount of bytes to allocate and read from the buffer
389 (and to forward).
390 @param[in] flags flags to pass to MySQL server my_malloc() function.
391 */
392 void alloc_and_strncpy(char **destination, size_t length, int flags);
393
394 /**
395 Reads string from cursor.
396
397 Reads in the following format:
398 1) Reads length stored on cursor first index. Moves cursor forward 1 byte.
399 2) Set destination pointer to the cursor. Moves cursor forward length bytes.
400
401 @param[out] destination the destination pointer.
402 @param[out] length the amount of bytes to allocate and read from the buffer
403 (and to move forward).
404 */
405 void read_str_at_most_255_bytes(const char **destination, uint8_t *length);
406
407 /**
408 Reads a packed value.
409
410 This function can move the cursor forward by 1, 3, 4 or 9 bytes depending on
411 the value to be returned.
412
413 @return the packed value.
414 */
415 uint64_t net_field_length_ll();
416
417 /**
418 Reads a transaction context data set.
419
420 @param[in] set_len length of the set object (and to move forward).
421 @param[out] set pointer to the set object to be filled.
422 */
423 void read_data_set(uint32_t set_len, std::list<const char *> *set);
424
425 /**
426 Reads a view change certification map.
427
428 @param[in] map_len the length of the certification info map (and to move
429 forward).
430 @param[out] map the certification info map to be filled.
431 */
432 void read_data_map(uint32_t map_len, std::map<std::string, std::string> *map);
433
434 /**
435 Copy a string into the destination buffer up to a max length.
436
437 @param[out] destination the destination buffer.
438 @param[in] max_length the max length to copy from the cursor.
439 @param[in] dest_length the max length supported by the destination buffer.
440 */
441 void strncpyz(char *destination, size_t max_length, size_t dest_length);
442
443 /**
444 Fills a vector with a sequence of bytes from the cursor.
445
446 @param[out] destination the vector be filled.
447 @param[in] length the amount of bytes to read from the cursor (and to move
448 forward).
449 */
450 void assign(std::vector<uint8_t> *destination, size_t length);
451
452 private:
453 /* The buffer with the serialized binary log event */
454 const char *m_buffer;
455 /* The cursor: a pointer to the current read position in the buffer */
456 const char *m_ptr;
457 /* The length of the buffer */
458 unsigned long long m_length;
459 /* The limit the reader shall respect when reading from the buffer */
460 unsigned long long m_limit;
461 /* The pointer to the current error message, or nullptr */
462 const char *m_error;
463
464 /**
465 Wrapper to le16toh to be used by read function.
466
467 @param[in] value the value to be converted.
468
469 @return the converted value.
470 */
471 uint16_t letoh(uint16_t value) { return le16toh(value); }
472
473 /**
474 Wrapper to le32toh to be used by read function.
475
476 @param[in] value the value to be converted.
477
478 @return the converted value.
479 */
480 int32_t letoh(int32_t value) { return le32toh(value); }
481
482 /**
483 Wrapper to le32toh to be used by read function.
484
485 @param[in] value the value to be converted.
486
487 @return the converted value.
488 */
489 uint32_t letoh(uint32_t value) { return le32toh(value); }
490
491 /**
492 Wrapper to le64toh to be used by read function.
493
494 @param[in] value the value to be converted.
495
496 @return the converted value.
497 */
498 int64_t letoh(int64_t value) { return le64toh(value); }
499
500 /**
501 Wrapper to le64toh to be used by read function.
502
503 @param[in] value the value to be converted.
504
505 @return the converted value.
506 */
507 uint64_t letoh(uint64_t value) { return le64toh(value); }
508};
509} // end namespace mysql::binlog::event
510
511namespace [[deprecated]] binary_log {
512using namespace mysql::binlog::event;
513} // namespace binary_log
514
515/// @}
516
517#endif // MYSQL_BINLOG_EVENT_EVENT_READER_H
Kerberos Client Authentication nullptr
Definition: auth_kerberos_client_plugin.cc:251
uint64_t le64toh(uint64_t x)
Converting a 64 bit integer from little-endian byte order to host byteorder.
Definition: byte_order_helpers.h:50
Event_reader class purpose is to avoid out-of-buffer reads when deserializing binary log events and i...
Definition: event_reader.h:74
bool has_error()
Returns if the Event_reader is in an error state or not.
Definition: event_reader.h:97
Event_reader(const char *buffer, unsigned long long length)
Event_reader constructor.
Definition: event_reader.h:84
void set_error(const char *error)
Sets Event_reader error state by setting the error message.
Definition: event_reader.cpp:30
uint64_t net_field_length_ll()
Reads a packed value.
Definition: event_reader.cpp:137
uint16_t letoh(uint16_t value)
Wrapper to le16toh to be used by read function.
Definition: event_reader.h:471
unsigned long long position()
Returns the current Event_reader cursor position in bytes.
Definition: event_reader.h:200
const char * get_error()
Returns the pointer to the error message.
Definition: event_reader.h:108
unsigned long long m_length
Definition: event_reader.h:458
void assign(std::vector< uint8_t > *destination, size_t length)
Fills a vector with a sequence of bytes from the cursor.
Definition: event_reader.cpp:214
int32_t letoh(int32_t value)
Wrapper to le32toh to be used by read function.
Definition: event_reader.h:480
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 memc...
Definition: event_reader.cpp:78
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,...
Definition: event_reader.h:290
unsigned long long available_to_read()
Returns the amount of bytes still available to read from cursor position.
Definition: event_reader.h:209
unsigned long long length()
Returns the Event_reader buffer length.
Definition: event_reader.h:134
void read_data_set(uint32_t set_len, std::list< const char * > *set)
Reads a transaction context data set.
Definition: event_reader.cpp:160
const char * forward(unsigned long long bytes)
Moves the buffer position forward to a given relative position and returns the pointer to the buffer ...
Definition: event_reader.h:247
uint64_t letoh(uint64_t value)
Wrapper to le64toh to be used by read function.
Definition: event_reader.h:507
void set_length(unsigned long long length)
Sets Event_reader buffer length and limit.
Definition: event_reader.cpp:36
void memcpy(T destination, size_t length)
Copies from the cursor to an already existent (and allocated) buffer and moves forward the cursor.
Definition: event_reader.h:338
void strncpyz(char *destination, size_t max_length, size_t dest_length)
Copy a string into the destination buffer up to a max length.
Definition: event_reader.cpp:200
uint32_t letoh(uint32_t value)
Wrapper to le32toh to be used by read function.
Definition: event_reader.h:489
const char * m_buffer
Definition: event_reader.h:454
void read_data_map(uint32_t map_len, std::map< std::string, std::string > *map)
Reads a view change certification map.
Definition: event_reader.cpp:173
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 strn...
Definition: event_reader.cpp:97
T strndup(size_t length)
Returns a pointer to a new string which is a duplicate of the input string.
Definition: event_reader.h:316
unsigned long long m_limit
Definition: event_reader.h:460
void shrink_limit(unsigned long long bytes)
Shrinks the Event_reader buffer limit.
Definition: event_reader.cpp:46
bool can_read(unsigned long long bytes)
Returns if the Event_reader can read a given amount of bytes from cursor position.
Definition: event_reader.h:223
const char * buffer()
Returns the Event_reader buffer pointer.
Definition: event_reader.h:170
const char * ptr()
Returns a pointer to the Event_reader cursor (next position to be read by the Event_reader functions)...
Definition: event_reader.h:178
void read_str_at_most_255_bytes(const char **destination, uint8_t *length)
Reads string from cursor.
Definition: event_reader.cpp:117
int64_t letoh(int64_t value)
Wrapper to le64toh to be used by read function.
Definition: event_reader.h:498
T memcpy()
Copies a basic type - bool, char, int, long, double, etc - from the buffer, moves the cursor forward ...
Definition: event_reader.h:261
const char * go_to(unsigned long long position)
Moves cursor to a given absolute buffer position and returns the pointer to the cursor.
Definition: event_reader.cpp:67
const char * m_ptr
Definition: event_reader.h:456
const char * m_error
Definition: event_reader.h:462
#define PRINT_READER_STATUS(message)
Definition: event_reader.h:46
static int flags[50]
Definition: hp_test1.cc:40
The file contains functions to convert the byte encoding of integer values to and from little-endian ...
uint16_t le16toh(uint16_t x)
Converting a 16 bit integer from little-endian byte order to host byteorder.
Definition: byteorder.h:62
uint32_t le32toh(uint32_t x)
Converting a 32 bit integer from little-endian byte order to host byteorder.
Definition: byteorder.h:78
std::string str(const mysqlrouter::ConfigGenerator::Options::Endpoint &ep)
Definition: config_generator.cc:1081
Definition: base.h:75
The namespace contains classes representing events that can occur in a replication stream.
Definition: binlog_event.cpp:36
const char * bapi_strndup(const char *destination, size_t n)
This is a wrapper function, and returns a pointer to a new string which is a duplicate of the input s...
Definition: wrapper_functions.h:150
std::set< Key, Compare, ut::allocator< Key > > set
Specialization of set which uses ut_allocator.
Definition: ut0new.h:2883
std::map< Key, Value, Compare, ut::allocator< std::pair< const Key, Value > > > map
Specialization of map which uses ut_allocator.
Definition: ut0new.h:2893
Contains wrapper functions for memory allocation and deallocation.
#define BAPI_ASSERT(x)
Definition: wrapper_functions.h:61
#define BAPI_PRINT(name, params)
Definition: wrapper_functions.h:62