mirror of
https://github.com/google/flatbuffers.git
synced 2026-07-02 18:58:17 +00:00
Fixed FlexBufferBuilder asserting on duplicate keys
This commit is contained in:
@@ -900,6 +900,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
BuilderFlag flags = BUILDER_FLAG_SHARE_KEYS)
|
BuilderFlag flags = BUILDER_FLAG_SHARE_KEYS)
|
||||||
: buf_(initial_size),
|
: buf_(initial_size),
|
||||||
finished_(false),
|
finished_(false),
|
||||||
|
has_duplicate_keys_(false),
|
||||||
flags_(flags),
|
flags_(flags),
|
||||||
force_min_bit_width_(BIT_WIDTH_8),
|
force_min_bit_width_(BIT_WIDTH_8),
|
||||||
key_pool(KeyOffsetCompare(buf_)),
|
key_pool(KeyOffsetCompare(buf_)),
|
||||||
@@ -1124,12 +1125,16 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
auto bs = reinterpret_cast<const char *>(
|
auto bs = reinterpret_cast<const char *>(
|
||||||
flatbuffers::vector_data(buf_) + b.key.u_);
|
flatbuffers::vector_data(buf_) + b.key.u_);
|
||||||
auto comp = strcmp(as, bs);
|
auto comp = strcmp(as, bs);
|
||||||
// If this assertion hits, you've added two keys with the same
|
// We want to disallow duplicate keys, since this results in a
|
||||||
// value to this map.
|
// 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
|
// TODO: Have to check for pointer equality, as some sort
|
||||||
// implementation apparently call this function with the same
|
// implementation apparently call this function with the same
|
||||||
// element?? Why?
|
// element?? Why?
|
||||||
FLATBUFFERS_ASSERT(comp || &a == &b);
|
if (!comp && &a != &b) has_duplicate_keys_ = true;
|
||||||
return comp < 0;
|
return comp < 0;
|
||||||
});
|
});
|
||||||
// First create a vector out of all keys.
|
// First create a vector out of all keys.
|
||||||
@@ -1143,6 +1148,10 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
return static_cast<size_t>(vec.u_);
|
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) {
|
template<typename F> size_t Vector(F f) {
|
||||||
auto start = StartVector();
|
auto start = StartVector();
|
||||||
f();
|
f();
|
||||||
@@ -1574,6 +1583,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
std::vector<Value> stack_;
|
std::vector<Value> stack_;
|
||||||
|
|
||||||
bool finished_;
|
bool finished_;
|
||||||
|
bool has_duplicate_keys_;
|
||||||
|
|
||||||
BuilderFlag flags_;
|
BuilderFlag flags_;
|
||||||
|
|
||||||
|
|||||||
@@ -2857,6 +2857,8 @@ CheckedError Parser::ParseFlexBufferValue(flexbuffers::Builder *builder) {
|
|||||||
});
|
});
|
||||||
ECHECK(err);
|
ECHECK(err);
|
||||||
builder->EndMap(start);
|
builder->EndMap(start);
|
||||||
|
if (builder->HasDuplicateKeys())
|
||||||
|
return Error("FlexBuffers map has duplicate keys");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case '[': {
|
case '[': {
|
||||||
|
|||||||
Reference in New Issue
Block a user