From a808f3e8772d8b1cb21b105403475577b4e35281 Mon Sep 17 00:00:00 2001
From: Haoyu Qiu <timothyqiu32@gmail.com>
Date: Mon, 19 Aug 2024 15:14:10 +0800
Subject: [PATCH] Fix split_floats behavior when spaces are used as separators

---
 core/ustring.cpp           | 10 ++++--
 main/tests/test_string.cpp | 62 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 70 insertions(+), 2 deletions(-)

diff --git a/core/ustring.cpp b/core/ustring.cpp
index d5543aa05bbc..22e065193996 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -904,13 +904,16 @@ Vector<float> String::split_floats(const String &p_splitter, bool p_allow_empty)
 	int from = 0;
 	int len = length();
 
+	String buffer = *this;
 	while (true) {
 		int end = find(p_splitter, from);
 		if (end < 0) {
 			end = len;
 		}
 		if (p_allow_empty || (end > from)) {
-			ret.push_back(String::to_double(&c_str()[from]));
+			buffer[end] = 0;
+			ret.push_back(String::to_double(&buffer.c_str()[from]));
+			buffer[end] = _cowdata.get(end);
 		}
 
 		if (end == len) {
@@ -928,6 +931,7 @@ Vector<float> String::split_floats_mk(const Vector<String> &p_splitters, bool p_
 	int from = 0;
 	int len = length();
 
+	String buffer = *this;
 	while (true) {
 		int idx;
 		int end = findmk(p_splitters, from, &idx);
@@ -939,7 +943,9 @@ Vector<float> String::split_floats_mk(const Vector<String> &p_splitters, bool p_
 		}
 
 		if (p_allow_empty || (end > from)) {
-			ret.push_back(String::to_double(&c_str()[from]));
+			buffer[end] = 0;
+			ret.push_back(String::to_double(&buffer.c_str()[from]));
+			buffer[end] = _cowdata.get(end);
 		}
 
 		if (end == len) {
diff --git a/main/tests/test_string.cpp b/main/tests/test_string.cpp
index f773650752d5..e2d4d41f8620 100644
--- a/main/tests/test_string.cpp
+++ b/main/tests/test_string.cpp
@@ -1254,6 +1254,67 @@ bool test_37() {
 	return true;
 }
 
+bool test_38() {
+#define CHECK_ARR_LEN(arr, len)                                                                           \
+	if (arr.size() != len) {                                                                              \
+		OS::get_singleton()->print("\tFAIL: Length of %s should be %d, got %d\n", #arr, len, arr.size()); \
+		return false;                                                                                     \
+	} else {                                                                                              \
+		OS::get_singleton()->print("\tPASS\n");                                                           \
+	}
+#define CHECK_ARR_ELEMENT(arr, i, expect)                                                 \
+	if (ABS(arr[i] - expect) > 0.00001) {                                                 \
+		OS::get_singleton()->print("\tFAIL: %s[%d] %f != %f\n", #arr, i, arr[i], expect); \
+		return false;                                                                     \
+	} else {                                                                              \
+		OS::get_singleton()->print("\tPASS\n");                                           \
+	}
+
+	OS::get_singleton()->print("\n\nTest 38: split_floats\n");
+
+	{
+		const String s = "1.2;2.3 4.5";
+		const float slices[3] = { 1.2, 2.3, 4.5 };
+
+		const Vector<float> d_arr = s.split_floats(";");
+		CHECK_ARR_LEN(d_arr, 2);
+		for (int i = 0; i < 2; i++) {
+			CHECK_ARR_ELEMENT(d_arr, i, slices[i]);
+		}
+
+		Vector<String> keys;
+		keys.push_back(";");
+		keys.push_back(" ");
+		const Vector<float> f_arr = s.split_floats_mk(keys);
+		CHECK_ARR_LEN(f_arr, 3);
+		for (int i = 0; i < 3; i++) {
+			CHECK_ARR_ELEMENT(f_arr, i, slices[i]);
+		}
+	}
+
+	{
+		const String s = " -2.0        5";
+		const float slices[10] = { 0, -2, 0, 0, 0, 0, 0, 0, 0, 5 };
+
+		const Vector<float> d_arr = s.split_floats(" ");
+		CHECK_ARR_LEN(d_arr, 10);
+		for (int i = 0; i < 10; i++) {
+			CHECK_ARR_ELEMENT(d_arr, i, slices[i]);
+		}
+
+		Vector<String> keys;
+		keys.push_back(";");
+		keys.push_back(" ");
+		const Vector<float> f_arr = s.split_floats_mk(keys);
+		CHECK_ARR_LEN(f_arr, 10);
+		for (int i = 0; i < 10; i++) {
+			CHECK_ARR_ELEMENT(f_arr, i, slices[i]);
+		}
+	}
+
+	return true;
+}
+
 typedef bool (*TestFunc)();
 
 TestFunc test_funcs[] = {
@@ -1295,6 +1356,7 @@ TestFunc test_funcs[] = {
 	test_35,
 	test_36,
 	test_37,
+	test_38,
 	nullptr
 
 };