summaryrefslogtreecommitdiffstats
path: root/document
diff options
context:
space:
mode:
authorArne Juul <arnej@yahooinc.com>2023-01-11 21:05:30 +0000
committerArne Juul <arnej@yahooinc.com>2023-01-11 21:08:53 +0000
commita642ea5db84e936912bd175fe9599873c1ccf041 (patch)
tree43de815d7ca8abdc0f71e7dfa8a4e92037311e21 /document
parent65f655bac61810a39c964fb3eb72f35f0c0154fb (diff)
sanity check annotation data input
Diffstat (limited to 'document')
-rw-r--r--document/src/vespa/document/serialization/annotationdeserializer.cpp25
1 files changed, 21 insertions, 4 deletions
diff --git a/document/src/vespa/document/serialization/annotationdeserializer.cpp b/document/src/vespa/document/serialization/annotationdeserializer.cpp
index 9e7a35cfdcb..e3e3f81143f 100644
--- a/document/src/vespa/document/serialization/annotationdeserializer.cpp
+++ b/document/src/vespa/document/serialization/annotationdeserializer.cpp
@@ -9,6 +9,7 @@
#include <vespa/document/base/exceptions.h>
#include <vespa/document/fieldvalue/stringfieldvalue.h>
#include <vespa/document/repo/fixedtyperepo.h>
+#include <vespa/document/util/serializableexceptions.h>
#include <vespa/vespalib/objects/nbostream.h>
#include <vespa/log/log.h>
@@ -17,6 +18,11 @@ LOG_SETUP(".annotationdeserializer");
using std::unique_ptr;
namespace document {
+namespace {
+void fail(const char *message) {
+ throw DeserializeException(message);
+}
+}
AnnotationDeserializer::AnnotationDeserializer(const FixedTypeRepo &repo,
vespalib::nbostream &stream,
@@ -63,6 +69,7 @@ unique_ptr<SpanNode> AnnotationDeserializer::readSpanNode() {
node = readAlternateSpanList();
} else {
LOG(warning, "Cannot read SpanNode of type %u.", type);
+ fail("Annotation data contains SpanNode with bad type");
}
_nodes[node_index] = node.get();
return node;
@@ -102,10 +109,15 @@ void AnnotationDeserializer::readAnnotation(Annotation & annotation) {
uint32_t type_id = readValue<uint32_t>(_stream);
uint8_t features = readValue<uint8_t>(_stream);
uint32_t size = getInt1_2_4Bytes(_stream);
+ if (size > _stream.size()) {
+ LOG(warning, "Annotation of type %u claims size %u > available %zd", type_id, size, _stream.size());
+ fail("Annotation contains SpanNode with bad size");
+ return;
+ }
const AnnotationType *type = _repo.getAnnotationType(type_id);
if (!type) {
-// LOG(warning, "Skipping unknown annotation of type %u", type_id);
+ LOG(warning, "Skipping unknown annotation of type %u", type_id);
_stream.adjustReadPos(size);
return;
}
@@ -114,16 +126,21 @@ void AnnotationDeserializer::readAnnotation(Annotation & annotation) {
SpanNode *span_node = 0;
if (features & 1) { // has span node
uint32_t span_node_id = getInt1_2_4Bytes(_stream);
- span_node = _nodes[span_node_id];
+ if (span_node_id > _nodes.size()) {
+ LOG(warning, "Annotation of type %u has node_id %u > #nodes %zd", type_id, span_node_id, _nodes.size());
+ fail("Annotation refers to out-of-bounds span node");
+ } else {
+ span_node = _nodes[span_node_id];
+ }
}
if (features & 2) { // has value
uint32_t data_type_id = readValue<uint32_t>(_stream);
const DataType *data_type = type->getDataType();
if (!data_type) {
- LOG(warning, "Skipping payload (data type %d) for annotation type %s",
+ LOG(warning, "Bad data type %d for annotation type %s",
data_type_id, type->getName().c_str());
- _stream.adjustReadPos(size - sizeof(uint32_t));
+ fail("Annotation with bad datatype for its value");
} else {
FieldValue::UP value(data_type->createFieldValue());
VespaDocumentDeserializer deserializer(_repo, _stream, _version);