diff options
Diffstat (limited to 'thirdparty/tourist/trace/src/protocol.cpp')
| -rw-r--r-- | thirdparty/tourist/trace/src/protocol.cpp | 71 |
1 files changed, 48 insertions, 23 deletions
diff --git a/thirdparty/tourist/trace/src/protocol.cpp b/thirdparty/tourist/trace/src/protocol.cpp index 5297048ec..38868a127 100644 --- a/thirdparty/tourist/trace/src/protocol.cpp +++ b/thirdparty/tourist/trace/src/protocol.cpp @@ -28,7 +28,27 @@ Tuple<uint32, TypeDesc> TypeDesc::parse(BufferStream& stream) uint32 info_size = stream.read<uint16>(); const uint8* type_info = stream.read(info_size); + + // Validate that the declared field count and name lengths actually fit + // within info_size before patch() walks _fields[] and writes to it. + if (info_size < sizeof(Type)) + fatal("type info smaller than Type header"); + auto* type = (Type*)type_info; + uint32 field_count = type->get_field_count(); + uint64 required = sizeof(Type); + required += uint64(field_count) * sizeof(Type::Field); + required += type->_logger_name_len; + required += type->_event_name_len; + if (required > info_size) + fatal("type info too small for declared fields"); + for (uint32 i = 0; i < field_count; ++i) + { + required += type->_fields[i].name_size; + if (required > info_size) + fatal("type info too small for declared field names"); + } + type->patch(); uint32 uid = type->get_uid(); @@ -69,6 +89,11 @@ private: //------------------------------------------------------------------------------ void Types::parse(Buffer& buffer, Vector<const Type*>& new_types) { + // Pin the buffer up-front. TypeDesc::parse stores raw pointers into + // this buffer's slab in _descs; if a later type is malformed and + // throws, we still need the already-stored entries to remain valid. + _buffer_refs.push_back(buffer.create_ref()); + BufferStream stream = buffer.create_stream(); do { @@ -83,9 +108,6 @@ void Types::parse(Buffer& buffer, Vector<const Type*>& new_types) new_types.push_back(desc.type); } while (stream.has_data()); - - BufferRef buffer_ref = buffer.create_ref(); - _buffer_refs.push_back(std::move(buffer_ref)); } //------------------------------------------------------------------------------ @@ -466,22 +488,25 @@ void EventParser::parse_aux(const State& state) //------------------------------------------------------------------------------ Serial EventParser::parse_important_aux(const State& state) { - uint32 uid = state.stream.read<uint8>(); - - if (uid == 1) // AuxData + while (true) { - parse_aux(state); - return parse_important_aux(state); - } + uint32 uid = state.stream.read<uint8>(); - if (uid == 3) // AuxDataTerminal - { - _stage = -1; - return Serial(Serial::NO_SYNC); - } + if (uid == 1) // AuxData + { + parse_aux(state); + continue; + } - fatal("unsupported important sub-uid"); - return Serial(); + if (uid == 3) // AuxDataTerminal + { + _stage = -1; + return Serial(Serial::NO_SYNC); + } + + fatal("unsupported important sub-uid"); + return Serial(); + } } @@ -544,12 +569,12 @@ class ParserPool { public: EventParser& get_parser(uint32 index); - uint16 alloc_parser(); + uint32 alloc_parser(); void free_parser(uint32 index); private: Vector<EventParser> _parsers; - Vector<uint16> _frees; + Vector<uint32> _frees; }; //------------------------------------------------------------------------------ @@ -559,15 +584,15 @@ EventParser& ParserPool::get_parser(uint32 index) } //------------------------------------------------------------------------------ -uint16 ParserPool::alloc_parser() +uint32 ParserPool::alloc_parser() { if (_frees.empty()) { _parsers.emplace_back(); - return uint16(_parsers.size() - 1); + return uint32(_parsers.size() - 1); } - uint16 index = _frees.back(); + uint32 index = _frees.back(); _frees.pop_back(); return index; } @@ -576,7 +601,7 @@ uint16 ParserPool::alloc_parser() void ParserPool::free_parser(uint32 index) { _parsers[index] = EventParser(); - _frees.push_back(uint16(index)); + _frees.push_back(index); } @@ -598,7 +623,7 @@ private: { Serial serial; uint16 id; - uint16 parser_index; + uint32 parser_index; PacketNode* head = nullptr; PacketNode* tail = nullptr; }; |