Protection for array operator for Vector2 / 3 in DEV builds
A previous PR had changed the array operator to give unbounded access. This could cause crashes where old code depended on this previous safe behaviour. This PR adds DEV_ASSERT macros for out of bound access to DEV builds, allowing us to quickly identify bugs in calling code, without affecting performance in release or release_debug editor builds.
This commit is contained in:
parent
6c3170e875
commit
0565676893
5 changed files with 33 additions and 0 deletions
core
|
@ -194,6 +194,7 @@ void _err_flush_stdout();
|
||||||
#define CRASH_BAD_INDEX(m_index, m_size) \
|
#define CRASH_BAD_INDEX(m_index, m_size) \
|
||||||
if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
|
if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
|
||||||
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), "", true); \
|
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), "", true); \
|
||||||
|
_err_flush_stdout(); \
|
||||||
GENERATE_TRAP(); \
|
GENERATE_TRAP(); \
|
||||||
} else \
|
} else \
|
||||||
((void)0)
|
((void)0)
|
||||||
|
@ -208,6 +209,7 @@ void _err_flush_stdout();
|
||||||
#define CRASH_BAD_INDEX_MSG(m_index, m_size, m_msg) \
|
#define CRASH_BAD_INDEX_MSG(m_index, m_size, m_msg) \
|
||||||
if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
|
if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
|
||||||
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), m_msg, true); \
|
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), m_msg, true); \
|
||||||
|
_err_flush_stdout(); \
|
||||||
GENERATE_TRAP(); \
|
GENERATE_TRAP(); \
|
||||||
} else \
|
} else \
|
||||||
((void)0)
|
((void)0)
|
||||||
|
@ -296,6 +298,7 @@ void _err_flush_stdout();
|
||||||
#define CRASH_BAD_UNSIGNED_INDEX(m_index, m_size) \
|
#define CRASH_BAD_UNSIGNED_INDEX(m_index, m_size) \
|
||||||
if (unlikely((m_index) >= (m_size))) { \
|
if (unlikely((m_index) >= (m_size))) { \
|
||||||
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), "", true); \
|
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), "", true); \
|
||||||
|
_err_flush_stdout(); \
|
||||||
GENERATE_TRAP(); \
|
GENERATE_TRAP(); \
|
||||||
} else \
|
} else \
|
||||||
((void)0)
|
((void)0)
|
||||||
|
@ -310,6 +313,7 @@ void _err_flush_stdout();
|
||||||
#define CRASH_BAD_UNSIGNED_INDEX_MSG(m_index, m_size, m_msg) \
|
#define CRASH_BAD_UNSIGNED_INDEX_MSG(m_index, m_size, m_msg) \
|
||||||
if (unlikely((m_index) >= (m_size))) { \
|
if (unlikely((m_index) >= (m_size))) { \
|
||||||
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), m_msg, true); \
|
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), m_msg, true); \
|
||||||
|
_err_flush_stdout(); \
|
||||||
GENERATE_TRAP(); \
|
GENERATE_TRAP(); \
|
||||||
} else \
|
} else \
|
||||||
((void)0)
|
((void)0)
|
||||||
|
@ -559,6 +563,7 @@ void _err_flush_stdout();
|
||||||
#define CRASH_COND(m_cond) \
|
#define CRASH_COND(m_cond) \
|
||||||
if (unlikely(m_cond)) { \
|
if (unlikely(m_cond)) { \
|
||||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition \"" _STR(m_cond) "\" is true."); \
|
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition \"" _STR(m_cond) "\" is true."); \
|
||||||
|
_err_flush_stdout(); \
|
||||||
GENERATE_TRAP(); \
|
GENERATE_TRAP(); \
|
||||||
} else \
|
} else \
|
||||||
((void)0)
|
((void)0)
|
||||||
|
@ -573,6 +578,7 @@ void _err_flush_stdout();
|
||||||
#define CRASH_COND_MSG(m_cond, m_msg) \
|
#define CRASH_COND_MSG(m_cond, m_msg) \
|
||||||
if (unlikely(m_cond)) { \
|
if (unlikely(m_cond)) { \
|
||||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition \"" _STR(m_cond) "\" is true.", m_msg); \
|
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition \"" _STR(m_cond) "\" is true.", m_msg); \
|
||||||
|
_err_flush_stdout(); \
|
||||||
GENERATE_TRAP(); \
|
GENERATE_TRAP(); \
|
||||||
} else \
|
} else \
|
||||||
((void)0)
|
((void)0)
|
||||||
|
@ -808,4 +814,20 @@ void _err_flush_stdout();
|
||||||
} else \
|
} else \
|
||||||
((void)0)
|
((void)0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This should be a 'free' assert for program flow and should not be needed in any releases,
|
||||||
|
* only used in dev builds.
|
||||||
|
*/
|
||||||
|
#ifdef DEV_ENABLED
|
||||||
|
#define DEV_ASSERT(m_cond) \
|
||||||
|
if (unlikely(!(m_cond))) { \
|
||||||
|
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: DEV_ASSERT failed \"" _STR(m_cond) "\" is false."); \
|
||||||
|
_err_flush_stdout(); \
|
||||||
|
GENERATE_TRAP(); \
|
||||||
|
} else \
|
||||||
|
((void)0)
|
||||||
|
#else
|
||||||
|
#define DEV_ASSERT(m_cond)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // ERROR_MACROS_H
|
#endif // ERROR_MACROS_H
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#ifndef VECTOR2_H
|
#ifndef VECTOR2_H
|
||||||
#define VECTOR2_H
|
#define VECTOR2_H
|
||||||
|
|
||||||
|
#include "core/error/error_macros.h"
|
||||||
#include "core/math/math_funcs.h"
|
#include "core/math/math_funcs.h"
|
||||||
|
|
||||||
class String;
|
class String;
|
||||||
|
@ -60,9 +61,11 @@ struct _NO_DISCARD_ Vector2 {
|
||||||
};
|
};
|
||||||
|
|
||||||
_FORCE_INLINE_ real_t &operator[](int p_idx) {
|
_FORCE_INLINE_ real_t &operator[](int p_idx) {
|
||||||
|
DEV_ASSERT((unsigned int)p_idx < 2);
|
||||||
return coord[p_idx];
|
return coord[p_idx];
|
||||||
}
|
}
|
||||||
_FORCE_INLINE_ const real_t &operator[](int p_idx) const {
|
_FORCE_INLINE_ const real_t &operator[](int p_idx) const {
|
||||||
|
DEV_ASSERT((unsigned int)p_idx < 2);
|
||||||
return coord[p_idx];
|
return coord[p_idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#ifndef VECTOR2I_H
|
#ifndef VECTOR2I_H
|
||||||
#define VECTOR2I_H
|
#define VECTOR2I_H
|
||||||
|
|
||||||
|
#include "core/error/error_macros.h"
|
||||||
#include "core/math/math_funcs.h"
|
#include "core/math/math_funcs.h"
|
||||||
|
|
||||||
class String;
|
class String;
|
||||||
|
@ -58,9 +59,11 @@ struct _NO_DISCARD_ Vector2i {
|
||||||
};
|
};
|
||||||
|
|
||||||
_FORCE_INLINE_ int32_t &operator[](int p_idx) {
|
_FORCE_INLINE_ int32_t &operator[](int p_idx) {
|
||||||
|
DEV_ASSERT((unsigned int)p_idx < 2);
|
||||||
return coord[p_idx];
|
return coord[p_idx];
|
||||||
}
|
}
|
||||||
_FORCE_INLINE_ const int32_t &operator[](int p_idx) const {
|
_FORCE_INLINE_ const int32_t &operator[](int p_idx) const {
|
||||||
|
DEV_ASSERT((unsigned int)p_idx < 2);
|
||||||
return coord[p_idx];
|
return coord[p_idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,10 +59,12 @@ struct _NO_DISCARD_ Vector3 {
|
||||||
};
|
};
|
||||||
|
|
||||||
_FORCE_INLINE_ const real_t &operator[](const int p_axis) const {
|
_FORCE_INLINE_ const real_t &operator[](const int p_axis) const {
|
||||||
|
DEV_ASSERT((unsigned int)p_axis < 3);
|
||||||
return coord[p_axis];
|
return coord[p_axis];
|
||||||
}
|
}
|
||||||
|
|
||||||
_FORCE_INLINE_ real_t &operator[](const int p_axis) {
|
_FORCE_INLINE_ real_t &operator[](const int p_axis) {
|
||||||
|
DEV_ASSERT((unsigned int)p_axis < 3);
|
||||||
return coord[p_axis];
|
return coord[p_axis];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#ifndef VECTOR3I_H
|
#ifndef VECTOR3I_H
|
||||||
#define VECTOR3I_H
|
#define VECTOR3I_H
|
||||||
|
|
||||||
|
#include "core/error/error_macros.h"
|
||||||
#include "core/math/math_funcs.h"
|
#include "core/math/math_funcs.h"
|
||||||
|
|
||||||
class String;
|
class String;
|
||||||
|
@ -54,10 +55,12 @@ struct _NO_DISCARD_ Vector3i {
|
||||||
};
|
};
|
||||||
|
|
||||||
_FORCE_INLINE_ const int32_t &operator[](const int p_axis) const {
|
_FORCE_INLINE_ const int32_t &operator[](const int p_axis) const {
|
||||||
|
DEV_ASSERT((unsigned int)p_axis < 3);
|
||||||
return coord[p_axis];
|
return coord[p_axis];
|
||||||
}
|
}
|
||||||
|
|
||||||
_FORCE_INLINE_ int32_t &operator[](const int p_axis) {
|
_FORCE_INLINE_ int32_t &operator[](const int p_axis) {
|
||||||
|
DEV_ASSERT((unsigned int)p_axis < 3);
|
||||||
return coord[p_axis];
|
return coord[p_axis];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue