From 9ddb3265e1a6d2f9937ff6a27d04302d76c10431 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mikrut?= <mikrutrafal54@gmail.com>
Date: Fri, 1 Nov 2019 16:16:31 +0100
Subject: [PATCH] Fix some crashes, overflows and using variables without 
 values

---
 core/image.cpp                               |  5 +++--
 core/ustring.cpp                             |  5 +++++
 core/ustring.h                               |  1 +
 drivers/unix/file_access_unix.cpp            |  1 +
 main/main.cpp                                |  4 ++--
 modules/visual_script/visual_script.cpp      |  1 +
 scene/animation/animation_blend_space_1d.cpp |  1 +
 scene/animation/animation_blend_space_2d.cpp |  1 +
 scene/resources/ray_shape.cpp                | 10 ++++++++--
 scene/resources/visual_shader_nodes.cpp      |  1 +
 servers/visual_server.cpp                    | 11 +++++------
 11 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/core/image.cpp b/core/image.cpp
index 89d23b8dbda..74706535b35 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -1284,8 +1284,8 @@ static void _generate_po2_mipmap(const Component *p_src, Component *p_dst, uint3
 		Component *dst_ptr = &p_dst[i * dst_w * CC];
 		uint32_t count = dst_w;
 
-		while (count--) {
-
+		while (count) {
+			count--;
 			for (int j = 0; j < CC; j++) {
 				average_func(dst_ptr[j], rup_ptr[j], rup_ptr[j + right_step], rdown_ptr[j], rdown_ptr[j + right_step]);
 			}
@@ -1375,6 +1375,7 @@ void Image::shrink_x2() {
 		int ps = get_format_pixel_size(format);
 		new_img.resize((width / 2) * (height / 2) * ps);
 		ERR_FAIL_COND(new_img.size() == 0);
+		ERR_FAIL_COND(data.size() == 0);
 
 		{
 			PoolVector<uint8_t>::Write w = new_img.write();
diff --git a/core/ustring.cpp b/core/ustring.cpp
index f029ae42003..7ee2fee312f 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -4058,6 +4058,11 @@ String itos(int64_t p_val) {
 	return String::num_int64(p_val);
 }
 
+String uitos(uint64_t p_val) {
+
+	return String::num_uint64(p_val);
+}
+
 String rtos(double p_val) {
 
 	return String::num(p_val);
diff --git a/core/ustring.h b/core/ustring.h
index 15e2c07d9f9..dfc50449424 100644
--- a/core/ustring.h
+++ b/core/ustring.h
@@ -369,6 +369,7 @@ String operator+(const char *p_chr, const String &p_str);
 String operator+(CharType p_chr, const String &p_str);
 
 String itos(int64_t p_val);
+String uitos(uint64_t p_val);
 String rtos(double p_val);
 String rtoss(double p_val); //scientific version
 
diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp
index 99425d5002b..e3026f9fd96 100644
--- a/drivers/unix/file_access_unix.cpp
+++ b/drivers/unix/file_access_unix.cpp
@@ -275,6 +275,7 @@ void FileAccessUnix::store_8(uint8_t p_dest) {
 void FileAccessUnix::store_buffer(const uint8_t *p_src, int p_length) {
 
 	ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
+	ERR_FAIL_COND(!p_src);
 	ERR_FAIL_COND((int)fwrite(p_src, 1, p_length, f) != p_length);
 }
 
diff --git a/main/main.cpp b/main/main.cpp
index fe0f5a0215a..28c4ef7fbb9 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1348,8 +1348,8 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
 
 	ClassDB::set_current_api(ClassDB::API_NONE); //no more api is registered at this point
 
-	print_verbose("CORE API HASH: " + itos(ClassDB::get_api_hash(ClassDB::API_CORE)));
-	print_verbose("EDITOR API HASH: " + itos(ClassDB::get_api_hash(ClassDB::API_EDITOR)));
+	print_verbose("CORE API HASH: " + uitos(ClassDB::get_api_hash(ClassDB::API_CORE)));
+	print_verbose("EDITOR API HASH: " + uitos(ClassDB::get_api_hash(ClassDB::API_EDITOR)));
 	MAIN_PRINT("Main: Done");
 
 	return OK;
diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp
index 0cacd0f0b53..bb8612af6f6 100644
--- a/modules/visual_script/visual_script.cpp
+++ b/modules/visual_script/visual_script.cpp
@@ -1361,6 +1361,7 @@ void VisualScript::_bind_methods() {
 VisualScript::VisualScript() {
 
 	base_type = "Object";
+	is_tool_script = false;
 }
 
 StringName VisualScript::get_default_func() const {
diff --git a/scene/animation/animation_blend_space_1d.cpp b/scene/animation/animation_blend_space_1d.cpp
index 416a291da1c..7fe544eaab7 100644
--- a/scene/animation/animation_blend_space_1d.cpp
+++ b/scene/animation/animation_blend_space_1d.cpp
@@ -157,6 +157,7 @@ Ref<AnimationRootNode> AnimationNodeBlendSpace1D::get_blend_point_node(int p_poi
 void AnimationNodeBlendSpace1D::remove_blend_point(int p_point) {
 	ERR_FAIL_INDEX(p_point, blend_points_used);
 
+	ERR_FAIL_COND(blend_points[p_point].node.is_null());
 	blend_points[p_point].node->disconnect("tree_changed", this, "_tree_changed");
 
 	for (int i = p_point; i < blend_points_used - 1; i++) {
diff --git a/scene/animation/animation_blend_space_2d.cpp b/scene/animation/animation_blend_space_2d.cpp
index 75031f01497..b04eefbe31e 100644
--- a/scene/animation/animation_blend_space_2d.cpp
+++ b/scene/animation/animation_blend_space_2d.cpp
@@ -113,6 +113,7 @@ Ref<AnimationRootNode> AnimationNodeBlendSpace2D::get_blend_point_node(int p_poi
 void AnimationNodeBlendSpace2D::remove_blend_point(int p_point) {
 	ERR_FAIL_INDEX(p_point, blend_points_used);
 
+	ERR_FAIL_COND(blend_points[p_point].node.is_null());
 	blend_points[p_point].node->disconnect("tree_changed", this, "_tree_changed");
 
 	for (int i = 0; i < triangles.size(); i++) {
diff --git a/scene/resources/ray_shape.cpp b/scene/resources/ray_shape.cpp
index 5a696aee233..f185263a361 100644
--- a/scene/resources/ray_shape.cpp
+++ b/scene/resources/ray_shape.cpp
@@ -90,6 +90,12 @@ void RayShape::_bind_methods() {
 RayShape::RayShape() :
 		Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_RAY)) {
 
-	set_length(1.0);
-	set_slips_on_slope(false);
+	length = 1.0;
+	slips_on_slope = false;
+
+	/* Code copied from setters to prevent the use of uninitialized variables */
+	_update_shape();
+	notify_change_to_owners();
+	_change_notify("length");
+	_change_notify("slips_on_slope");
 }
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index a7df736c787..bd9dd7c23d6 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -905,6 +905,7 @@ void VisualShaderNodeCubeMap::_bind_methods() {
 
 VisualShaderNodeCubeMap::VisualShaderNodeCubeMap() {
 	texture_type = TYPE_DATA;
+	source = SOURCE_TEXTURE;
 }
 
 ////////////// Scalar Op
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index 2e1f5243627..4bab9b76bac 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -508,12 +508,11 @@ Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_
 				if (p_format & ARRAY_COMPRESS_TANGENT) {
 
 					for (int i = 0; i < p_vertex_array_len; i++) {
-
-						uint8_t xyzw[4] = {
-							(uint8_t)CLAMP(src[i * 4 + 0] * 127, -128, 127),
-							(uint8_t)CLAMP(src[i * 4 + 1] * 127, -128, 127),
-							(uint8_t)CLAMP(src[i * 4 + 2] * 127, -128, 127),
-							(uint8_t)CLAMP(src[i * 4 + 3] * 127, -128, 127)
+						int8_t xyzw[4] = {
+							(int8_t)CLAMP(src[i * 4 + 0] * 127, -128, 127),
+							(int8_t)CLAMP(src[i * 4 + 1] * 127, -128, 127),
+							(int8_t)CLAMP(src[i * 4 + 2] * 127, -128, 127),
+							(int8_t)CLAMP(src[i * 4 + 3] * 127, -128, 127)
 						};
 
 						copymem(&vw[p_offsets[ai] + i * p_stride], xyzw, 4);