diff --git a/src/Avalonia.Base/Platform/Storage/FileIO/BclLauncher.cs b/src/Avalonia.Base/Platform/Storage/FileIO/BclLauncher.cs index 4342b7b2f2a..242b8e6d41b 100644 --- a/src/Avalonia.Base/Platform/Storage/FileIO/BclLauncher.cs +++ b/src/Avalonia.Base/Platform/Storage/FileIO/BclLauncher.cs @@ -3,7 +3,6 @@ using System.Text.RegularExpressions; using System.Threading.Tasks; using Avalonia.Compatibility; -using Avalonia.Metadata; namespace Avalonia.Platform.Storage.FileIO; @@ -44,7 +43,8 @@ private static bool Exec(string urlOrFile) { // If no associated application/json MimeType is found xdg-open opens return error // but it tries to open it anyway using the console editor (nano, vim, other..) - ShellExec($"xdg-open {urlOrFile}", waitForExit: false); + var args = EscapeForShell(urlOrFile); + ShellExecRaw($"xdg-open \\\"{args}\\\"", waitForExit: false); return true; } else if (OperatingSystemEx.IsWindows() || OperatingSystemEx.IsMacOS()) @@ -63,17 +63,18 @@ private static bool Exec(string urlOrFile) return false; } } - - private static void ShellExec(string cmd, bool waitForExit = true) + + private static string EscapeForShell(string input) => Regex + .Replace(input, "(?=[`~!#&*()|;'<>])", "\\") + .Replace("\"", "\\\\\\\""); + + private static void ShellExecRaw(string cmd, bool waitForExit = true) { - var escapedArgs = Regex.Replace(cmd, "(?=[`~!#&*()|;'<>])", "\\") - .Replace("\"", "\\\\\\\""); - using (var process = Process.Start( new ProcessStartInfo { FileName = "/bin/sh", - Arguments = $"-c \"{escapedArgs}\"", + Arguments = $"-c \"{cmd}\"", RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true,