Sfoglia il codice sorgente

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.
lawnjelly 3 anni fa
parent
commit
0565676893
5 ha cambiato i file con 33 aggiunte e 0 eliminazioni
  1. 22 0
      core/error/error_macros.h
  2. 3 0
      core/math/vector2.h
  3. 3 0
      core/math/vector2i.h
  4. 2 0
      core/math/vector3.h
  5. 3 0
      core/math/vector3i.h

+ 22 - 0
core/error/error_macros.h

@@ -194,6 +194,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)
@@ -208,6 +209,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)
@@ -296,6 +298,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)
@@ -310,6 +313,7 @@ void _err_flush_stdout();
 #define CRASH_BAD_UNSIGNED_INDEX_MSG(m_index, m_size, m_msg)                                                                 \
 	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_flush_stdout();                                                                                                 \
 		GENERATE_TRAP();                                                                                                     \
 	} else                                                                                                                   \
 		((void)0)
@@ -559,6 +563,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)
@@ -573,6 +578,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)
@@ -808,4 +814,20 @@ void _err_flush_stdout();
 	} else                                                                                           \
 		((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

+ 3 - 0
core/math/vector2.h

@@ -31,6 +31,7 @@
 #ifndef VECTOR2_H
 #define VECTOR2_H
 
+#include "core/error/error_macros.h"
 #include "core/math/math_funcs.h"
 
 class String;
@@ -60,9 +61,11 @@ struct _NO_DISCARD_ 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];
 	}
 

+ 3 - 0
core/math/vector2i.h

@@ -31,6 +31,7 @@
 #ifndef VECTOR2I_H
 #define VECTOR2I_H
 
+#include "core/error/error_macros.h"
 #include "core/math/math_funcs.h"
 
 class String;
@@ -58,9 +59,11 @@ struct _NO_DISCARD_ Vector2i {
 	};
 
 	_FORCE_INLINE_ int32_t &operator[](int p_idx) {
+		DEV_ASSERT((unsigned int)p_idx < 2);
 		return coord[p_idx];
 	}
 	_FORCE_INLINE_ const int32_t &operator[](int p_idx) const {
+		DEV_ASSERT((unsigned int)p_idx < 2);
 		return coord[p_idx];
 	}
 

+ 2 - 0
core/math/vector3.h

@@ -59,10 +59,12 @@ struct _NO_DISCARD_ Vector3 {
 	};
 
 	_FORCE_INLINE_ const real_t &operator[](const int p_axis) const {
+		DEV_ASSERT((unsigned int)p_axis < 3);
 		return coord[p_axis];
 	}
 
 	_FORCE_INLINE_ real_t &operator[](const int p_axis) {
+		DEV_ASSERT((unsigned int)p_axis < 3);
 		return coord[p_axis];
 	}
 

+ 3 - 0
core/math/vector3i.h

@@ -31,6 +31,7 @@
 #ifndef VECTOR3I_H
 #define VECTOR3I_H
 
+#include "core/error/error_macros.h"
 #include "core/math/math_funcs.h"
 
 class String;
@@ -54,10 +55,12 @@ struct _NO_DISCARD_ Vector3i {
 	};
 
 	_FORCE_INLINE_ const int32_t &operator[](const int p_axis) const {
+		DEV_ASSERT((unsigned int)p_axis < 3);
 		return coord[p_axis];
 	}
 
 	_FORCE_INLINE_ int32_t &operator[](const int p_axis) {
+		DEV_ASSERT((unsigned int)p_axis < 3);
 		return coord[p_axis];
 	}