summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarc Gilleron <marc.gilleron@gmail.com>2021-01-07 01:05:12 +0000
committerMarc Gilleron <marc.gilleron@gmail.com>2021-01-07 01:05:12 +0000
commitfb71edd45b2473bf0ac502c777a1850fb564087e (patch)
tree5d7a48365313cd54a2a763efa85728c36cf7ed86 /src
parent43828ebb3931b9117ad57f08cc457e052fdfd631 (diff)
downloadredot-cpp-fb71edd45b2473bf0ac502c777a1850fb564087e.tar.gz
Fix container and string leaks
Some functions return a new instance of such containers, but instead we made a copy of them, without taking ownership of the original created by the function. Now we use a specific constructor taking ownership on the godot_* struct.
Diffstat (limited to 'src')
-rw-r--r--src/core/Array.cpp22
-rw-r--r--src/core/Dictionary.cpp12
-rw-r--r--src/core/NodePath.cpp12
-rw-r--r--src/core/String.cpp47
-rw-r--r--src/core/Variant.cpp53
5 files changed, 66 insertions, 80 deletions
diff --git a/src/core/Array.cpp b/src/core/Array.cpp
index 676eba5..04b4a3d 100644
--- a/src/core/Array.cpp
+++ b/src/core/Array.cpp
@@ -52,14 +52,16 @@ Array::Array(const PoolColorArray &a) {
Variant &Array::operator[](const int idx) {
godot_variant *v = godot::api->godot_array_operator_index(&_godot_array, idx);
- return *(Variant *)v;
+ // We assume it's ok to reinterpret because the value is a pointer whose data is already owned by the array,
+ // so can return a reference without constructing a Variant
+ return *reinterpret_cast<Variant *>(v);
}
-Variant Array::operator[](const int idx) const {
+const Variant &Array::operator[](const int idx) const {
// Yes, I'm casting away the const... you can hate me now.
// since the result is
godot_variant *v = godot::api->godot_array_operator_index((godot_array *)&_godot_array, idx);
- return *(Variant *)v;
+ return *reinterpret_cast<const Variant *>(v);
}
void Array::append(const Variant &v) {
@@ -84,12 +86,12 @@ void Array::erase(const Variant &v) {
Variant Array::front() const {
godot_variant v = godot::api->godot_array_front(&_godot_array);
- return *(Variant *)&v;
+ return Variant(v);
}
Variant Array::back() const {
godot_variant v = godot::api->godot_array_back(&_godot_array);
- return *(Variant *)&v;
+ return Variant(v);
}
int Array::find(const Variant &what, const int from) {
@@ -118,12 +120,12 @@ void Array::invert() {
Variant Array::pop_back() {
godot_variant v = godot::api->godot_array_pop_back(&_godot_array);
- return *(Variant *)&v;
+ return Variant(v);
}
Variant Array::pop_front() {
godot_variant v = godot::api->godot_array_pop_front(&_godot_array);
- return *(Variant *)&v;
+ return Variant(v);
}
void Array::push_back(const Variant &v) {
@@ -170,17 +172,17 @@ int Array::bsearch_custom(const Variant &value, const Object *obj,
Array Array::duplicate(const bool deep) const {
godot_array arr = godot::core_1_1_api->godot_array_duplicate(&_godot_array, deep);
- return *(Array *)&arr;
+ return Array(arr);
}
Variant Array::max() const {
godot_variant v = godot::core_1_1_api->godot_array_max(&_godot_array);
- return *(Variant *)&v;
+ return Variant(v);
}
Variant Array::min() const {
godot_variant v = godot::core_1_1_api->godot_array_min(&_godot_array);
- return *(Variant *)&v;
+ return Variant(v);
}
void Array::shuffle() {
diff --git a/src/core/Dictionary.cpp b/src/core/Dictionary.cpp
index 17f16a4..9c5be43 100644
--- a/src/core/Dictionary.cpp
+++ b/src/core/Dictionary.cpp
@@ -45,16 +45,18 @@ uint32_t Dictionary::hash() const {
Array Dictionary::keys() const {
godot_array a = godot::api->godot_dictionary_keys(&_godot_dictionary);
- return *(Array *)&a;
+ return Array(a);
}
Variant &Dictionary::operator[](const Variant &key) {
- return *(Variant *)godot::api->godot_dictionary_operator_index(&_godot_dictionary, (godot_variant *)&key);
+ godot_variant *v = godot::api->godot_dictionary_operator_index(&_godot_dictionary, (godot_variant *)&key);
+ return *reinterpret_cast<Variant *>(v);
}
const Variant &Dictionary::operator[](const Variant &key) const {
// oops I did it again
- return *(Variant *)godot::api->godot_dictionary_operator_index((godot_dictionary *)&_godot_dictionary, (godot_variant *)&key);
+ godot_variant *v = godot::api->godot_dictionary_operator_index((godot_dictionary *)&_godot_dictionary, (godot_variant *)&key);
+ return *reinterpret_cast<Variant *>(v);
}
int Dictionary::size() const {
@@ -63,12 +65,12 @@ int Dictionary::size() const {
String Dictionary::to_json() const {
godot_string s = godot::api->godot_dictionary_to_json(&_godot_dictionary);
- return *(String *)&s;
+ return String(s);
}
Array Dictionary::values() const {
godot_array a = godot::api->godot_dictionary_values(&_godot_dictionary);
- return *(Array *)&a;
+ return Array(a);
}
Dictionary::~Dictionary() {
diff --git a/src/core/NodePath.cpp b/src/core/NodePath.cpp
index 37ab2a3..bc069b7 100644
--- a/src/core/NodePath.cpp
+++ b/src/core/NodePath.cpp
@@ -27,8 +27,7 @@ NodePath::NodePath(const char *contents) {
String NodePath::get_name(const int idx) const {
godot_string str = godot::api->godot_node_path_get_name(&_node_path, idx);
-
- return *(String *)&str;
+ return String(str);
}
int NodePath::get_name_count() const {
@@ -37,7 +36,7 @@ int NodePath::get_name_count() const {
String NodePath::get_subname(const int idx) const {
godot_string str = godot::api->godot_node_path_get_subname(&_node_path, idx);
- return *(String *)&str;
+ return String(str);
}
int NodePath::get_subname_count() const {
@@ -54,17 +53,16 @@ bool NodePath::is_empty() const {
NodePath NodePath::get_as_property_path() const {
godot_node_path path = godot::core_1_1_api->godot_node_path_get_as_property_path(&_node_path);
- return *(NodePath *)&path;
+ return NodePath(path);
}
String NodePath::get_concatenated_subnames() const {
godot_string str = godot::api->godot_node_path_get_concatenated_subnames(&_node_path);
- return *(String *)&str;
+ return String(str);
}
NodePath::operator String() const {
godot_string str = godot::api->godot_node_path_as_string(&_node_path);
-
- return *(String *)&str;
+ return String(str);
}
bool NodePath::operator==(const NodePath &other) {
diff --git a/src/core/String.cpp b/src/core/String.cpp
index 73573f7..552ebfe 100644
--- a/src/core/String.cpp
+++ b/src/core/String.cpp
@@ -195,8 +195,7 @@ bool String::begins_with_char_array(const char *p_char_array) const {
PoolStringArray String::bigrams() const {
godot_array arr = godot::api->godot_string_bigrams(&_godot_string);
-
- return *(Array *)&arr;
+ return Array(arr);
}
String String::c_escape() const {
@@ -329,7 +328,7 @@ bool String::matchn(String expr) const {
PoolByteArray String::md5_buffer() const {
godot_pool_byte_array arr = godot::api->godot_string_md5_buffer(&_godot_string);
- return *(PoolByteArray *)&arr;
+ return PoolByteArray(arr);
}
String String::md5_text() const {
@@ -382,8 +381,7 @@ String String::right(int position) const {
PoolByteArray String::sha256_buffer() const {
godot_pool_byte_array arr = godot::api->godot_string_sha256_buffer(&_godot_string);
-
- return *(PoolByteArray *)&arr;
+ return PoolByteArray(arr);
}
String String::sha256_text() const {
@@ -396,20 +394,19 @@ float String::similarity(String text) const {
PoolStringArray String::split(String divisor, bool allow_empty) const {
godot_array arr = godot::api->godot_string_split(&_godot_string, &divisor._godot_string);
-
- return *(Array *)&arr;
+ return Array(arr);
}
PoolIntArray String::split_ints(String divisor, bool allow_empty) const {
godot_array arr = godot::api->godot_string_split_floats(&_godot_string, &divisor._godot_string);
-
- return *(Array *)&arr;
+ return Array(arr);
}
PoolRealArray String::split_floats(String divisor, bool allow_empty) const {
+ // TODO The GDNative API returns godot_array, when according to the doc, it should have been godot_pool_real_array
godot_array arr = godot::api->godot_string_split_floats(&_godot_string, &divisor._godot_string);
-
- return *(Array *)&arr;
+ Array wrapped_array(arr);
+ return PoolRealArray(wrapped_array);
}
String String::strip_edges(bool left, bool right) const {
@@ -457,33 +454,29 @@ signed char String::naturalnocasecmp_to(String p_str) const {
}
String String::dedent() const {
- String new_string;
- new_string._godot_string = godot::core_1_1_api->godot_string_dedent(&_godot_string);
- return new_string;
+ godot_string s = godot::core_1_1_api->godot_string_dedent(&_godot_string);
+ return String(s);
}
-PoolStringArray String::rsplit(const String &divisor, const bool allow_empty,
- const int maxsplit) const {
- godot_pool_string_array arr = godot::core_1_1_api->godot_string_rsplit(&_godot_string, &divisor._godot_string, allow_empty, maxsplit);
- return *(PoolStringArray *)&arr;
+PoolStringArray String::rsplit(const String &divisor, const bool allow_empty, const int maxsplit) const {
+ godot_pool_string_array arr =
+ godot::core_1_1_api->godot_string_rsplit(&_godot_string, &divisor._godot_string, allow_empty, maxsplit);
+ return PoolStringArray(arr);
}
String String::rstrip(const String &chars) const {
- String new_string;
- new_string._godot_string = godot::core_1_1_api->godot_string_rstrip(&_godot_string, &chars._godot_string);
- return new_string;
+ godot_string s = godot::core_1_1_api->godot_string_rstrip(&_godot_string, &chars._godot_string);
+ return String(s);
}
String String::trim_prefix(const String &prefix) const {
- String new_string;
- new_string._godot_string = godot::core_1_1_api->godot_string_trim_prefix(&_godot_string, &prefix._godot_string);
- return new_string;
+ godot_string s = godot::core_1_1_api->godot_string_trim_prefix(&_godot_string, &prefix._godot_string);
+ return String(s);
}
String String::trim_suffix(const String &suffix) const {
- String new_string;
- new_string._godot_string = godot::core_1_1_api->godot_string_trim_suffix(&_godot_string, &suffix._godot_string);
- return new_string;
+ godot_string s = godot::core_1_1_api->godot_string_trim_suffix(&_godot_string, &suffix._godot_string);
+ return String(s);
}
} // namespace godot
diff --git a/src/core/Variant.cpp b/src/core/Variant.cpp
index 86d2f91..9e3927f 100644
--- a/src/core/Variant.cpp
+++ b/src/core/Variant.cpp
@@ -205,9 +205,8 @@ Variant::operator double() const {
return godot::api->godot_variant_as_real(&_godot_variant);
}
Variant::operator String() const {
- String ret;
- *(godot_string *)&ret = godot::api->godot_variant_as_string(&_godot_variant);
- return ret;
+ godot_string s = godot::api->godot_variant_as_string(&_godot_variant);
+ return String(s);
}
Variant::operator Vector2() const {
godot_vector2 s = godot::api->godot_variant_as_vector2(&_godot_variant);
@@ -251,9 +250,8 @@ Variant::operator Color() const {
return *(Color *)&s;
}
Variant::operator NodePath() const {
- NodePath ret;
- *(godot_node_path *)&ret = godot::api->godot_variant_as_node_path(&_godot_variant);
- return ret;
+ godot_node_path ret = godot::api->godot_variant_as_node_path(&_godot_variant);
+ return NodePath(ret);
}
Variant::operator RID() const {
godot_rid s = godot::api->godot_variant_as_rid(&_godot_variant);
@@ -271,52 +269,45 @@ Variant::operator Array() const {
}
Variant::operator PoolByteArray() const {
- PoolByteArray ret;
- *(godot_pool_byte_array *)&ret = godot::api->godot_variant_as_pool_byte_array(&_godot_variant);
- return ret;
+ godot_pool_byte_array ret = godot::api->godot_variant_as_pool_byte_array(&_godot_variant);
+ return PoolByteArray(ret);
}
Variant::operator PoolIntArray() const {
- PoolIntArray ret;
- *(godot_pool_int_array *)&ret = godot::api->godot_variant_as_pool_int_array(&_godot_variant);
- return ret;
+ godot_pool_int_array ret = godot::api->godot_variant_as_pool_int_array(&_godot_variant);
+ return PoolIntArray(ret);
}
Variant::operator PoolRealArray() const {
- PoolRealArray ret;
- *(godot_pool_real_array *)&ret = godot::api->godot_variant_as_pool_real_array(&_godot_variant);
- return ret;
+ godot_pool_real_array ret = godot::api->godot_variant_as_pool_real_array(&_godot_variant);
+ return PoolRealArray(ret);
}
Variant::operator PoolStringArray() const {
- PoolStringArray ret;
- *(godot_pool_string_array *)&ret = godot::api->godot_variant_as_pool_string_array(&_godot_variant);
- return ret;
+ godot_pool_string_array ret = godot::api->godot_variant_as_pool_string_array(&_godot_variant);
+ return PoolStringArray(ret);
}
Variant::operator PoolVector2Array() const {
- PoolVector2Array ret;
- *(godot_pool_vector2_array *)&ret = godot::api->godot_variant_as_pool_vector2_array(&_godot_variant);
- return ret;
+ godot_pool_vector2_array ret = godot::api->godot_variant_as_pool_vector2_array(&_godot_variant);
+ return PoolVector2Array(ret);
}
Variant::operator PoolVector3Array() const {
- PoolVector3Array ret;
- *(godot_pool_vector3_array *)&ret = godot::api->godot_variant_as_pool_vector3_array(&_godot_variant);
- return ret;
+ godot_pool_vector3_array ret = godot::api->godot_variant_as_pool_vector3_array(&_godot_variant);
+ return PoolVector3Array(ret);
}
Variant::operator PoolColorArray() const {
- PoolColorArray ret;
- *(godot_pool_color_array *)&ret = godot::api->godot_variant_as_pool_color_array(&_godot_variant);
- return ret;
+ godot_pool_color_array ret = godot::api->godot_variant_as_pool_color_array(&_godot_variant);
+ return PoolColorArray(ret);
}
Variant::operator godot_object *() const {
return godot::api->godot_variant_as_object(&_godot_variant);
}
Variant::Type Variant::get_type() const {
- return (Type)godot::api->godot_variant_get_type(&_godot_variant);
+ return static_cast<Type>(godot::api->godot_variant_get_type(&_godot_variant));
}
Variant Variant::call(const String &method, const Variant **args, const int arg_count) {
- Variant v;
- *(godot_variant *)&v = godot::api->godot_variant_call(&_godot_variant, (godot_string *)&method, (const godot_variant **)args, arg_count, nullptr);
- return v;
+ godot_variant v = godot::api->godot_variant_call(
+ &_godot_variant, (godot_string *)&method, (const godot_variant **)args, arg_count, nullptr);
+ return Variant(v);
}
bool Variant::has_method(const String &method) {