2
0
Эх сурвалжийг харах

Merge pull request #71514 from akien-mga/os-unset_environment

OS: Add `unset_environment`, better validate input
Rémi Verschelde 2 жил өмнө
parent
commit
6da836bbb4

+ 8 - 3
core/core_bind.cpp

@@ -322,8 +322,12 @@ String OS::get_environment(const String &p_var) const {
 	return ::OS::get_singleton()->get_environment(p_var);
 }
 
-bool OS::set_environment(const String &p_var, const String &p_value) const {
-	return ::OS::get_singleton()->set_environment(p_var, p_value);
+void OS::set_environment(const String &p_var, const String &p_value) const {
+	::OS::get_singleton()->set_environment(p_var, p_value);
+}
+
+void OS::unset_environment(const String &p_var) const {
+	::OS::get_singleton()->unset_environment(p_var);
 }
 
 String OS::get_name() const {
@@ -548,9 +552,10 @@ void OS::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("is_process_running", "pid"), &OS::is_process_running);
 	ClassDB::bind_method(D_METHOD("get_process_id"), &OS::get_process_id);
 
+	ClassDB::bind_method(D_METHOD("has_environment", "variable"), &OS::has_environment);
 	ClassDB::bind_method(D_METHOD("get_environment", "variable"), &OS::get_environment);
 	ClassDB::bind_method(D_METHOD("set_environment", "variable", "value"), &OS::set_environment);
-	ClassDB::bind_method(D_METHOD("has_environment", "variable"), &OS::has_environment);
+	ClassDB::bind_method(D_METHOD("unset_environment", "variable"), &OS::unset_environment);
 
 	ClassDB::bind_method(D_METHOD("get_name"), &OS::get_name);
 	ClassDB::bind_method(D_METHOD("get_distribution_name"), &OS::get_distribution_name);

+ 2 - 1
core/core_bind.h

@@ -162,7 +162,8 @@ public:
 
 	bool has_environment(const String &p_var) const;
 	String get_environment(const String &p_var) const;
-	bool set_environment(const String &p_var, const String &p_value) const;
+	void set_environment(const String &p_var, const String &p_value) const;
+	void unset_environment(const String &p_var) const;
 
 	String get_name() const;
 	String get_distribution_name() const;

+ 2 - 1
core/os/os.h

@@ -167,7 +167,8 @@ public:
 
 	virtual bool has_environment(const String &p_var) const = 0;
 	virtual String get_environment(const String &p_var) const = 0;
-	virtual bool set_environment(const String &p_var, const String &p_value) const = 0;
+	virtual void set_environment(const String &p_var, const String &p_value) const = 0;
+	virtual void unset_environment(const String &p_var) const = 0;
 
 	virtual String get_name() const = 0;
 	virtual String get_distribution_name() const = 0;

+ 10 - 2
doc/classes/OS.xml

@@ -592,12 +592,12 @@
 			</description>
 		</method>
 		<method name="set_environment" qualifiers="const">
-			<return type="bool" />
+			<return type="void" />
 			<param index="0" name="variable" type="String" />
 			<param index="1" name="value" type="String" />
 			<description>
 				Sets the value of the environment variable [param variable] to [param value]. The environment variable will be set for the Godot process and any process executed with [method execute] after running [method set_environment]. The environment variable will [i]not[/i] persist to processes run after the Godot process was terminated.
-				[b]Note:[/b] Double-check the casing of [param variable]. Environment variable names are case-sensitive on all platforms except Windows.
+				[b]Note:[/b] Environment variable names are case-sensitive on all platforms except Windows. The [param variable] name cannot be empty or include the [code]=[/code] character. On Windows, there is a 32767 characters limit for the combined length of [param variable], [param value], and the [code]=[/code] and null terminator characters that will be registered in the environment block.
 			</description>
 		</method>
 		<method name="set_restart_on_exit">
@@ -637,6 +637,14 @@
 				[b]Note:[/b] This method is implemented on Android, iOS, Web, Linux, macOS and Windows.
 			</description>
 		</method>
+		<method name="unset_environment" qualifiers="const">
+			<return type="void" />
+			<param index="0" name="variable" type="String" />
+			<description>
+				Removes the environment [param variable] from the current environment, if it exists. The environment variable will be removed for the Godot process and any process executed with [method execute] after running [method unset_environment]. The removal of the environment variable will [i]not[/i] persist to processes run after the Godot process was terminated.
+				[b]Note:[/b] Environment variable names are case-sensitive on all platforms except Windows. The [param variable] name cannot be empty or include the [code]=[/code] character.
+			</description>
+		</method>
 	</methods>
 	<members>
 		<member name="low_processor_usage_mode" type="bool" setter="set_low_processor_usage_mode" getter="is_in_low_processor_usage_mode" default="false">

+ 13 - 6
drivers/unix/os_unix.cpp

@@ -411,10 +411,6 @@ bool OS_Unix::is_process_running(const ProcessID &p_pid) const {
 	return true;
 }
 
-bool OS_Unix::has_environment(const String &p_var) const {
-	return getenv(p_var.utf8().get_data()) != nullptr;
-}
-
 String OS_Unix::get_locale() const {
 	if (!has_environment("LANG")) {
 		return "en";
@@ -487,6 +483,10 @@ Error OS_Unix::set_cwd(const String &p_cwd) {
 	return OK;
 }
 
+bool OS_Unix::has_environment(const String &p_var) const {
+	return getenv(p_var.utf8().get_data()) != nullptr;
+}
+
 String OS_Unix::get_environment(const String &p_var) const {
 	if (getenv(p_var.utf8().get_data())) {
 		return getenv(p_var.utf8().get_data());
@@ -494,8 +494,15 @@ String OS_Unix::get_environment(const String &p_var) const {
 	return "";
 }
 
-bool OS_Unix::set_environment(const String &p_var, const String &p_value) const {
-	return setenv(p_var.utf8().get_data(), p_value.utf8().get_data(), /* overwrite: */ true) == 0;
+void OS_Unix::set_environment(const String &p_var, const String &p_value) const {
+	ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains("="), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var));
+	int err = setenv(p_var.utf8().get_data(), p_value.utf8().get_data(), /* overwrite: */ 1);
+	ERR_FAIL_COND_MSG(err != 0, vformat("Failed setting environment variable '%s', the system is out of memory.", p_var));
+}
+
+void OS_Unix::unset_environment(const String &p_var) const {
+	ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains("="), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var));
+	unsetenv(p_var.utf8().get_data());
 }
 
 String OS_Unix::get_user_data_dir() const {

+ 3 - 1
drivers/unix/os_unix.h

@@ -81,7 +81,9 @@ public:
 
 	virtual bool has_environment(const String &p_var) const override;
 	virtual String get_environment(const String &p_var) const override;
-	virtual bool set_environment(const String &p_var, const String &p_value) const override;
+	virtual void set_environment(const String &p_var, const String &p_value) const override;
+	virtual void unset_environment(const String &p_var) const override;
+
 	virtual String get_locale() const override;
 
 	virtual void initialize_debugging() override;

+ 11 - 2
platform/windows/os_windows.cpp

@@ -1166,8 +1166,17 @@ String OS_Windows::get_environment(const String &p_var) const {
 	return "";
 }
 
-bool OS_Windows::set_environment(const String &p_var, const String &p_value) const {
-	return (bool)SetEnvironmentVariableW((LPCWSTR)(p_var.utf16().get_data()), (LPCWSTR)(p_value.utf16().get_data()));
+void OS_Windows::set_environment(const String &p_var, const String &p_value) const {
+	ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains("="), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var));
+	Char16String var = p_var.utf16();
+	Char16String value = p_value.utf16();
+	ERR_FAIL_COND_MSG(var.length() + value.length() + 2 > 32767, vformat("Invalid definition for environment variable '%s', cannot exceed 32767 characters.", p_var));
+	SetEnvironmentVariableW((LPCWSTR)(var.get_data()), (LPCWSTR)(value.get_data()));
+}
+
+void OS_Windows::unset_environment(const String &p_var) const {
+	ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains("="), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var));
+	SetEnvironmentVariableW((LPCWSTR)(p_var.utf16().get_data()), nullptr); // Null to delete.
 }
 
 String OS_Windows::get_stdin_string() {

+ 2 - 1
platform/windows/os_windows.h

@@ -186,7 +186,8 @@ public:
 
 	virtual bool has_environment(const String &p_var) const override;
 	virtual String get_environment(const String &p_var) const override;
-	virtual bool set_environment(const String &p_var, const String &p_value) const override;
+	virtual void set_environment(const String &p_var, const String &p_value) const override;
+	virtual void unset_environment(const String &p_var) const override;
 
 	virtual Vector<String> get_system_fonts() const override;
 	virtual String get_system_font_path(const String &p_font_name, int p_weight = 400, int p_stretch = 100, bool p_italic = false) const override;