From 12236d28687db984d5d9dd3f247936b93195ed0a Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Fri, 7 May 2021 19:02:35 +0200 Subject: [PATCH] Only allow absolute paths in XDG environment variables The XDG Base Directory specification does not allow using relative paths (which broke things in Godot anyway). If a relative path is detected, it should be ignored. (cherry picked from commits 011a99316ab8c0e96971aebd9ba995313867fe17 and 0e1d45b210d0e5924b279419d9bba188f557e329) --- platform/osx/os_osx.mm | 40 +++++++++++++++++++++---------- platform/windows/os_windows.cpp | 42 ++++++++++++++++++++++----------- platform/x11/os_x11.cpp | 42 +++++++++++++++++++++------------ 3 files changed, 82 insertions(+), 42 deletions(-) diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 325aee8ad43..cdc9d0e84a9 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -2238,31 +2238,45 @@ 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 macOS as well. if (has_environment("XDG_CONFIG_HOME")) { - return get_environment("XDG_CONFIG_HOME"); - } else if (has_environment("HOME")) { - return get_environment("HOME").plus_file("Library/Application Support"); - } else { - return "."; + 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."); + } } + if (has_environment("HOME")) { + return get_environment("HOME").plus_file("Library/Application Support"); + } + return "."; } 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 macOS as well. if (has_environment("XDG_DATA_HOME")) { - return get_environment("XDG_DATA_HOME"); - } else { - return get_config_path(); + 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(); } 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 macOS as well. if (has_environment("XDG_CACHE_HOME")) { - return get_environment("XDG_CACHE_HOME"); - } else if (has_environment("HOME")) { - return get_environment("HOME").plus_file("Library/Caches"); - } else { - return get_config_path(); + 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."); + } } + if (has_environment("HOME")) { + return get_environment("HOME").plus_file("Library/Caches"); + } + return get_config_path(); } String OS_OSX::get_bundle_resource_dir() const { diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index c013e562462..952c83179b9 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -3316,31 +3316,45 @@ 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"); - } else if (has_environment("APPDATA")) { - return get_environment("APPDATA"); - } else { - return "."; + // 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."); + } } + if (has_environment("APPDATA")) { + return get_environment("APPDATA"); + } + return "."; } 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"); - } else { - return get_config_path(); + 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(); } 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"); - } else if (has_environment("TEMP")) { - return get_environment("TEMP"); - } else { - return get_config_path(); + 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."); + } } + if (has_environment("TEMP")) { + return get_environment("TEMP"); + } + return get_config_path(); } // Get properly capitalized engine name for system paths diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 1a888ac504f..7a5c80e2cb2 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -3208,32 +3208,44 @@ bool OS_X11::_check_internal_feature_support(const String &p_feature) { String OS_X11::get_config_path() const { if (has_environment("XDG_CONFIG_HOME")) { - return get_environment("XDG_CONFIG_HOME"); - } else if (has_environment("HOME")) { - return get_environment("HOME").plus_file(".config"); - } else { - return "."; + 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."); + } } + if (has_environment("HOME")) { + return get_environment("HOME").plus_file(".config"); + } + return "."; } String OS_X11::get_data_path() const { if (has_environment("XDG_DATA_HOME")) { - return get_environment("XDG_DATA_HOME"); - } else if (has_environment("HOME")) { - return get_environment("HOME").plus_file(".local/share"); - } else { - return get_config_path(); + 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."); + } } + if (has_environment("HOME")) { + return get_environment("HOME").plus_file(".local/share"); + } + return get_config_path(); } String OS_X11::get_cache_path() const { if (has_environment("XDG_CACHE_HOME")) { - return get_environment("XDG_CACHE_HOME"); - } else if (has_environment("HOME")) { - return get_environment("HOME").plus_file(".cache"); - } else { - return get_config_path(); + 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."); + } } + if (has_environment("HOME")) { + return get_environment("HOME").plus_file(".cache"); + } + return get_config_path(); } String OS_X11::get_system_dir(SystemDir p_dir) const {