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