Fixed FlexBufferBuilder asserting on duplicate keys

This commit is contained in:
Wouter van Oortmerssen
2020-11-23 09:02:40 -08:00
parent 100c59054c
commit bc518a5127
2 changed files with 15 additions and 3 deletions

View File

@@ -900,6 +900,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
BuilderFlag flags = BUILDER_FLAG_SHARE_KEYS)
: buf_(initial_size),
finished_(false),
has_duplicate_keys_(false),
flags_(flags),
force_min_bit_width_(BIT_WIDTH_8),
key_pool(KeyOffsetCompare(buf_)),
@@ -1124,12 +1125,16 @@ class Builder FLATBUFFERS_FINAL_CLASS {
auto bs = reinterpret_cast<const char *>(
flatbuffers::vector_data(buf_) + b.key.u_);
auto comp = strcmp(as, bs);
// If this assertion hits, you've added two keys with the same
// value to this map.
// We want to disallow duplicate keys, since this results in a
// map where values cannot be found.
// But we can't assert here (since we don't want to fail on
// random JSON input) or have an error mechanism.
// Instead, we set has_duplicate_keys_ in the builder to
// signal this.
// TODO: Have to check for pointer equality, as some sort
// implementation apparently call this function with the same
// element?? Why?
FLATBUFFERS_ASSERT(comp || &a == &b);
if (!comp && &a != &b) has_duplicate_keys_ = true;
return comp < 0;
});
// First create a vector out of all keys.
@@ -1143,6 +1148,10 @@ class Builder FLATBUFFERS_FINAL_CLASS {
return static_cast<size_t>(vec.u_);
}
// Call this after EndMap to see if the map had any duplicate keys.
// Any map with such keys won't be able to retrieve all values.
bool HasDuplicateKeys() const { return has_duplicate_keys_; }
template<typename F> size_t Vector(F f) {
auto start = StartVector();
f();
@@ -1574,6 +1583,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
std::vector<Value> stack_;
bool finished_;
bool has_duplicate_keys_;
BuilderFlag flags_;