From a8809e04f95bf7c68fb96d0e708ee99592865883 Mon Sep 17 00:00:00 2001 From: Sviatoslav Peleshko Date: Sun, 15 May 2022 07:51:10 +0300 Subject: [PATCH 1/3] Use the correct size for the symlink path buffer This fixes crashes when the path has non-ASCII characters --- src/Avalonia.FreeDesktop/NativeMethods.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Avalonia.FreeDesktop/NativeMethods.cs b/src/Avalonia.FreeDesktop/NativeMethods.cs index 8bbda98bb2..147955b6a3 100644 --- a/src/Avalonia.FreeDesktop/NativeMethods.cs +++ b/src/Avalonia.FreeDesktop/NativeMethods.cs @@ -14,15 +14,15 @@ namespace Avalonia.FreeDesktop public static string ReadLink(string path) { - var symlinkMaxSize = Encoding.ASCII.GetMaxByteCount(path.Length); + var symlinkSize = Encoding.UTF8.GetByteCount(path); var bufferSize = 4097; // PATH_MAX is (usually?) 4096, but we need to know if the result was truncated - var symlink = ArrayPool.Shared.Rent(symlinkMaxSize + 1); + var symlink = ArrayPool.Shared.Rent(symlinkSize + 1); var buffer = ArrayPool.Shared.Rent(bufferSize); try { - var symlinkSize = Encoding.UTF8.GetBytes(path, 0, path.Length, symlink, 0); + Encoding.UTF8.GetBytes(path, 0, path.Length, symlink, 0); symlink[symlinkSize] = 0; var size = readlink(symlink, buffer, bufferSize); From 56b5af0da6b033af423cc933278e6b669c0b049a Mon Sep 17 00:00:00 2001 From: Sviatoslav Peleshko Date: Sun, 15 May 2022 07:55:39 +0300 Subject: [PATCH 2/3] Unescape mount point paths read from /proc/mounts This makes mounts that have symbols " \t\n\\" actually appear in the volumes list in the ManagedFileChooser dialog. --- src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoListener.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoListener.cs b/src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoListener.cs index f9737b461d..1af44f9db6 100644 --- a/src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoListener.cs +++ b/src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoListener.cs @@ -36,6 +36,11 @@ namespace Avalonia.FreeDesktop private string GetSymlinkTarget(string x) => Path.GetFullPath(Path.Combine(DevByLabelDir, NativeMethods.ReadLink(x))); + private string UnescapeString(string input, string regexText, int escapeBase) => + new Regex(regexText).Replace(input, m => Convert.ToChar(Convert.ToByte(m.Groups[1].Value, escapeBase)).ToString()); + + private string UnescapePathFromProcMounts(string input) => UnescapeString(input, @"\\(\d{3})", 8); + private void Poll(long _) { var fProcPartitions = File.ReadAllLines(ProcPartitionsDir) @@ -47,7 +52,7 @@ namespace Avalonia.FreeDesktop var fProcMounts = File.ReadAllLines(ProcMountsDir) .Select(x => x.Split(' ')) - .Select(x => (x[0], x[1])) + .Select(x => (x[0], UnescapePathFromProcMounts(x[1]))) .Where(x => !x.Item2.StartsWith("/snap/", StringComparison.InvariantCultureIgnoreCase)); var labelDirEnum = Directory.Exists(DevByLabelDir) ? From 97765b522c19f3a726bd902b974af7501f45db18 Mon Sep 17 00:00:00 2001 From: Sviatoslav Peleshko Date: Sun, 15 May 2022 07:58:45 +0300 Subject: [PATCH 3/3] Unescape volumes labels read from /dev/disk/by-label folder This makes volumes with labels containing some special characters (e.g. whitespace, tab, etc.) to show up correctly in the ManagedFileChooser dialog. --- src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoListener.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoListener.cs b/src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoListener.cs index 1af44f9db6..39ddd9d769 100644 --- a/src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoListener.cs +++ b/src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoListener.cs @@ -41,6 +41,8 @@ namespace Avalonia.FreeDesktop private string UnescapePathFromProcMounts(string input) => UnescapeString(input, @"\\(\d{3})", 8); + private string UnescapeDeviceLabel(string input) => UnescapeString(input, @"\\x([0-9a-f]{2})", 16); + private void Poll(long _) { var fProcPartitions = File.ReadAllLines(ProcPartitionsDir) @@ -59,7 +61,7 @@ namespace Avalonia.FreeDesktop new DirectoryInfo(DevByLabelDir).GetFiles() : Enumerable.Empty(); var labelDevPathPairs = labelDirEnum - .Select(x => (GetSymlinkTarget(x.FullName), x.Name)); + .Select(x => (GetSymlinkTarget(x.FullName), UnescapeDeviceLabel(x.Name))); var q1 = from mount in fProcMounts join device in fProcPartitions on mount.Item1 equals device.Item2 @@ -69,7 +71,7 @@ namespace Avalonia.FreeDesktop { VolumePath = mount.Item2, VolumeSizeBytes = device.Item1, - VolumeLabel = x.Name + VolumeLabel = x.Item2 }; var mountVolInfos = q1.ToArray();