using System.Buffers;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;

namespace Avalonia.FreeDesktop
{
    internal static class NativeMethods
    {
        [DllImport("libc", SetLastError = true)]
        private static extern long readlink([MarshalAs(UnmanagedType.LPArray)] byte[] filename,
                                            [MarshalAs(UnmanagedType.LPArray)] byte[] buffer,
                                            long len);

        public static string ReadLink(string path)
        {
            var symlinkMaxSize = Encoding.ASCII.GetMaxByteCount(path.Length);
            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 buffer = ArrayPool<byte>.Shared.Rent(bufferSize);

            try
            {
                var symlinkSize = Encoding.UTF8.GetBytes(path, 0, path.Length, symlink, 0);
                symlink[symlinkSize] = 0;

                var size = readlink(symlink, buffer, bufferSize);
                Debug.Assert(size < bufferSize); // if this fails, we need to increase the buffer size (dynamically?)

                return Encoding.UTF8.GetString(buffer, 0, (int)size);
            }
            finally
            {
                ArrayPool<byte>.Shared.Return(symlink);
                ArrayPool<byte>.Shared.Return(buffer);
            }
        }
    }
}

using System.Buffers;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;

namespace Avalonia.FreeDesktop
{
    internal static class NativeMethods
    {
        [DllImport("libc", SetLastError = true)]
        private static extern long readlink([MarshalAs(UnmanagedType.LPArray)] byte[] filename,
                                            [MarshalAs(UnmanagedType.LPArray)] byte[] buffer,
                                            long len);

        public static string ReadLink(string path)
        {
            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<byte>.Shared.Rent(symlinkSize + 1);
            var buffer = ArrayPool<byte>.Shared.Rent(bufferSize);

            try
            {
                Encoding.UTF8.GetBytes(path, 0, path.Length, symlink, 0);
                symlink[symlinkSize] = 0;

                var size = readlink(symlink, buffer, bufferSize);
                Debug.Assert(size < bufferSize); // if this fails, we need to increase the buffer size (dynamically?)

                return Encoding.UTF8.GetString(buffer, 0, (int)size);
            }
            finally
            {
                ArrayPool<byte>.Shared.Return(symlink);
                ArrayPool<byte>.Shared.Return(buffer);
            }
        }
    }
}

Use the correct size for the symlink path buffer
Use the correct size for the symlink path buffer

This fixes crashes when the path has non-ASCII characters
