Skip to content

[vendored-sync] platform-terminal-native-methods: drift detected (#0) #10075

Description

@github-actions

Automated drift report for vendored file src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NativeMethods.cs.

Source

Drift

  • Baseline blob SHA: a62b415fd2be6de86ee2d23aa35dc591050dfe95
  • Current blob SHA: 57b65e7302795a75fb72756f72353521f15b1d3b
  • Baseline ref SHA : 5d4dd79d0ffc1b827c1c6baa9dee0a0c475fe79c
  • Current ref SHA : e4f142939bc3971465a79b89219441f543b743b1

Links

Upstream-only diff

--- src/Framework/NativeMethods.cs@a62b415
+++ src/Framework/NativeMethods.cs@57b65e7
@@ -1206,32 +1206,6 @@
         return true;
     }
 
-#if FEATURE_WINDOWSINTEROP
-    [SupportedOSPlatform("windows6.1")]
-    internal static unsafe string GetFullPath(string path)
-    {
-        using BufferScope<char> buffer = new(stackalloc char[(int)PInvoke.MAX_PATH]);
-        int fullPathLength = (int)PInvoke.GetFullPathName(path, buffer, out _);
-
-        // If user is using long paths we could need to allocate a larger buffer
-        if (fullPathLength > buffer.Length)
-        {
-            buffer.EnsureCapacity(fullPathLength);
-            fullPathLength = (int)PInvoke.GetFullPathName(path, buffer, out _);
-        }
-
-        if (fullPathLength == 0)
-        {
-            HRESULT.FromLastError().ThrowOnFailure();
-        }
-
-        // Avoid creating new strings unnecessarily
-        ReadOnlySpan<char> result = buffer.AsSpan().Slice(0, fullPathLength);
-        return result.SequenceEqual(path.AsSpan()) ? path : result.ToString();
-    }
-
-#endif
-
     /// <summary>
     /// Overrides the console capabilities reported by <see cref="QueryIsScreenAndTryEnableAnsiColorCodes"/>.
     /// Set by a node (e.g. the MSBuild Server node) to the capabilities transmitted from the client process,
@@ -1330,6 +1304,56 @@
     [DllImport("libc", SetLastError = true)]
     internal static extern int symlink(string oldpath, string newpath);
 
+#if NET
+    [DllImport("libc", EntryPoint = "realpath", SetLastError = true)]
+    private static extern IntPtr realpath_native(string path, IntPtr resolved);
+
+    [DllImport("libc", EntryPoint = "free")]
+    private static extern void free_native(IntPtr ptr);
+
+    /// <summary>
+    /// Resolves <paramref name="path"/> to its canonical form via POSIX <c>realpath(3)</c>, following
+    /// symlinks. Returns <c>null</c> on Windows, on null/empty input, or when the call fails.
+    /// Unlike <see cref="System.IO.Path.GetFullPath(string)"/>, this resolves symlinks against the real
+    /// filesystem without mutating process-global state, so it is safe to call from any thread.
+    /// </summary>
+    internal static string RealPath(string path)
+    {
+        if (IsWindows || string.IsNullOrEmpty(path))
+        {
+            return null;
+        }
+
+        IntPtr ptr = IntPtr.Zero;
+        try
+        {
+            ptr = realpath_native(path, IntPtr.Zero);
+            if (ptr == IntPtr.Zero)
+            {
+                return null;
+            }
+
+            return Marshal.PtrToStringUTF8(ptr);
+        }
+        finally
+        {
+            if (ptr != IntPtr.Zero)
+            {
+                // realpath() with NULL second arg returns a malloc()'d buffer; caller must free().
+                // Free it through libc's free() - the same library realpath() allocated it from -
+                // rather than relying on the managed runtime's allocator matching that libc.
+                free_native(ptr);
+            }
+        }
+    }
+#else
+    /// <summary>
+    /// .NET Framework builds of MSBuild only ship for Windows, where POSIX <c>realpath(3)</c> does not
+    /// exist, so this is always a no-op returning <c>null</c>.
+    /// </summary>
+    internal static string RealPath(string path) => null;
+#endif
+
 #if FEATURE_WINDOWSINTEROP
     [SupportedOSPlatform("windows6.1")]
     internal static unsafe bool SetThreadErrorMode(int newMode, out int oldMode)

Local adaptation notes

Only QueryIsScreenAndTryEnableAnsiColorCodes and its console-mode P/Invokes are copied from msbuild's Framework NativeMethods.

How to reconcile

  1. Review the upstream changes and decide whether they should be ported.
  2. Port the relevant changes to src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NativeMethods.cs.
  3. Update eng/vendored-files.json entry platform-terminal-native-methods (source index 0):
    • bump baseline_ref_sha to the new upstream ref SHA,
    • bump baseline_blob_sha to the new upstream blob SHA.
  4. Close this issue once the reconciliation PR is merged.

If no port is needed (e.g. whitespace-only upstream change), still bump the baseline SHAs to silence future runs.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/vendored-syncDrift detected between a vendored source file and its upstream copy

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions