Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions include/envoy/json/json_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,13 @@ class Object {
virtual double getDouble(const std::string& name, double default_value) const PURE;

/**
* @return a hash of the JSON object. This is a hash of each nested element in stable order.
* It does not consider white space that was originally in the parsed JSON.
* @return a hash of the JSON object.
* Per RFC 7159:
* An object is an unordered collection of zero or more name/value
* pairs, where a name is a string and a value is a string, number,
* boolean, null, object, or array.
* Objects with fields in different orders are equivalent and produce the same hash.
* It does not consider white space that was originally in the parsed JSON.
*/
virtual uint64_t hash() const PURE;

Expand Down
4 changes: 2 additions & 2 deletions source/common/json/json_loader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
#include <cstdint>
#include <fstream>
#include <limits>
#include <map>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>

#include "common/common/assert.h"
Expand Down Expand Up @@ -127,7 +127,7 @@ class Field : public Object {
bool boolean_value_;
double double_value_;
int64_t integer_value_;
std::unordered_map<std::string, FieldSharedPtr> object_value_;
std::map<std::string, FieldSharedPtr> object_value_;
std::string string_value_;
};

Expand Down
2 changes: 1 addition & 1 deletion test/common/json/json_loader_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ TEST_F(JsonLoaderTest, Hash) {
ObjectSharedPtr json1 = Factory::loadFromString("{\"value1\": 10.5, \"value2\": -12.3}");
ObjectSharedPtr json2 = Factory::loadFromString("{\"value2\": -12.3, \"value1\": 10.5}");
ObjectSharedPtr json3 = Factory::loadFromString(" { \"value2\": -12.3, \"value1\": 10.5} ");
EXPECT_NE(json1->hash(), json2->hash());
EXPECT_EQ(json1->hash(), json2->hash());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these tests be stricter and verify that the hash has a specific value?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could to make it v strict, though changing the underlying container/hash algorithm changes could make this test brittle and require repeated changes

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed.

possible nit: there are no remaining EXPECT_NE for the hash function. It may make sense to add something like:

ObjectSharedPtr json4 = Factory::loadFromString("{"value1": 10.5}");
EXPECT_EQ(json1->hash(), json4->hash());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point! will add that test assertion

EXPECT_EQ(json2->hash(), json3->hash());
}

Expand Down