C#idiomatic C#
ca2101fundamentals/code-analysis/quality-rules

Code analysis

CA2101: Specify marshalling for P/Invoke string arguments

Learn about code analysis rule CA2101: Specify marshalling for P-Invoke string arguments

CA2101 Globalization enabled by default in .NET 10: As suggestion
Fix is breaking or non-breaking Non-breakingApplicable languages C# and Visual Basic

Cause

A platform invoke member allows for partially trusted callers, has a string parameter, and does not explicitly marshal the string.

Rule description

When you convert from Unicode to ANSI, it is possible that not all Unicode characters can be represented in a specific ANSI code page. Best-fit mapping tries to solve this problem by substituting a character for the character that cannot be represented. The use of this feature can cause a potential security vulnerability because you cannot control the character that is chosen. For example, malicious code could intentionally create a Unicode string that contains characters that are not found in a particular code page, which are converted to file system special characters such as '..' or '/'. Note also that security checks for special characters frequently occur before the string is converted to ANSI.

Best-fit mapping is the default for the unmanaged conversion, WChar to MByte. Unless you explicitly disable best-fit mapping, your code might contain an exploitable security vulnerability because of this issue.

How to fix violations

To fix a violation of this rule, explicitly marshal string data types.

When to suppress warnings

Do not suppress a warning from this rule.

Example

The following example shows a method that violates this rule, and then shows how to fix the violation.

sample · csharpdocs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/ca2101.cssnippet1

csharp
using System;
using System.Runtime.InteropServices;

namespace ca2101
{
    //<snippet1>
    class NativeMethods
    {
        // Violates rule: SpecifyMarshalingForPInvokeStringArguments.
        [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
        internal static extern int RegCreateKey(IntPtr key, String subKey, out IntPtr result);

        // Satisfies rule: SpecifyMarshalingForPInvokeStringArguments.
        [DllImport("advapi32.dll", CharSet = CharSet.Unicode)]
        internal static extern int RegCreateKey2(IntPtr key, String subKey, out IntPtr result);
    }
    //</snippet1>
}

sample · vbdocs/fundamentals/code-analysis/quality-rules/snippets/vb/all-rules/ca2101.vbsnippet2

vb
Imports System
Imports System.Runtime.InteropServices

Namespace ca2101
    '<snippet2>
    Friend Class NativeMethods
        ' Violates rule: SpecifyMarshalingForPInvokeStringArguments.
        <DllImport("advapi32.dll", CharSet:=CharSet.Auto)>
        Friend Shared Function RegCreateKey(ByVal key As IntPtr, ByVal subKey As String, <Out> ByRef result As IntPtr) As Integer
        End Function

        ' Satisfies rule: SpecifyMarshalingForPInvokeStringArguments.
        <DllImport("advapi32.dll", CharSet:=CharSet.Unicode)>
        Friend Shared Function RegCreateKey2(ByVal key As IntPtr, ByVal subKey As String, <Out> ByRef result As IntPtr) As Integer
        End Function
    End Class
    '</snippet2>
End Namespace