Browse Source

Merge pull request #48542 from Calinou/xdg-base-dirs-absolute-only

Only allow absolute paths in XDG environment variables
Rémi Verschelde 4 years ago
parent
commit
557df29fc9
3 changed files with 61 additions and 10 deletions
  1. 18 3
      platform/linuxbsd/os_linuxbsd.cpp
  2. 21 3
      platform/osx/os_osx.mm
  3. 22 4
      platform/windows/os_windows.cpp

+ 18 - 3
platform/linuxbsd/os_linuxbsd.cpp

@@ -164,7 +164,12 @@ bool OS_LinuxBSD::_check_internal_feature_support(const String &p_feature) {
 
 String OS_LinuxBSD::get_config_path() const {
 	if (has_environment("XDG_CONFIG_HOME")) {
-		return get_environment("XDG_CONFIG_HOME");
+		if (get_environment("XDG_CONFIG_HOME").is_abs_path()) {
+			return get_environment("XDG_CONFIG_HOME");
+		} else {
+			WARN_PRINT_ONCE("`XDG_CONFIG_HOME` is a relative path. Ignoring its value and falling back to `$HOME/.config` or `.` per the XDG Base Directory specification.");
+			return has_environment("HOME") ? get_environment("HOME").plus_file(".config") : ".";
+		}
 	} else if (has_environment("HOME")) {
 		return get_environment("HOME").plus_file(".config");
 	} else {
@@ -174,7 +179,12 @@ String OS_LinuxBSD::get_config_path() const {
 
 String OS_LinuxBSD::get_data_path() const {
 	if (has_environment("XDG_DATA_HOME")) {
-		return get_environment("XDG_DATA_HOME");
+		if (get_environment("XDG_DATA_HOME").is_abs_path()) {
+			return get_environment("XDG_DATA_HOME");
+		} else {
+			WARN_PRINT_ONCE("`XDG_DATA_HOME` is a relative path. Ignoring its value and falling back to `$HOME/.local/share` or `get_config_path()` per the XDG Base Directory specification.");
+			return has_environment("HOME") ? get_environment("HOME").plus_file(".local/share") : get_config_path();
+		}
 	} else if (has_environment("HOME")) {
 		return get_environment("HOME").plus_file(".local/share");
 	} else {
@@ -184,7 +194,12 @@ String OS_LinuxBSD::get_data_path() const {
 
 String OS_LinuxBSD::get_cache_path() const {
 	if (has_environment("XDG_CACHE_HOME")) {
-		return get_environment("XDG_CACHE_HOME");
+		if (get_environment("XDG_CACHE_HOME").is_abs_path()) {
+			return get_environment("XDG_CACHE_HOME");
+		} else {
+			WARN_PRINT_ONCE("`XDG_CACHE_HOME` is a relative path. Ignoring its value and falling back to `$HOME/.cache` or `get_config_path()` per the XDG Base Directory specification.");
+			return has_environment("HOME") ? get_environment("HOME").plus_file(".cache") : get_config_path();
+		}
 	} else if (has_environment("HOME")) {
 		return get_environment("HOME").plus_file(".cache");
 	} else {

+ 21 - 3
platform/osx/os_osx.mm

@@ -188,8 +188,14 @@ MainLoop *OS_OSX::get_main_loop() const {
 }
 
 String OS_OSX::get_config_path() const {
+	// The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on Windows as well.
 	if (has_environment("XDG_CONFIG_HOME")) {
-		return get_environment("XDG_CONFIG_HOME");
+		if (get_environment("XDG_CONFIG_HOME").is_abs_path()) {
+			return get_environment("XDG_CONFIG_HOME");
+		} else {
+			WARN_PRINT_ONCE("`XDG_CONFIG_HOME` is a relative path. Ignoring its value and falling back to `$HOME/Library/Application Support` or `.` per the XDG Base Directory specification.");
+			return has_environment("HOME") ? get_environment("HOME").plus_file("Library/Application Support") : ".";
+		}
 	} else if (has_environment("HOME")) {
 		return get_environment("HOME").plus_file("Library/Application Support");
 	} else {
@@ -198,16 +204,28 @@ String OS_OSX::get_config_path() const {
 }
 
 String OS_OSX::get_data_path() const {
+	// The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on Windows as well.
 	if (has_environment("XDG_DATA_HOME")) {
-		return get_environment("XDG_DATA_HOME");
+		if (get_environment("XDG_DATA_HOME").is_abs_path()) {
+			return get_environment("XDG_DATA_HOME");
+		} else {
+			WARN_PRINT_ONCE("`XDG_DATA_HOME` is a relative path. Ignoring its value and falling back to `get_config_path()` per the XDG Base Directory specification.");
+			return get_config_path();
+		}
 	} else {
 		return get_config_path();
 	}
 }
 
 String OS_OSX::get_cache_path() const {
+	// The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on Windows as well.
 	if (has_environment("XDG_CACHE_HOME")) {
-		return get_environment("XDG_CACHE_HOME");
+		if (get_environment("XDG_CACHE_HOME").is_abs_path()) {
+			return get_environment("XDG_CACHE_HOME");
+		} else {
+			WARN_PRINT_ONCE("`XDG_CACHE_HOME` is a relative path. Ignoring its value and falling back to `$HOME/Libary/Caches` or `get_config_path()` per the XDG Base Directory specification.");
+			return has_environment("HOME") ? get_environment("HOME").plus_file("Library/Caches") : get_config_path();
+		}
 	} else if (has_environment("HOME")) {
 		return get_environment("HOME").plus_file("Library/Caches");
 	} else {

+ 22 - 4
platform/windows/os_windows.cpp

@@ -631,8 +631,14 @@ MainLoop *OS_Windows::get_main_loop() const {
 }
 
 String OS_Windows::get_config_path() const {
-	if (has_environment("XDG_CONFIG_HOME")) { // unlikely, but after all why not?
-		return get_environment("XDG_CONFIG_HOME");
+	// The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on Windows as well.
+	if (has_environment("XDG_CONFIG_HOME")) {
+		if (get_environment("XDG_CONFIG_HOME").is_abs_path()) {
+			return get_environment("XDG_CONFIG_HOME");
+		} else {
+			WARN_PRINT_ONCE("`XDG_CONFIG_HOME` is a relative path. Ignoring its value and falling back to `%APPDATA%` or `.` per the XDG Base Directory specification.");
+			return has_environment("APPDATA") ? get_environment("APPDATA") : ".";
+		}
 	} else if (has_environment("APPDATA")) {
 		return get_environment("APPDATA");
 	} else {
@@ -641,16 +647,28 @@ String OS_Windows::get_config_path() const {
 }
 
 String OS_Windows::get_data_path() const {
+	// The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on Windows as well.
 	if (has_environment("XDG_DATA_HOME")) {
-		return get_environment("XDG_DATA_HOME");
+		if (get_environment("XDG_DATA_HOME").is_abs_path()) {
+			return get_environment("XDG_DATA_HOME");
+		} else {
+			WARN_PRINT_ONCE("`XDG_DATA_HOME` is a relative path. Ignoring its value and falling back to `get_config_path()` per the XDG Base Directory specification.");
+			return get_config_path();
+		}
 	} else {
 		return get_config_path();
 	}
 }
 
 String OS_Windows::get_cache_path() const {
+	// The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on Windows as well.
 	if (has_environment("XDG_CACHE_HOME")) {
-		return get_environment("XDG_CACHE_HOME");
+		if (get_environment("XDG_CACHE_HOME").is_abs_path()) {
+			return get_environment("XDG_CACHE_HOME");
+		} else {
+			WARN_PRINT_ONCE("`XDG_CACHE_HOME` is a relative path. Ignoring its value and falling back to `%TEMP%` or `get_config_path()` per the XDG Base Directory specification.");
+			return has_environment("TEMP") ? get_environment("TEMP") : get_config_path();
+		}
 	} else if (has_environment("TEMP")) {
 		return get_environment("TEMP");
 	} else {