Jelajahi Sumber

Merge pull request #51068 from Faless/net/4.x_marshalls_recurse

[Net] Fix Marshalls infinite recursion crash.
Rémi Verschelde 4 tahun lalu
induk
melakukan
c27ef1565f
3 mengubah file dengan 16 tambahan dan 9 penghapusan
  1. 10 8
      core/io/marshalls.cpp
  2. 1 1
      core/io/marshalls.h
  3. 5 0
      core/variant/variant.h

+ 10 - 8
core/io/marshalls.cpp

@@ -1031,7 +1031,8 @@ static void _encode_string(const String &p_string, uint8_t *&buf, int &r_len) {
 	}
 }
 
-Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_full_objects) {
+Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_full_objects, int p_depth) {
+	ERR_FAIL_COND_V_MSG(p_depth > Variant::MAX_RECURSION_DEPTH, ERR_OUT_OF_MEMORY, "Potential inifite recursion detected. Bailing.");
 	uint8_t *buf = r_buffer;
 
 	r_len = 0;
@@ -1380,10 +1381,8 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
 						_encode_string(E.name, buf, r_len);
 
 						int len;
-						Error err = encode_variant(obj->get(E.name), buf, len, p_full_objects);
-						if (err) {
-							return err;
-						}
+						Error err = encode_variant(obj->get(E.name), buf, len, p_full_objects, p_depth + 1);
+						ERR_FAIL_COND_V(err, err);
 						ERR_FAIL_COND_V(len % 4, ERR_BUG);
 						r_len += len;
 						if (buf) {
@@ -1433,7 +1432,8 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
 					r_len++; //pad
 				*/
 				int len;
-				encode_variant(E, buf, len, p_full_objects);
+				Error err = encode_variant(E, buf, len, p_full_objects, p_depth + 1);
+				ERR_FAIL_COND_V(err, err);
 				ERR_FAIL_COND_V(len % 4, ERR_BUG);
 				r_len += len;
 				if (buf) {
@@ -1441,7 +1441,8 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
 				}
 				Variant *v = d.getptr(E);
 				ERR_FAIL_COND_V(!v, ERR_BUG);
-				encode_variant(*v, buf, len, p_full_objects);
+				err = encode_variant(*v, buf, len, p_full_objects, p_depth + 1);
+				ERR_FAIL_COND_V(err, err);
 				ERR_FAIL_COND_V(len % 4, ERR_BUG);
 				r_len += len;
 				if (buf) {
@@ -1462,7 +1463,8 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
 
 			for (int i = 0; i < v.size(); i++) {
 				int len;
-				encode_variant(v.get(i), buf, len, p_full_objects);
+				Error err = encode_variant(v.get(i), buf, len, p_full_objects, p_depth + 1);
+				ERR_FAIL_COND_V(err, err);
 				ERR_FAIL_COND_V(len % 4, ERR_BUG);
 				r_len += len;
 				if (buf) {

+ 1 - 1
core/io/marshalls.h

@@ -213,6 +213,6 @@ public:
 };
 
 Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len = nullptr, bool p_allow_objects = false);
-Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_full_objects = false);
+Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_full_objects = false, int p_depth = 0);
 
 #endif // MARSHALLS_H

+ 5 - 0
core/variant/variant.h

@@ -118,6 +118,11 @@ public:
 		VARIANT_MAX
 	};
 
+	enum {
+		// Maximum recursion depth allowed when serializing variants.
+		MAX_RECURSION_DEPTH = 1024,
+	};
+
 private:
 	friend struct _VariantCall;
 	friend class VariantInternal;