aboutsummaryrefslogtreecommitdiffstats
path: root/document
diff options
context:
space:
mode:
authorTor Brede Vekterli <vekterli@yahooinc.com>2023-01-26 16:27:41 +0000
committerTor Brede Vekterli <vekterli@yahooinc.com>2023-01-26 16:27:41 +0000
commit6f685d73523ed956efbc0ce85d1fb29f5a86e012 (patch)
tree28c3ffe5a84812b5256eb94cb9f9d6947e826a3e /document
parent48b902d4852bc63db8ec835a9dfccc2b1f8f89ec (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.cpp10
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))