浏览代码

Merge pull request #8134 from speles/volume_names_fixes

Fixes related to `ManagedFileChooser` handling of "complex" volume names
Jumar Macato 3 年之前
父节点
当前提交
049dc0bf6c
共有 2 个文件被更改,包括 13 次插入6 次删除
  1. 10 3
      src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoListener.cs
  2. 3 3
      src/Avalonia.FreeDesktop/NativeMethods.cs

+ 10 - 3
src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoListener.cs

@@ -36,6 +36,13 @@ namespace Avalonia.FreeDesktop
 
 
         private string GetSymlinkTarget(string x) => Path.GetFullPath(Path.Combine(DevByLabelDir, NativeMethods.ReadLink(x)));
         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 string UnescapeDeviceLabel(string input) => UnescapeString(input, @"\\x([0-9a-f]{2})", 16);
+
         private void Poll(long _)
         private void Poll(long _)
         {
         {
             var fProcPartitions = File.ReadAllLines(ProcPartitionsDir)
             var fProcPartitions = File.ReadAllLines(ProcPartitionsDir)
@@ -47,14 +54,14 @@ namespace Avalonia.FreeDesktop
 
 
             var fProcMounts = File.ReadAllLines(ProcMountsDir)
             var fProcMounts = File.ReadAllLines(ProcMountsDir)
                                   .Select(x => x.Split(' '))
                                   .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));
                                   .Where(x => !x.Item2.StartsWith("/snap/", StringComparison.InvariantCultureIgnoreCase));
 
 
             var labelDirEnum = Directory.Exists(DevByLabelDir) ?
             var labelDirEnum = Directory.Exists(DevByLabelDir) ?
                                new DirectoryInfo(DevByLabelDir).GetFiles() : Enumerable.Empty<FileInfo>();
                                new DirectoryInfo(DevByLabelDir).GetFiles() : Enumerable.Empty<FileInfo>();
 
 
             var labelDevPathPairs = labelDirEnum
             var labelDevPathPairs = labelDirEnum
-                                    .Select(x => (GetSymlinkTarget(x.FullName), x.Name));
+                                    .Select(x => (GetSymlinkTarget(x.FullName), UnescapeDeviceLabel(x.Name)));
 
 
             var q1 = from mount in fProcMounts
             var q1 = from mount in fProcMounts
                      join device in fProcPartitions on mount.Item1 equals device.Item2
                      join device in fProcPartitions on mount.Item1 equals device.Item2
@@ -64,7 +71,7 @@ namespace Avalonia.FreeDesktop
                      {
                      {
                          VolumePath = mount.Item2,
                          VolumePath = mount.Item2,
                          VolumeSizeBytes = device.Item1,
                          VolumeSizeBytes = device.Item1,
-                         VolumeLabel = x.Name
+                         VolumeLabel = x.Item2
                      };
                      };
 
 
             var mountVolInfos = q1.ToArray();
             var mountVolInfos = q1.ToArray();

+ 3 - 3
src/Avalonia.FreeDesktop/NativeMethods.cs

@@ -14,15 +14,15 @@ namespace Avalonia.FreeDesktop
 
 
         public static string ReadLink(string path)
         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 bufferSize = 4097; // PATH_MAX is (usually?) 4096, but we need to know if the result was truncated
 
 
-            var symlink = ArrayPool<byte>.Shared.Rent(symlinkMaxSize + 1);
+            var symlink = ArrayPool<byte>.Shared.Rent(symlinkSize + 1);
             var buffer = ArrayPool<byte>.Shared.Rent(bufferSize);
             var buffer = ArrayPool<byte>.Shared.Rent(bufferSize);
 
 
             try
             try
             {
             {
-                var symlinkSize = Encoding.UTF8.GetBytes(path, 0, path.Length, symlink, 0);
+                Encoding.UTF8.GetBytes(path, 0, path.Length, symlink, 0);
                 symlink[symlinkSize] = 0;
                 symlink[symlinkSize] = 0;
 
 
                 var size = readlink(symlink, buffer, bufferSize);
                 var size = readlink(symlink, buffer, bufferSize);