diff --git a/core/relinker/cli/src/Autorun.cpp b/core/relinker/cli/src/Autorun.cpp index 3bb7016be..0660289e4 100644 --- a/core/relinker/cli/src/Autorun.cpp +++ b/core/relinker/cli/src/Autorun.cpp @@ -16,7 +16,16 @@ int Autorun(const std::string& absPath, bool toWindows) { std::filesystem::perm_options::add); } +#ifdef _WIN32 const std::string cmd = "\"" + absPath + "\""; +#else + std::string cmd = "'"; + for (const char character : absPath) { + if (character == '\'') cmd += "'\\''"; + else cmd += character; + } + cmd += '\''; +#endif const int rawCode = std::system(cmd.c_str()); int exitCode = rawCode; diff --git a/core/relinker/cli/tests/AutorunExitTests.cpp b/core/relinker/cli/tests/AutorunExitTests.cpp index f6fc70829..4890de71d 100644 --- a/core/relinker/cli/tests/AutorunExitTests.cpp +++ b/core/relinker/cli/tests/AutorunExitTests.cpp @@ -6,6 +6,7 @@ #include #include #include +#include int main(int, char* argv[]) { const auto executable = std::filesystem::absolute(argv[0]); @@ -14,7 +15,7 @@ int main(int, char* argv[]) { if (name.find("signal") != std::string::npos) std::raise(SIGILL); return 42; } - const auto child = std::filesystem::temp_directory_path() / ("anyps5-autorun-child-" + + auto child = std::filesystem::temp_directory_path() / ("anyps5-autorun-child-" + std::to_string(std::chrono::steady_clock::now().time_since_epoch().count()) + " with spaces" + executable.extension().string()); #ifndef _WIN32 const auto signaled = child.parent_path() / ("anyps5-autorun-child-signal-" + child.filename().string()); @@ -24,9 +25,21 @@ int main(int, char* argv[]) { int result = 0; try { std::filesystem::copy_file(executable, child); - for (const bool windows : {false, true}) { - const int code = Cli::Autorun(child.string(), windows); - if (code != 42) throw std::runtime_error("Autorun changed exit code 42 to " + std::to_string(code)); + std::vector suffixes{""}; +#ifndef _WIN32 + suffixes.insert(suffixes.end(), {" $HOME", " $(printf substituted)", " `printf substituted`", + " 'single'", " \"double\"", " \\backslash", " line\nbreak"}); +#endif + const auto originalChild = child; + for (const auto& suffix : suffixes) { + const auto renamed = std::filesystem::path(originalChild.string() + suffix); + if (renamed != child) std::filesystem::rename(child, renamed); + child = renamed; + for (const bool windows : {false, true}) { + const int code = Cli::Autorun(child.string(), windows); + if (code != 42) throw std::runtime_error("Autorun changed exit code 42 to " + + std::to_string(code) + " for " + child.string()); + } } #ifndef _WIN32 std::filesystem::rename(child, signaled);