Fix incorrect string length calculation (#76127)
authorSparin <sparin285@gmail.com>
Tue, 27 Sep 2022 15:33:33 +0000 (18:33 +0300)
committerGitHub <noreply@github.com>
Tue, 27 Sep 2022 15:33:33 +0000 (08:33 -0700)
ANSI string depends on system encoding charset. Unix's implementation of Marshal.StringToHGlobalAnsi encodes in UTF8. UTF8 characters which are out of 8-bit range (otcet) encodes in multiple bytes (otcets). ASCII characters usually are in 0x00-0x7F range but cyrillic and other characters are not. For example, 'Зфыы123;' (eq. 'Pass123$') will be encoded in 12 bytes instead of 8

Fix #76125

src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/LdapPal.Linux.cs

index c751636..e2fd327 100644 (file)
@@ -120,7 +120,7 @@ namespace System.DirectoryServices.Protocols
         // This option is not supported in Linux, so it would most likely throw.
         internal static int SetServerCertOption(ConnectionHandle ldapHandle, LdapOption option, VERIFYSERVERCERT outValue) => Interop.Ldap.ldap_set_option_servercert(ldapHandle, option, outValue);
 
-        internal static int BindToDirectory(ConnectionHandle ld, string who, string passwd)
+        internal static unsafe int BindToDirectory(ConnectionHandle ld, string who, string passwd)
         {
             IntPtr passwordPtr = IntPtr.Zero;
             try
@@ -128,7 +128,7 @@ namespace System.DirectoryServices.Protocols
                 passwordPtr = LdapPal.StringToPtr(passwd);
                 BerVal passwordBerval = new BerVal
                 {
-                    bv_len = passwd?.Length ?? 0,
+                    bv_len = MemoryMarshal.CreateReadOnlySpanFromNullTerminated((byte*)passwordPtr).Length,
                     bv_val = passwordPtr,
                 };