summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/bind/core_bind.cpp3
-rw-r--r--core/image.cpp3
-rw-r--r--core/io/multiplayer_api.cpp1
-rw-r--r--core/io/packet_peer.cpp33
-rw-r--r--core/io/packet_peer.h6
-rw-r--r--core/io/pck_packer.cpp4
-rw-r--r--core/io/xml_parser.cpp8
-rw-r--r--core/io/zip_io.cpp1
-rw-r--r--core/object.cpp15
-rw-r--r--core/object.h4
10 files changed, 61 insertions, 17 deletions
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index 68650019a2..95f433607c 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -2773,8 +2773,9 @@ _Thread::_Thread() {
_Thread::~_Thread() {
- ERR_FAIL_COND_MSG(active, "Reference to a Thread object object was lost while the thread is still running...");
+ ERR_FAIL_COND_MSG(active, "Reference to a Thread object was lost while the thread is still running...");
}
+
/////////////////////////////////////
PoolStringArray _ClassDB::get_class_list() const {
diff --git a/core/image.cpp b/core/image.cpp
index 672f850a1f..18d0653bae 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -2027,8 +2027,7 @@ Rect2 Image::get_used_rect() const {
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
- bool opaque = get_pixel(i, j).a > 0.99;
- if (!opaque)
+ if (!(get_pixel(i, j).a > 0))
continue;
if (i > maxx)
maxx = i;
diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp
index 2708cb8c01..381ac4c0bb 100644
--- a/core/io/multiplayer_api.cpp
+++ b/core/io/multiplayer_api.cpp
@@ -111,6 +111,7 @@ void MultiplayerAPI::poll() {
Error err = network_peer->get_packet(&packet, len);
if (err != OK) {
ERR_PRINT("Error getting packet!");
+ break; // Something is wrong!
}
rpc_sender_id = sender;
diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp
index ae0520df6e..9e53d773ba 100644
--- a/core/io/packet_peer.cpp
+++ b/core/io/packet_peer.cpp
@@ -37,7 +37,8 @@
PacketPeer::PacketPeer() :
last_get_error(OK),
- allow_object_decoding(false) {
+ allow_object_decoding(false),
+ encode_buffer_max_size(8 * 1024 * 1024) {
}
void PacketPeer::set_allow_object_decoding(bool p_enable) {
@@ -50,6 +51,19 @@ bool PacketPeer::is_object_decoding_allowed() const {
return allow_object_decoding;
}
+void PacketPeer::set_encode_buffer_max_size(int p_max_size) {
+
+ ERR_FAIL_COND_MSG(p_max_size < 1024, "Max encode buffer must be at least 1024 bytes");
+ ERR_FAIL_COND_MSG(p_max_size > 256 * 1024 * 1024, "Max encode buffer cannot exceed 256 MiB");
+ encode_buffer_max_size = next_power_of_2(p_max_size);
+ encode_buffer.resize(0);
+}
+
+int PacketPeer::get_encode_buffer_max_size() const {
+
+ return encode_buffer_max_size;
+}
+
Error PacketPeer::get_packet_buffer(PoolVector<uint8_t> &r_buffer) {
const uint8_t *buffer;
@@ -100,12 +114,18 @@ Error PacketPeer::put_var(const Variant &p_packet, bool p_full_objects) {
if (len == 0)
return OK;
- uint8_t *buf = (uint8_t *)alloca(len);
- ERR_FAIL_COND_V_MSG(!buf, ERR_OUT_OF_MEMORY, "Out of memory.");
- err = encode_variant(p_packet, buf, len, p_full_objects || allow_object_decoding);
+ ERR_FAIL_COND_V_MSG(len > encode_buffer_max_size, ERR_OUT_OF_MEMORY, "Failed to encode variant, encode size is bigger then encode_buffer_max_size. Consider raising it via 'set_encode_buffer_max_size'.");
+
+ if (unlikely(encode_buffer.size() < len)) {
+ encode_buffer.resize(0); // Avoid realloc
+ encode_buffer.resize(next_power_of_2(len));
+ }
+
+ PoolVector<uint8_t>::Write w = encode_buffer.write();
+ err = encode_variant(p_packet, w.ptr(), len, p_full_objects || allow_object_decoding);
ERR_FAIL_COND_V_MSG(err != OK, err, "Error when trying to encode Variant.");
- return put_packet(buf, len);
+ return put_packet(w.ptr(), len);
}
Variant PacketPeer::_bnd_get_var(bool p_allow_objects) {
@@ -142,7 +162,10 @@ void PacketPeer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_allow_object_decoding", "enable"), &PacketPeer::set_allow_object_decoding);
ClassDB::bind_method(D_METHOD("is_object_decoding_allowed"), &PacketPeer::is_object_decoding_allowed);
+ ClassDB::bind_method(D_METHOD("get_encode_buffer_max_size"), &PacketPeer::get_encode_buffer_max_size);
+ ClassDB::bind_method(D_METHOD("set_encode_buffer_max_size", "max_size"), &PacketPeer::set_encode_buffer_max_size);
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "encode_buffer_max_size"), "set_encode_buffer_max_size", "get_encode_buffer_max_size");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_object_decoding"), "set_allow_object_decoding", "is_object_decoding_allowed");
};
diff --git a/core/io/packet_peer.h b/core/io/packet_peer.h
index f1870e8ef1..2b13f2e952 100644
--- a/core/io/packet_peer.h
+++ b/core/io/packet_peer.h
@@ -51,6 +51,9 @@ class PacketPeer : public Reference {
bool allow_object_decoding;
+ int encode_buffer_max_size;
+ PoolVector<uint8_t> encode_buffer;
+
public:
virtual int get_available_packet_count() const = 0;
virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size) = 0; ///< buffer is GONE after next get_packet
@@ -69,6 +72,9 @@ public:
void set_allow_object_decoding(bool p_enable);
bool is_object_decoding_allowed() const;
+ void set_encode_buffer_max_size(int p_max_size);
+ int get_encode_buffer_max_size() const;
+
PacketPeer();
~PacketPeer() {}
};
diff --git a/core/io/pck_packer.cpp b/core/io/pck_packer.cpp
index 8bc73103e9..fb83f0ac90 100644
--- a/core/io/pck_packer.cpp
+++ b/core/io/pck_packer.cpp
@@ -63,6 +63,10 @@ void PCKPacker::_bind_methods() {
Error PCKPacker::pck_start(const String &p_file, int p_alignment) {
+ if (file != NULL) {
+ memdelete(file);
+ }
+
file = FileAccess::open(p_file, FileAccess::WRITE);
ERR_FAIL_COND_V_MSG(!file, ERR_CANT_CREATE, "Can't open file to write: " + String(p_file) + ".");
diff --git a/core/io/xml_parser.cpp b/core/io/xml_parser.cpp
index 53e7da91a7..bd450dd84f 100644
--- a/core/io/xml_parser.cpp
+++ b/core/io/xml_parser.cpp
@@ -471,6 +471,10 @@ Error XMLParser::open_buffer(const Vector<uint8_t> &p_buffer) {
ERR_FAIL_COND_V(p_buffer.size() == 0, ERR_INVALID_DATA);
+ if (data) {
+ memdelete_arr(data);
+ }
+
length = p_buffer.size();
data = memnew_arr(char, length + 1);
copymem(data, p_buffer.ptr(), length);
@@ -489,6 +493,10 @@ Error XMLParser::open(const String &p_path) {
length = file->get_len();
ERR_FAIL_COND_V(length < 1, ERR_FILE_CORRUPT);
+ if (data) {
+ memdelete_arr(data);
+ }
+
data = memnew_arr(char, length + 1);
file->get_buffer((uint8_t *)data, length);
data[length] = 0;
diff --git a/core/io/zip_io.cpp b/core/io/zip_io.cpp
index 582b7c906b..40e902d874 100644
--- a/core/io/zip_io.cpp
+++ b/core/io/zip_io.cpp
@@ -97,6 +97,7 @@ int zipio_close(voidpf opaque, voidpf stream) {
FileAccess *&f = *(FileAccess **)opaque;
if (f) {
f->close();
+ memdelete(f);
f = NULL;
}
return 0;
diff --git a/core/object.cpp b/core/object.cpp
index 21666a334c..21a3b2cc6c 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -1213,9 +1213,9 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
MessageQueue::get_singleton()->push_call(target->get_instance_id(), c.method, args, argc, true);
} else {
Variant::CallError ce;
- s->lock++;
+ _emitting = true;
target->call(c.method, args, argc, ce);
- s->lock--;
+ _emitting = false;
if (ce.error != Variant::CallError::CALL_OK) {
#ifdef DEBUG_ENABLED
@@ -1920,6 +1920,7 @@ Object::Object() {
_instance_id = ObjectDB::add_instance(this);
_can_translate = true;
_is_queued_for_deletion = false;
+ _emitting = false;
instance_binding_count = 0;
memset(_script_instance_bindings, 0, sizeof(void *) * MAX_SCRIPT_INSTANCE_BINDINGS);
script_instance = NULL;
@@ -1942,15 +1943,15 @@ Object::~Object() {
const StringName *S = NULL;
+ if (_emitting) {
+ //@todo this may need to actually reach the debugger prioritarily somehow because it may crash before
+ ERR_PRINTS("Object " + to_string() + " was freed or unreferenced while a signal is being emitted from it. Try connecting to the signal using 'CONNECT_DEFERRED' flag, or use queue_free() to free the object (if this object is a Node) to avoid this error and potential crashes.");
+ }
+
while ((S = signal_map.next(NULL))) {
Signal *s = &signal_map[*S];
- if (s->lock > 0) {
- //@todo this may need to actually reach the debugger prioritarily somehow because it may crash before
- ERR_PRINTS("Object was freed or unreferenced while signal '" + String(*S) + "' is being emitted from it. Try connecting to the signal using 'CONNECT_DEFERRED' flag, or use queue_free() to free the object (if this object is a Node) to avoid this error and potential crashes.");
- }
-
//brute force disconnect for performance
int slot_count = s->slot_map.size();
const VMap<Signal::Target, Signal::Slot>::Pair *slot_list = s->slot_map.get_array();
diff --git a/core/object.h b/core/object.h
index ad1865da7b..865c155764 100644
--- a/core/object.h
+++ b/core/object.h
@@ -465,8 +465,7 @@ private:
MethodInfo user;
VMap<Target, Slot> slot_map;
- int lock;
- Signal() { lock = 0; }
+ Signal() {}
};
HashMap<StringName, Signal> signal_map;
@@ -481,6 +480,7 @@ private:
bool _predelete();
void _postinitialize();
bool _can_translate;
+ bool _emitting;
#ifdef TOOLS_ENABLED
bool _edited;
uint32_t _edited_version;