From 0bcda22d7cc297919f839a8125172f8664883c9e Mon Sep 17 00:00:00 2001 From: lawnjelly Date: Tue, 22 Feb 2022 12:49:14 +0000 Subject: [PATCH] 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. --- core/error_macros.h | 11 ++++++++--- core/math/vector2.h | 4 ++++ core/math/vector3.h | 2 ++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/core/error_macros.h b/core/error_macros.h index cf540c3c332..379cc7d7cb0 100644 --- a/core/error_macros.h +++ b/core/error_macros.h @@ -208,6 +208,7 @@ void _err_flush_stdout(); #define CRASH_BAD_INDEX(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_flush_stdout(); \ GENERATE_TRAP \ } else \ ((void)0) @@ -221,6 +222,7 @@ void _err_flush_stdout(); #define CRASH_BAD_INDEX_MSG(m_index, m_size, m_msg) \ 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_flush_stdout(); \ GENERATE_TRAP \ } else \ ((void)0) @@ -234,6 +236,7 @@ void _err_flush_stdout(); #define CRASH_BAD_UNSIGNED_INDEX(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_flush_stdout(); \ GENERATE_TRAP \ } else \ ((void)0) @@ -305,6 +308,7 @@ void _err_flush_stdout(); #define CRASH_COND(m_cond) \ if (unlikely(m_cond)) { \ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition \"" _STR(m_cond) "\" is true."); \ + _err_flush_stdout(); \ GENERATE_TRAP \ } else \ ((void)0) @@ -316,6 +320,7 @@ void _err_flush_stdout(); #define CRASH_COND_MSG(m_cond, m_msg) \ if (unlikely(m_cond)) { \ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition \"" _STR(m_cond) "\" is true.", m_msg); \ + _err_flush_stdout(); \ GENERATE_TRAP \ } else \ ((void)0) @@ -427,7 +432,7 @@ void _err_flush_stdout(); #define CRASH_NOW() \ if (true) { \ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method failed."); \ - void _err_flush_stdout(); \ + _err_flush_stdout(); \ GENERATE_TRAP \ } else \ ((void)0) @@ -439,7 +444,7 @@ void _err_flush_stdout(); #define CRASH_NOW_MSG(m_msg) \ if (true) { \ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method failed.", m_msg); \ - void _err_flush_stdout(); \ + _err_flush_stdout(); \ GENERATE_TRAP \ } else \ ((void)0) @@ -523,7 +528,7 @@ void _err_flush_stdout(); #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."); \ - void _err_flush_stdout(); \ + _err_flush_stdout(); \ GENERATE_TRAP \ } else \ ((void)0) diff --git a/core/math/vector2.h b/core/math/vector2.h index b7b00e3b3ad..b8965a04093 100644 --- a/core/math/vector2.h +++ b/core/math/vector2.h @@ -60,9 +60,11 @@ struct _NO_DISCARD_CLASS_ Vector2 { }; _FORCE_INLINE_ real_t &operator[](int p_idx) { + DEV_ASSERT((unsigned int)p_idx < 2); return coord[p_idx]; } _FORCE_INLINE_ const real_t &operator[](int p_idx) const { + DEV_ASSERT((unsigned int)p_idx < 2); return coord[p_idx]; } @@ -291,9 +293,11 @@ struct _NO_DISCARD_CLASS_ Vector2i { }; _FORCE_INLINE_ int &operator[](int p_idx) { + DEV_ASSERT((unsigned int)p_idx < 2); return coord[p_idx]; } _FORCE_INLINE_ const int &operator[](int p_idx) const { + DEV_ASSERT((unsigned int)p_idx < 2); return coord[p_idx]; } diff --git a/core/math/vector3.h b/core/math/vector3.h index 4a9d379bb12..ade15e0b026 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -56,10 +56,12 @@ struct _NO_DISCARD_CLASS_ Vector3 { }; _FORCE_INLINE_ const real_t &operator[](int p_axis) const { + DEV_ASSERT((unsigned int)p_axis < 3); return coord[p_axis]; } _FORCE_INLINE_ real_t &operator[](int p_axis) { + DEV_ASSERT((unsigned int)p_axis < 3); return coord[p_axis]; }