Simplify BinlogEvent::init/validate.

This commit is contained in:
levlam 2023-02-02 04:03:17 +03:00
parent 38b2fbe176
commit 0e58eeb5e9
3 changed files with 28 additions and 27 deletions

View File

@ -139,7 +139,8 @@ class BinlogReader {
} }
event->debug_info_ = BinlogDebugInfo{__FILE__, __LINE__}; event->debug_info_ = BinlogDebugInfo{__FILE__, __LINE__};
TRY_STATUS(event->init(input_->cut_head(size_).move_as_buffer_slice())); event->init(input_->cut_head(size_).move_as_buffer_slice());
TRY_STATUS(event->validate());
offset_ += size_; offset_ += size_;
event->offset_ = offset_; event->offset_ = offset_;
state_ = State::ReadLength; state_ = State::ReadLength;

View File

@ -14,26 +14,18 @@
namespace td { namespace td {
Status BinlogEvent::init(BufferSlice &&raw_event, bool check_crc) { void BinlogEvent::init(BufferSlice &&raw_event) {
TlParser parser(raw_event.as_slice()); TlParser parser(raw_event.as_slice());
size_ = parser.fetch_int(); size_ = static_cast<uint32>(parser.fetch_int());
LOG_CHECK(size_ == raw_event.size()) << size_ << " " << raw_event.size() << debug_info_; LOG_CHECK(size_ == raw_event.size()) << size_ << ' ' << raw_event.size() << debug_info_;
id_ = parser.fetch_long(); id_ = static_cast<uint64>(parser.fetch_long());
type_ = parser.fetch_int(); type_ = parser.fetch_int();
flags_ = parser.fetch_int(); flags_ = parser.fetch_int();
extra_ = parser.fetch_long(); extra_ = static_cast<uint64>(parser.fetch_long());
CHECK(size_ >= MIN_SIZE); CHECK(size_ >= MIN_SIZE);
parser.fetch_string_raw<Slice>(size_ - MIN_SIZE); // skip data parser.fetch_string_raw<Slice>(size_ - MIN_SIZE); // skip data
crc32_ = static_cast<uint32>(parser.fetch_int()); crc32_ = static_cast<uint32>(parser.fetch_int());
if (check_crc) {
auto calculated_crc = crc32(raw_event.as_slice().substr(0, size_ - TAIL_SIZE));
if (calculated_crc != crc32_) {
return Status::Error(PSLICE() << "crc mismatch " << tag("actual", format::as_hex(calculated_crc))
<< tag("expected", format::as_hex(crc32_)) << public_to_string());
}
}
raw_event_ = std::move(raw_event); raw_event_ = std::move(raw_event);
return Status::OK();
} }
Slice BinlogEvent::get_data() const { Slice BinlogEvent::get_data() const {
@ -41,15 +33,22 @@ Slice BinlogEvent::get_data() const {
} }
Status BinlogEvent::validate() const { Status BinlogEvent::validate() const {
BinlogEvent event; if (raw_event_.size() < MIN_SIZE) {
if (raw_event_.size() < 4) {
return Status::Error("Too small event"); return Status::Error("Too small event");
} }
uint32 size = TlParser(raw_event_.as_slice().substr(0, 4)).fetch_int(); TlParser parser(raw_event_.as_slice());
if (size_ != size) { uint32 size = static_cast<uint32>(parser.fetch_int());
if (size_ != size || size_ != raw_event_.size()) {
return Status::Error(PSLICE() << "Size of event changed: " << tag("was", size_) << tag("now", size)); return Status::Error(PSLICE() << "Size of event changed: " << tag("was", size_) << tag("now", size));
} }
return event.init(raw_event_.clone(), true); parser.fetch_string_raw<Slice>(size_ - TAIL_SIZE - sizeof(int)); // skip
auto stored_crc32 = static_cast<uint32>(parser.fetch_int());
auto calculated_crc = crc32(Slice(raw_event_.as_slice().data(), size_ - TAIL_SIZE));
if (calculated_crc != crc32_ || calculated_crc != stored_crc32) {
return Status::Error(PSLICE() << "CRC mismatch " << tag("actual", format::as_hex(calculated_crc))
<< tag("expected", format::as_hex(crc32_)) << public_to_string());
}
return Status::OK();
} }
BufferSlice BinlogEvent::create_raw(uint64 id, int32 type, int32 flags, const Storer &storer) { BufferSlice BinlogEvent::create_raw(uint64 id, int32 type, int32 flags, const Storer &storer) {

View File

@ -74,13 +74,16 @@ struct BinlogEvent {
void clear() { void clear() {
raw_event_ = BufferSlice(); raw_event_ = BufferSlice();
} }
bool empty() const { bool empty() const {
return raw_event_.empty(); return raw_event_.empty();
} }
BinlogEvent clone() const { BinlogEvent clone() const {
BinlogEvent result; BinlogEvent result;
result.debug_info_ = BinlogDebugInfo{__FILE__, __LINE__}; result.debug_info_ = BinlogDebugInfo{__FILE__, __LINE__};
result.init(raw_event_.clone()).ensure(); result.init(raw_event_.clone());
result.validate().ensure();
return result; return result;
} }
@ -89,16 +92,12 @@ struct BinlogEvent {
} }
BinlogEvent() = default; BinlogEvent() = default;
//explicit BinlogEvent(BufferSlice &&raw_event) {
//init(std::move(raw_event), false).ensure();
//}
BinlogEvent(BufferSlice &&raw_event, BinlogDebugInfo info) { BinlogEvent(BufferSlice &&raw_event, BinlogDebugInfo info) {
debug_info_ = info; debug_info_ = info;
init(std::move(raw_event), false).ensure(); init(std::move(raw_event));
} }
Status init(BufferSlice &&raw_event, bool check_crc = true) TD_WARN_UNUSED_RESULT;
static BufferSlice create_raw(uint64 id, int32 type, int32 flags, const Storer &storer); static BufferSlice create_raw(uint64 id, int32 type, int32 flags, const Storer &storer);
std::string public_to_string() const { std::string public_to_string() const {
@ -106,7 +105,9 @@ struct BinlogEvent {
<< tag("data", get_data().size()) << "]" << debug_info_; << tag("data", get_data().size()) << "]" << debug_info_;
} }
Status validate() const; void init(BufferSlice &&raw_event);
Status validate() const TD_WARN_UNUSED_RESULT;
void realloc(); void realloc();
}; };