Make Variant setget use set() method of Array

This ensure that typed arrays are properly checked when setting an
element.

Moved the macro to a straight declaration since the macro was only used
for Array and it now is quite specific to the Array class.
This commit is contained in:
George Marques 2021-03-09 12:30:42 -03:00
parent fbfdd5e110
commit 997a8ae9e8
No known key found for this signature in database
GPG Key ID: 046BD46A3201E43D

View File

@ -875,65 +875,64 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const {
static uint64_t get_indexed_size(const Variant *base) { return m_max; } \ static uint64_t get_indexed_size(const Variant *base) { return m_max; } \
}; };
#define INDEXED_SETGET_STRUCT_VARIANT(m_base_type) \ struct VariantIndexedSetGet_Array {
struct VariantIndexedSetGet_##m_base_type { \ static void get(const Variant *base, int64_t index, Variant *value, bool *oob) {
static void get(const Variant *base, int64_t index, Variant *value, bool *oob) { \ int64_t size = VariantGetInternalPtr<Array>::get_ptr(base)->size();
int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \ if (index < 0) {
if (index < 0) { \ index += size;
index += size; \ }
} \ if (index < 0 || index >= size) {
if (index < 0 || index >= size) { \ *oob = true;
*oob = true; \ return;
return; \ }
} \ *value = (*VariantGetInternalPtr<Array>::get_ptr(base))[index];
*value = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index]; \ *oob = false;
*oob = false; \ }
} \ static void ptr_get(const void *base, int64_t index, void *member) {
static void ptr_get(const void *base, int64_t index, void *member) { \ /* avoid ptrconvert for performance*/
/* avoid ptrconvert for performance*/ \ const Array &v = *reinterpret_cast<const Array *>(base);
const m_base_type &v = *reinterpret_cast<const m_base_type *>(base); \ if (index < 0)
if (index < 0) \ index += v.size();
index += v.size(); \ OOB_TEST(index, v.size());
OOB_TEST(index, v.size()); \ PtrToArg<Variant>::encode(v[index], member);
PtrToArg<Variant>::encode(v[index], member); \ }
} \ static void set(Variant *base, int64_t index, const Variant *value, bool *valid, bool *oob) {
static void set(Variant *base, int64_t index, const Variant *value, bool *valid, bool *oob) { \ int64_t size = VariantGetInternalPtr<Array>::get_ptr(base)->size();
int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \ if (index < 0) {
if (index < 0) { \ index += size;
index += size; \ }
} \ if (index < 0 || index >= size) {
if (index < 0 || index >= size) { \ *oob = true;
*oob = true; \ *valid = false;
*valid = false; \ return;
return; \ }
} \ VariantGetInternalPtr<Array>::get_ptr(base)->set(index, *value);
(*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index] = *value; \ *oob = false;
*oob = false; \ *valid = true;
*valid = true; \ }
} \ static void validated_set(Variant *base, int64_t index, const Variant *value, bool *oob) {
static void validated_set(Variant *base, int64_t index, const Variant *value, bool *oob) { \ int64_t size = VariantGetInternalPtr<Array>::get_ptr(base)->size();
int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \ if (index < 0) {
if (index < 0) { \ index += size;
index += size; \ }
} \ if (index < 0 || index >= size) {
if (index < 0 || index >= size) { \ *oob = true;
*oob = true; \ return;
return; \ }
} \ VariantGetInternalPtr<Array>::get_ptr(base)->set(index, *value);
(*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index] = *value; \ *oob = false;
*oob = false; \ }
} \ static void ptr_set(void *base, int64_t index, const void *member) {
static void ptr_set(void *base, int64_t index, const void *member) { \ /* avoid ptrconvert for performance*/
/* avoid ptrconvert for performance*/ \ Array &v = *reinterpret_cast<Array *>(base);
m_base_type &v = *reinterpret_cast<m_base_type *>(base); \ if (index < 0)
if (index < 0) \ index += v.size();
index += v.size(); \ OOB_TEST(index, v.size());
OOB_TEST(index, v.size()); \ v.set(index, PtrToArg<Variant>::convert(member));
v[index] = PtrToArg<Variant>::convert(member); \ }
} \ static Variant::Type get_index_type() { return Variant::NIL; }
static Variant::Type get_index_type() { return Variant::NIL; } \ static uint64_t get_indexed_size(const Variant *base) { return 0; }
static uint64_t get_indexed_size(const Variant *base) { return 0; } \ };
};
#define INDEXED_SETGET_STRUCT_DICT(m_base_type) \ #define INDEXED_SETGET_STRUCT_DICT(m_base_type) \
struct VariantIndexedSetGet_##m_base_type { \ struct VariantIndexedSetGet_##m_base_type { \
@ -990,7 +989,6 @@ INDEXED_SETGET_STRUCT_TYPED(PackedVector3Array, Vector3)
INDEXED_SETGET_STRUCT_TYPED(PackedStringArray, String) INDEXED_SETGET_STRUCT_TYPED(PackedStringArray, String)
INDEXED_SETGET_STRUCT_TYPED(PackedColorArray, Color) INDEXED_SETGET_STRUCT_TYPED(PackedColorArray, Color)
INDEXED_SETGET_STRUCT_VARIANT(Array)
INDEXED_SETGET_STRUCT_DICT(Dictionary) INDEXED_SETGET_STRUCT_DICT(Dictionary)
struct VariantIndexedSetterGetterInfo { struct VariantIndexedSetterGetterInfo {