mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2025-03-04 04:13:02 +01:00
Core: Add recursion level check for Array
and Dictionary
hashing
This commit is contained in:
parent
a96e650b7e
commit
254cb747b7
@ -31,9 +31,9 @@
|
|||||||
#include "array.h"
|
#include "array.h"
|
||||||
|
|
||||||
#include "core/containers/hashfuncs.h"
|
#include "core/containers/hashfuncs.h"
|
||||||
|
#include "core/containers/vector.h"
|
||||||
#include "core/object/object.h"
|
#include "core/object/object.h"
|
||||||
#include "core/variant/variant.h"
|
#include "core/variant/variant.h"
|
||||||
#include "core/containers/vector.h"
|
|
||||||
|
|
||||||
class ArrayPrivate {
|
class ArrayPrivate {
|
||||||
public:
|
public:
|
||||||
@ -117,16 +117,25 @@ bool Array::operator==(const Array &p_array) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Array::hash() const {
|
uint32_t Array::hash() const {
|
||||||
|
return recursive_hash(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Array::recursive_hash(int p_recursion_count) const {
|
||||||
|
ERR_FAIL_COND_V_MSG(p_recursion_count > MAX_RECURSION, 0, "Max recursion reached");
|
||||||
|
p_recursion_count++;
|
||||||
|
|
||||||
uint32_t h = hash_murmur3_one_32(0);
|
uint32_t h = hash_murmur3_one_32(0);
|
||||||
|
|
||||||
for (int i = 0; i < _p->array.size(); i++) {
|
for (int i = 0; i < _p->array.size(); i++) {
|
||||||
h = hash_murmur3_one_32(_p->array[i].hash(), h);
|
h = hash_murmur3_one_32(_p->array[i].recursive_hash(p_recursion_count), h);
|
||||||
}
|
}
|
||||||
return hash_fmix32(h);
|
return hash_fmix32(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Array::operator=(const Array &p_array) {
|
void Array::operator=(const Array &p_array) {
|
||||||
_ref(p_array);
|
_ref(p_array);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Array::push_back(const Variant &p_value) {
|
void Array::push_back(const Variant &p_value) {
|
||||||
_p->array.push_back(p_value);
|
_p->array.push_back(p_value);
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,7 @@ public:
|
|||||||
bool operator==(const Array &p_array) const;
|
bool operator==(const Array &p_array) const;
|
||||||
|
|
||||||
uint32_t hash() const;
|
uint32_t hash() const;
|
||||||
|
uint32_t recursive_hash(int p_recursion_count) const;
|
||||||
void operator=(const Array &p_array);
|
void operator=(const Array &p_array);
|
||||||
|
|
||||||
void push_back(const Variant &p_value);
|
void push_back(const Variant &p_value);
|
||||||
|
@ -221,12 +221,20 @@ void Dictionary::_unref() const {
|
|||||||
}
|
}
|
||||||
_p = nullptr;
|
_p = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Dictionary::hash() const {
|
uint32_t Dictionary::hash() const {
|
||||||
|
return recursive_hash(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Dictionary::recursive_hash(int p_recursion_count) const {
|
||||||
|
ERR_FAIL_COND_V_MSG(p_recursion_count > MAX_RECURSION, 0, "Max recursion reached");
|
||||||
|
p_recursion_count++;
|
||||||
|
|
||||||
uint32_t h = hash_murmur3_one_32(Variant::DICTIONARY);
|
uint32_t h = hash_murmur3_one_32(Variant::DICTIONARY);
|
||||||
|
|
||||||
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
|
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
|
||||||
h = hash_murmur3_one_32(E.key().hash(), h);
|
h = hash_murmur3_one_32(E.key().recursive_hash(p_recursion_count), h);
|
||||||
h = hash_murmur3_one_32(E.value().hash(), h);
|
h = hash_murmur3_one_32(E.value().recursive_hash(p_recursion_count), h);
|
||||||
}
|
}
|
||||||
|
|
||||||
return hash_fmix32(h);
|
return hash_fmix32(h);
|
||||||
|
@ -74,6 +74,7 @@ public:
|
|||||||
bool operator!=(const Dictionary &p_dictionary) const;
|
bool operator!=(const Dictionary &p_dictionary) const;
|
||||||
|
|
||||||
uint32_t hash() const;
|
uint32_t hash() const;
|
||||||
|
uint32_t recursive_hash(int p_recursion_count) const;
|
||||||
void operator=(const Dictionary &p_dictionary);
|
void operator=(const Dictionary &p_dictionary);
|
||||||
|
|
||||||
const Variant *next(const Variant *p_key = nullptr) const;
|
const Variant *next(const Variant *p_key = nullptr) const;
|
||||||
|
@ -3224,6 +3224,10 @@ Variant::~Variant() {
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
uint32_t Variant::hash() const {
|
uint32_t Variant::hash() const {
|
||||||
|
return recursive_hash(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Variant::recursive_hash(int p_recursion_count) const {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case NIL: {
|
case NIL: {
|
||||||
return 0;
|
return 0;
|
||||||
@ -3376,11 +3380,11 @@ uint32_t Variant::hash() const {
|
|||||||
return reinterpret_cast<const StringName *>(_data._mem)->hash();
|
return reinterpret_cast<const StringName *>(_data._mem)->hash();
|
||||||
} break;
|
} break;
|
||||||
case DICTIONARY: {
|
case DICTIONARY: {
|
||||||
return reinterpret_cast<const Dictionary *>(_data._mem)->hash();
|
return reinterpret_cast<const Dictionary *>(_data._mem)->recursive_hash(p_recursion_count);
|
||||||
} break;
|
} break;
|
||||||
case ARRAY: {
|
case ARRAY: {
|
||||||
const Array &arr = *reinterpret_cast<const Array *>(_data._mem);
|
const Array &arr = *reinterpret_cast<const Array *>(_data._mem);
|
||||||
return arr.hash();
|
return arr.recursive_hash(p_recursion_count);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case POOL_BYTE_ARRAY: {
|
case POOL_BYTE_ARRAY: {
|
||||||
|
@ -464,6 +464,7 @@ public:
|
|||||||
bool operator!=(const Variant &p_variant) const;
|
bool operator!=(const Variant &p_variant) const;
|
||||||
bool operator<(const Variant &p_variant) const;
|
bool operator<(const Variant &p_variant) const;
|
||||||
uint32_t hash() const;
|
uint32_t hash() const;
|
||||||
|
uint32_t recursive_hash(int p_recursion_count) const;
|
||||||
|
|
||||||
bool hash_compare(const Variant &p_variant) const;
|
bool hash_compare(const Variant &p_variant) const;
|
||||||
bool booleanize() const;
|
bool booleanize() const;
|
||||||
|
Loading…
Reference in New Issue
Block a user