diff options
author | Tor Brede Vekterli <vekterli@yahooinc.com> | 2023-01-26 16:27:41 +0000 |
---|---|---|
committer | Tor Brede Vekterli <vekterli@yahooinc.com> | 2023-01-26 16:27:41 +0000 |
commit | 6f685d73523ed956efbc0ce85d1fb29f5a86e012 (patch) | |
tree | 28c3ffe5a84812b5256eb94cb9f9d6947e826a3e /document | |
parent | 48b902d4852bc63db8ec835a9dfccc2b1f8f89ec (diff) |
More document deserialization improvements
* Move field info reading before checking remaining buffer size,
as the serialized data size does not include the field info.
* Increment read cursor prior to using serialized annotation buffer,
thus preemptively triggering any OOB exceptions.
Diffstat (limited to 'document')
-rw-r--r-- | document/src/vespa/document/serialization/vespadocumentdeserializer.cpp | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/document/src/vespa/document/serialization/vespadocumentdeserializer.cpp b/document/src/vespa/document/serialization/vespadocumentdeserializer.cpp index 829cf9d306c..bbe4f5373cb 100644 --- a/document/src/vespa/document/serialization/vespadocumentdeserializer.cpp +++ b/document/src/vespa/document/serialization/vespadocumentdeserializer.cpp @@ -282,9 +282,9 @@ VespaDocumentDeserializer::read(StringFieldValue &value) { setValue(value, val, _stream.isLongLivedBuffer()); if (coding & 0x40) { uint32_t serializedAnnotationsSize = readValue<uint32_t>(_stream); - value.setSpanTrees(vespalib::ConstBufferRef(_stream.peek(), serializedAnnotationsSize), - _repo, _version, _stream.isLongLivedBuffer()); - _stream.adjustReadPos(serializedAnnotationsSize); + auto span_buf = vespalib::ConstBufferRef(_stream.peek(), serializedAnnotationsSize); + _stream.adjustReadPos(serializedAnnotationsSize); // Trigger any out-of-bounds before using buffer range. + value.setSpanTrees(span_buf, _repo, _version, _stream.isLongLivedBuffer()); } else { value.clearSpanTrees(); } @@ -359,11 +359,13 @@ VespaDocumentDeserializer::readStructNoReset(StructFieldValue &value) { if (is_compressed && (compression_type != CompressionConfig::LZ4)) [[unlikely]] { throw DeserializeException(fmt("Unsupported compression type: %u", static_cast<uint8_t>(compression_type)), VESPA_STRLOC); } + // Must read field info _prior_ to checking remaining stream size against + // data_size, as the field info size is not counted as part of data_size. + readFieldInfo(_stream, field_info, is_compressed ? uncompressed_size : data_size); if (data_size > _stream.size()) [[unlikely]] { throw DeserializeException(fmt("Struct size (%zu) is greater than remaining buffer size (%zu)", data_size, _stream.size()), VESPA_STRLOC); } - readFieldInfo(_stream, field_info, is_compressed ? uncompressed_size : data_size); if (data_size > 0) { ByteBuffer buffer = is_compressed ? deCompress(compression_type, uncompressed_size, ConstBufferRef(_stream.peek(), data_size)) |