Skip to content

Commit 0e9ec23

Browse files
Copilotjkotas
andauthored
Replace calls to Marshal.PtrToStringUTF8 methods with Utf8StringMarshaller and improve type consistency (#118862)
Fixes #118861 Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: Jan Kotas <[email protected]>
1 parent 80c8bb7 commit 0e9ec23

File tree

45 files changed

+154
-117
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+154
-117
lines changed

src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using System.Runtime.CompilerServices;
1313
using System.Runtime.ExceptionServices;
1414
using System.Runtime.InteropServices;
15+
using System.Runtime.InteropServices.Marshalling;
1516
using System.Runtime.Versioning;
1617
using System.Threading;
1718

@@ -870,7 +871,7 @@ internal struct GCConfigurationContext
870871
}
871872

872873
[UnmanagedCallersOnly]
873-
private static unsafe void ConfigCallback(void* configurationContext, void* name, void* publicKey, GCConfigurationType type, long data)
874+
private static unsafe void ConfigCallback(void* configurationContext, byte* name, byte* publicKey, GCConfigurationType type, long data)
874875
{
875876
// If the public key is null, it means that the corresponding configuration isn't publicly available
876877
// and therefore, we shouldn't add it to the configuration dictionary to return to the user.
@@ -886,7 +887,7 @@ private static unsafe void ConfigCallback(void* configurationContext, void* name
886887
Debug.Assert(context.Configurations != null);
887888
Dictionary<string, object> configurationDictionary = context.Configurations;
888889

889-
string nameAsString = Marshal.PtrToStringUTF8((IntPtr)name)!;
890+
string nameAsString = Utf8StringMarshaller.ConvertToManaged(name)!;
890891
switch (type)
891892
{
892893
case GCConfigurationType.Int64:
@@ -895,7 +896,7 @@ private static unsafe void ConfigCallback(void* configurationContext, void* name
895896

896897
case GCConfigurationType.StringUtf8:
897898
{
898-
string? dataAsString = Marshal.PtrToStringUTF8((nint)data);
899+
string? dataAsString = Utf8StringMarshaller.ConvertToManaged((byte*)data);
899900
configurationDictionary[nameAsString] = dataAsString ?? string.Empty;
900901
break;
901902
}
@@ -931,7 +932,7 @@ internal enum GCConfigurationType
931932
}
932933

933934
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "GCInterface_EnumerateConfigurationValues")]
934-
internal static unsafe partial void _EnumerateConfigurationValues(void* configurationDictionary, delegate* unmanaged<void*, void*, void*, GCConfigurationType, long, void> callback);
935+
internal static unsafe partial void _EnumerateConfigurationValues(void* configurationDictionary, delegate* unmanaged<void*, byte*, byte*, GCConfigurationType, long, void> callback);
935936

936937
internal enum RefreshMemoryStatus
937938
{

src/coreclr/gc/gcconfig.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,18 +47,18 @@ GC_CONFIGURATION_KEYS
4747
void GCConfig::EnumerateConfigurationValues(void* context, ConfigurationValueFunc configurationValueFunc)
4848
{
4949
#define INT_CONFIG(name, unused_private_key, public_key, unused_default, unused_doc) \
50-
configurationValueFunc(context, (void*)(#name), (void*)(public_key), GCConfigurationType::Int64, static_cast<int64_t>(s_Updated##name));
50+
configurationValueFunc(context, #name, public_key, GCConfigurationType::Int64, static_cast<int64_t>(s_Updated##name));
5151

5252
#define STRING_CONFIG(name, private_key, public_key, unused_doc) \
5353
{ \
5454
const char* resultStr = nullptr; \
5555
GCToEEInterface::GetStringConfigValue(private_key, public_key, &resultStr); \
5656
GCConfigStringHolder holder(resultStr); \
57-
configurationValueFunc(context, (void*)(#name), (void*)(public_key), GCConfigurationType::StringUtf8, reinterpret_cast<int64_t>(resultStr)); \
57+
configurationValueFunc(context, #name, public_key, GCConfigurationType::StringUtf8, reinterpret_cast<int64_t>(resultStr)); \
5858
}
5959

6060
#define BOOL_CONFIG(name, unused_private_key, public_key, unused_default, unused_doc) \
61-
configurationValueFunc(context, (void*)(#name), (void*)(public_key), GCConfigurationType::Boolean, static_cast<int64_t>(s_Updated##name));
61+
configurationValueFunc(context, #name, public_key, GCConfigurationType::Boolean, static_cast<int64_t>(s_Updated##name));
6262

6363
GC_CONFIGURATION_KEYS
6464

src/coreclr/gc/gcinterface.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ enum class GCConfigurationType
641641
Boolean
642642
};
643643

644-
using ConfigurationValueFunc = void (*)(void* context, void* name, void* publicKey, GCConfigurationType type, int64_t data);
644+
using ConfigurationValueFunc = void (*)(void* context, const char* name, const char* publicKey, GCConfigurationType type, int64_t data);
645645

646646
// IGCHeap is the interface that the VM will use when interacting with the GC.
647647
// NOTE!

src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.NativeAot.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using System.Runtime;
1111
using System.Runtime.CompilerServices;
1212
using System.Runtime.InteropServices;
13+
using System.Runtime.InteropServices.Marshalling;
1314
using System.Threading;
1415

1516
using Internal.Runtime;
@@ -648,7 +649,7 @@ internal struct GCConfigurationContext
648649
}
649650

650651
[UnmanagedCallersOnly]
651-
private static unsafe void ConfigCallback(void* configurationContext, void* name, void* publicKey, RuntimeImports.GCConfigurationType type, long data)
652+
private static unsafe void ConfigCallback(void* configurationContext, byte* name, byte* publicKey, RuntimeImports.GCConfigurationType type, long data)
652653
{
653654
// If the public key is null, it means that the corresponding configuration isn't publicly available
654655
// and therefore, we shouldn't add it to the configuration dictionary to return to the user.
@@ -664,7 +665,7 @@ private static unsafe void ConfigCallback(void* configurationContext, void* name
664665
Debug.Assert(context.Configurations != null);
665666
Dictionary<string, object> configurationDictionary = context.Configurations!;
666667

667-
string nameAsString = Marshal.PtrToStringUTF8((IntPtr)name)!;
668+
string nameAsString = Utf8StringMarshaller.ConvertToManaged(name)!;
668669
switch (type)
669670
{
670671
case RuntimeImports.GCConfigurationType.Int64:
@@ -673,7 +674,7 @@ private static unsafe void ConfigCallback(void* configurationContext, void* name
673674

674675
case RuntimeImports.GCConfigurationType.StringUtf8:
675676
{
676-
string? dataAsString = Marshal.PtrToStringUTF8((nint)data);
677+
string? dataAsString = Utf8StringMarshaller.ConvertToManaged((byte*)data);
677678
configurationDictionary[nameAsString] = dataAsString ?? string.Empty;
678679
break;
679680
}

src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ internal enum GCConfigurationType
209209
}
210210

211211
[LibraryImport(RuntimeLibrary)]
212-
internal static unsafe partial void RhEnumerateConfigurationValues(void* configurationContext, delegate* unmanaged<void*, void*, void*, GCConfigurationType, long, void> callback);
212+
internal static unsafe partial void RhEnumerateConfigurationValues(void* configurationContext, delegate* unmanaged<void*, byte*, byte*, GCConfigurationType, long, void> callback);
213213

214214
internal struct GCHeapHardLimitInfo
215215
{

src/coreclr/vm/comutilnative.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ typedef GCMemoryInfoData * GCMEMORYINFODATA;
139139
typedef GCMemoryInfoData * GCMEMORYINFODATAREF;
140140
#endif // USE_CHECKED_OBJECTREFS
141141

142-
using EnumerateConfigurationValuesCallback = void (*)(void* context, void* name, void* publicKey, GCConfigurationType type, int64_t data);
142+
using EnumerateConfigurationValuesCallback = void (*)(void* context, const char* name, const char* publicKey, GCConfigurationType type, int64_t data);
143143

144144
struct GCHeapHardLimitInfo
145145
{

src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Err.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using System.Diagnostics;
66
using System.Runtime.InteropServices;
7+
using System.Runtime.InteropServices.Marshalling;
78
using System.Security.Cryptography;
89

910
internal static partial class Interop
@@ -34,7 +35,7 @@ private static unsafe string ErrErrorStringN(ulong error)
3435
fixed (byte* buf = &buffer[0])
3536
{
3637
ErrErrorStringN(error, buf, buffer.Length);
37-
return Marshal.PtrToStringUTF8((IntPtr)buf)!;
38+
return Utf8StringMarshaller.ConvertToManaged(buf)!;
3839
}
3940
}
4041

src/libraries/Common/src/Interop/FreeBSD/Interop.Process.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.ComponentModel;
77
using System.Diagnostics;
88
using System.Runtime.InteropServices;
9+
using System.Runtime.InteropServices.Marshalling;
910

1011
#pragma warning disable CA1823 // analyzer incorrectly flags fixed buffer length const (https://github.com/dotnet/roslyn/issues/37593)
1112

@@ -117,7 +118,7 @@ public static unsafe ProcessInfo GetProcessInfoById(int pid)
117118
// Get the process information for the specified pid
118119
info = new ProcessInfo();
119120

120-
info.ProcessName = Marshal.PtrToStringUTF8((IntPtr)kinfo->ki_comm)!;
121+
info.ProcessName = Utf8StringMarshaller.ConvertToManaged(kinfo->ki_comm)!;
121122
info.BasePriority = kinfo->ki_nice;
122123
info.VirtualBytes = (long)kinfo->ki_size;
123124
info.WorkingSet = kinfo->ki_rssize;

src/libraries/Common/src/Interop/OSX/Interop.CoreFoundation.CFString.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using System.Diagnostics;
66
using System.Runtime.InteropServices;
7+
using System.Runtime.InteropServices.Marshalling;
78
using System.Text;
89
using Microsoft.Win32.SafeHandles;
910

@@ -16,7 +17,7 @@ internal static partial class CoreFoundation
1617
/// If it has the wrong encoding, or if the interior pointer isn't being shared for some reason, returns NULL
1718
/// </summary>
1819
[LibraryImport(Libraries.CoreFoundationLibrary)]
19-
private static partial IntPtr CFStringGetCStringPtr(
20+
private static unsafe partial byte* CFStringGetCStringPtr(
2021
SafeCFStringHandle cfString,
2122
CFStringBuiltInEncodings encoding);
2223

@@ -27,7 +28,7 @@ private static partial SafeCFDataHandle CFStringCreateExternalRepresentation(
2728
CFStringBuiltInEncodings encoding,
2829
byte lossByte);
2930

30-
internal static string CFStringToString(SafeCFStringHandle cfString)
31+
internal static unsafe string CFStringToString(SafeCFStringHandle cfString)
3132
{
3233
Debug.Assert(cfString != null);
3334
Debug.Assert(!cfString.IsInvalid);
@@ -36,13 +37,13 @@ internal static string CFStringToString(SafeCFStringHandle cfString)
3637
// If the string is already stored internally as UTF-8 we can (usually)
3738
// get the raw pointer to the data blob, then we can Marshal in the string
3839
// via pointer semantics, avoiding a copy.
39-
IntPtr interiorPointer = CFStringGetCStringPtr(
40+
byte* interiorPointer = CFStringGetCStringPtr(
4041
cfString,
4142
CFStringBuiltInEncodings.kCFStringEncodingUTF8);
4243

43-
if (interiorPointer != IntPtr.Zero)
44+
if (interiorPointer != null)
4445
{
45-
return Marshal.PtrToStringUTF8(interiorPointer)!;
46+
return Utf8StringMarshaller.ConvertToManaged(interiorPointer)!;
4647
}
4748

4849
SafeCFDataHandle cfData = CFStringCreateExternalRepresentation(

src/libraries/Common/src/Interop/OSX/Interop.NetworkFramework.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using System.Runtime.InteropServices;
6+
using System.Runtime.InteropServices.Marshalling;
67
using Microsoft.Win32.SafeHandles;
78

89
internal static partial class Interop
@@ -62,21 +63,21 @@ public override string ToString()
6263
}
6364

6465
[StructLayout(LayoutKind.Sequential)]
65-
internal struct NetworkFrameworkError
66+
internal unsafe struct NetworkFrameworkError
6667
{
6768
public int ErrorCode;
6869
public int ErrorDomain;
69-
public IntPtr ErrorMessage; // C string of NULL
70+
public byte* ErrorMessage; // C string of NULL
7071
}
7172

72-
internal static Exception CreateExceptionForNetworkFrameworkError(in NetworkFrameworkError error)
73+
internal static unsafe Exception CreateExceptionForNetworkFrameworkError(in NetworkFrameworkError error)
7374
{
7475
string? message = null;
7576
NetworkFrameworkErrorDomain domain = (NetworkFrameworkErrorDomain)error.ErrorDomain;
7677

77-
if (error.ErrorMessage != IntPtr.Zero)
78+
if (error.ErrorMessage != null)
7879
{
79-
message = Marshal.PtrToStringUTF8(error.ErrorMessage);
80+
message = Utf8StringMarshaller.ConvertToManaged(error.ErrorMessage);
8081
}
8182

8283
return new NetworkFrameworkException(error.ErrorCode, domain, message);

0 commit comments

Comments
 (0)