From 3215d25965d9b27c267d201ad95450c2bc570283 Mon Sep 17 00:00:00 2001 From: Sergey Date: Wed, 31 Mar 2021 19:28:28 -0700 Subject: [PATCH 1/4] Reenable the tests. --- .../tests/AsqRequestControlTests.cs | 1 - .../tests/BerConversionExceptionTests.cs | 1 - .../tests/BerConverterTests.cs | 1 - .../tests/DirSyncRequestControlTests.cs | 1 - .../tests/DirectoryControlTests.cs | 1 - .../tests/DirectoryServicesProtocolsTests.cs | 1 - .../tests/ExtendedDNControlTests.cs | 1 - .../tests/PageResultRequestControlTests.cs | 1 - .../tests/QuotaControlTests.cs | 1 - .../tests/SearchOptionsControlTests.cs | 1 - .../tests/SecurityDescriptorFlagControlTests.cs | 1 - .../tests/VerifyNameControlTests.cs | 1 - .../tests/VlvRequestControlTests.cs | 1 - 13 files changed, 13 deletions(-) diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/AsqRequestControlTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/AsqRequestControlTests.cs index 6391870ef11aac..d2704307152d5a 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/AsqRequestControlTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/AsqRequestControlTests.cs @@ -8,7 +8,6 @@ namespace System.DirectoryServices.Protocols.Tests { [ConditionalClass(typeof(DirectoryServicesTestHelpers), nameof(DirectoryServicesTestHelpers.IsWindowsOrLibLdapIsInstalled))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/49105", typeof(PlatformDetection), nameof(PlatformDetection.IsMacOsAppleSilicon))] public class AsqRequestControlTests { [Fact] diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/BerConversionExceptionTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/BerConversionExceptionTests.cs index 4a474ec57eae18..b0a47bad6fe645 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/BerConversionExceptionTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/BerConversionExceptionTests.cs @@ -9,7 +9,6 @@ namespace System.DirectoryServices.Protocols.Tests { - [ActiveIssue("https://github.com/dotnet/runtime/issues/49105", typeof(PlatformDetection), nameof(PlatformDetection.IsMacOsAppleSilicon))] public class BerConversionExceptionTests { [Fact] diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/BerConverterTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/BerConverterTests.cs index d636a889898813..d47ecba69a09c8 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/BerConverterTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/BerConverterTests.cs @@ -9,7 +9,6 @@ namespace System.DirectoryServices.Protocols.Tests { [ConditionalClass(typeof(DirectoryServicesTestHelpers), nameof(DirectoryServicesTestHelpers.IsWindowsOrLibLdapIsInstalled))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/49105", typeof(PlatformDetection), nameof(PlatformDetection.IsMacOsAppleSilicon))] public class BerConverterTests { public static IEnumerable Encode_TestData() diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/DirSyncRequestControlTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/DirSyncRequestControlTests.cs index 847f482176d7db..da6bcfbdf5b691 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/DirSyncRequestControlTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/DirSyncRequestControlTests.cs @@ -8,7 +8,6 @@ namespace System.DirectoryServices.Protocols.Tests { [ConditionalClass(typeof(DirectoryServicesTestHelpers), nameof(DirectoryServicesTestHelpers.IsWindowsOrLibLdapIsInstalled))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/49105", typeof(PlatformDetection), nameof(PlatformDetection.IsMacOsAppleSilicon))] public class DirSyncRequestControlTests { [Fact] diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryControlTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryControlTests.cs index 4f79e81c83ec1f..32d2b36f062493 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryControlTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryControlTests.cs @@ -5,7 +5,6 @@ namespace System.DirectoryServices.Protocols.Tests { - [ActiveIssue("https://github.com/dotnet/runtime/issues/49105", typeof(PlatformDetection), nameof(PlatformDetection.IsMacOsAppleSilicon))] public class DirectoryControlTests { [Theory] diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryServicesProtocolsTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryServicesProtocolsTests.cs index 1329fa83a6cfff..00d56e12bc8d19 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryServicesProtocolsTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryServicesProtocolsTests.cs @@ -10,7 +10,6 @@ namespace System.DirectoryServices.Protocols.Tests { - [ActiveIssue("https://github.com/dotnet/runtime/issues/49105", typeof(PlatformDetection), nameof(PlatformDetection.IsMacOsAppleSilicon))] public partial class DirectoryServicesProtocolsTests { internal static bool IsLdapConfigurationExist => LdapConfiguration.Configuration != null; diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/ExtendedDNControlTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/ExtendedDNControlTests.cs index a7c571598d7c29..284d916613b238 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/ExtendedDNControlTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/ExtendedDNControlTests.cs @@ -8,7 +8,6 @@ namespace System.DirectoryServices.Protocols.Tests { [ConditionalClass(typeof(DirectoryServicesTestHelpers), nameof(DirectoryServicesTestHelpers.IsWindowsOrLibLdapIsInstalled))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/49105", typeof(PlatformDetection), nameof(PlatformDetection.IsMacOsAppleSilicon))] public class ExtendedDNControlTests { [Fact] diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/PageResultRequestControlTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/PageResultRequestControlTests.cs index e6f10e4bddc7ec..537874c7f4fbd7 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/PageResultRequestControlTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/PageResultRequestControlTests.cs @@ -8,7 +8,6 @@ namespace System.DirectoryServices.Protocols.Tests { [ConditionalClass(typeof(DirectoryServicesTestHelpers), nameof(DirectoryServicesTestHelpers.IsWindowsOrLibLdapIsInstalled))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/49105", typeof(PlatformDetection), nameof(PlatformDetection.IsMacOsAppleSilicon))] public class PageResultRequestControlTests { [Fact] diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/QuotaControlTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/QuotaControlTests.cs index 033865e1353d95..b1ddaa9efa8e88 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/QuotaControlTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/QuotaControlTests.cs @@ -9,7 +9,6 @@ namespace System.DirectoryServices.Protocols.Tests { [ConditionalClass(typeof(DirectoryServicesTestHelpers), nameof(DirectoryServicesTestHelpers.IsWindowsOrLibLdapIsInstalled))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/49105", typeof(PlatformDetection), nameof(PlatformDetection.IsMacOsAppleSilicon))] public class QuotaControlTests { [Fact] diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/SearchOptionsControlTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/SearchOptionsControlTests.cs index c173904caaaef5..2a30d7dc3a522a 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/SearchOptionsControlTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/SearchOptionsControlTests.cs @@ -8,7 +8,6 @@ namespace System.DirectoryServices.Protocols.Tests { [ConditionalClass(typeof(DirectoryServicesTestHelpers), nameof(DirectoryServicesTestHelpers.IsWindowsOrLibLdapIsInstalled))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/49105", typeof(PlatformDetection), nameof(PlatformDetection.IsMacOsAppleSilicon))] public class SearchOptionsControlTests { [Fact] diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/SecurityDescriptorFlagControlTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/SecurityDescriptorFlagControlTests.cs index 47ceca06e70a51..6ec7955faa782b 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/SecurityDescriptorFlagControlTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/SecurityDescriptorFlagControlTests.cs @@ -8,7 +8,6 @@ namespace System.DirectoryServices.Protocols.Tests { [ConditionalClass(typeof(DirectoryServicesTestHelpers), nameof(DirectoryServicesTestHelpers.IsWindowsOrLibLdapIsInstalled))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/49105", typeof(PlatformDetection), nameof(PlatformDetection.IsMacOsAppleSilicon))] public class SecurityDescriptorFlagControlTests { [Fact] diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/VerifyNameControlTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/VerifyNameControlTests.cs index c6edf3487253d5..5e7469d27ed01c 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/VerifyNameControlTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/VerifyNameControlTests.cs @@ -8,7 +8,6 @@ namespace System.DirectoryServices.Protocols.Tests { [ConditionalClass(typeof(DirectoryServicesTestHelpers), nameof(DirectoryServicesTestHelpers.IsWindowsOrLibLdapIsInstalled))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/49105", typeof(PlatformDetection), nameof(PlatformDetection.IsMacOsAppleSilicon))] public class VerifyNameControlTests { [Fact] diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/VlvRequestControlTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/VlvRequestControlTests.cs index 4ea87e1a5f6ec8..a259bd11c7e8aa 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/VlvRequestControlTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/VlvRequestControlTests.cs @@ -8,7 +8,6 @@ namespace System.DirectoryServices.Protocols.Tests { [ConditionalClass(typeof(DirectoryServicesTestHelpers), nameof(DirectoryServicesTestHelpers.IsWindowsOrLibLdapIsInstalled))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/49105", typeof(PlatformDetection), nameof(PlatformDetection.IsMacOsAppleSilicon))] public class VlvRequestControlTests { [Fact] From b35e7d8cac736700fe29392b2395a667f0e0e991 Mon Sep 17 00:00:00 2001 From: Sergey Date: Tue, 13 Apr 2021 16:13:22 -0700 Subject: [PATCH 2/4] Use __arglist for windows. Use ber_put_*/ber_get_* for Unix --- .../src/Interop/Linux/OpenLdap/Interop.Ber.cs | 194 ++++++++++++++++-- .../Interop/Windows/Wldap32/Interop.Ber.cs | 22 +- .../Protocols/Interop/BerPal.Linux.cs | 14 +- .../Protocols/Interop/BerPal.Windows.cs | 20 +- .../Protocols/common/BerConverter.cs | 69 +++++-- .../tests/BerConverterTests.cs | 13 +- 6 files changed, 267 insertions(+), 65 deletions(-) diff --git a/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ber.cs b/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ber.cs index 9dc20b7f4eb062..830e56c0562482 100644 --- a/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ber.cs +++ b/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ber.cs @@ -4,11 +4,14 @@ using System; using System.Runtime.InteropServices; using System.DirectoryServices.Protocols; +using System.Diagnostics; internal static partial class Interop { internal static partial class Ldap { + private const int ber_default_successful_return_code = 0; + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_alloc_t", CharSet = CharSet.Ansi)] public static extern IntPtr ber_alloc(int option); @@ -18,17 +21,105 @@ internal static partial class Ldap [DllImport(Libraries.OpenLdap, EntryPoint = "ber_free", CharSet = CharSet.Ansi)] public static extern IntPtr ber_free([In] IntPtr berelement, int option); - [DllImport(Libraries.OpenLdap, EntryPoint = "ber_printf", CharSet = CharSet.Ansi)] - public static extern int ber_printf_emptyarg(SafeBerHandle berElement, string format); + public static int ber_printf_emptyarg(SafeBerHandle berElement, string format, int tag) + { + if (format == "{") + { + return ber_start_seq(berElement, tag); + } + else if (format == "}") + { + return ber_put_seq(berElement, tag); + } + else if (format == "[") + { + return ber_start_set(berElement, tag); + } + else if (format == "]") + { + return ber_put_set(berElement, tag); + } + else + { + Debug.Assert(format == "n"); + return ber_put_null(berElement, tag); + } + } + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_start_seq", CharSet = CharSet.Ansi)] + public static extern int ber_start_seq(SafeBerHandle berElement, int tag); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_start_set", CharSet = CharSet.Ansi)] + public static extern int ber_start_set(SafeBerHandle berElement, int tag); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_put_seq", CharSet = CharSet.Ansi)] + public static extern int ber_put_seq(SafeBerHandle berElement, int tag); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_put_set", CharSet = CharSet.Ansi)] + public static extern int ber_put_set(SafeBerHandle berElement, int tag); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_put_null", CharSet = CharSet.Ansi)] + public static extern int ber_put_null(SafeBerHandle berElement, int tag); + + + public static int ber_printf_tag(SafeBerHandle berElement, string format, int tag) + { + // Ber Linux tags are passed with the values that they affect, like `ber_printf_int(.., tag)`. + // So this function does nothing on Linux. + return ber_default_successful_return_code; + } + + public static int ber_printf_int(SafeBerHandle berElement, string format, int value, int tag) + { + if (format == "i") + { + return ber_put_int(berElement, value, tag); + } + else if (format == "e") + { + return ber_put_enum(berElement, value, tag); + } + else + { + Debug.Assert(format == "b"); + return ber_put_boolean(berElement, value, tag); + } + } + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_put_int", CharSet = CharSet.Ansi)] + public static extern int ber_put_int(SafeBerHandle berElement, int value, int tag); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_put_enum", CharSet = CharSet.Ansi)] + public static extern int ber_put_enum(SafeBerHandle berElement, int value, int tag); - [DllImport(Libraries.OpenLdap, EntryPoint = "ber_printf", CharSet = CharSet.Ansi)] - public static extern int ber_printf_int(SafeBerHandle berElement, string format, int value); + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_put_boolean", CharSet = CharSet.Ansi)] + public static extern int ber_put_boolean(SafeBerHandle berElement, int value, int tag); - [DllImport(Libraries.OpenLdap, EntryPoint = "ber_printf", CharSet = CharSet.Ansi)] - public static extern int ber_printf_bytearray(SafeBerHandle berElement, string format, HGlobalMemHandle value, int length); + public static int ber_printf_bytearray(SafeBerHandle berElement, string format, HGlobalMemHandle value, int length, int tag) + { + if (format == "o") + { + return ber_put_ostring(berElement, value, length, tag); + } + else if (format == "s") + { + return ber_put_string(berElement, value, tag); + } + else + { + Debug.Assert(format == "X"); + return ber_put_bitstring(berElement, value, length, tag); + } + } - [DllImport(Libraries.OpenLdap, EntryPoint = "ber_printf", CharSet = CharSet.Ansi)] - public static extern int ber_printf_berarray(SafeBerHandle berElement, string format, IntPtr value); + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_put_ostring", CharSet = CharSet.Ansi)] + private static extern int ber_put_ostring(SafeBerHandle berElement, HGlobalMemHandle value, int length, int tag); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_put_string", CharSet = CharSet.Ansi)] + private static extern int ber_put_string(SafeBerHandle berElement, HGlobalMemHandle value, int tag); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_put_bitstring", CharSet = CharSet.Ansi)] + private static extern int ber_put_bitstring(SafeBerHandle berElement, HGlobalMemHandle value, int length, int tag); [DllImport(Libraries.OpenLdap, EntryPoint = "ber_flatten", CharSet = CharSet.Ansi)] public static extern int ber_flatten(SafeBerHandle berElement, ref IntPtr value); @@ -39,16 +130,87 @@ internal static partial class Ldap [DllImport(Libraries.OpenLdap, EntryPoint = "ber_bvecfree", CharSet = CharSet.Ansi)] public static extern int ber_bvecfree(IntPtr value); - [DllImport(Libraries.OpenLdap, EntryPoint = "ber_scanf", CharSet = CharSet.Ansi)] - public static extern int ber_scanf(SafeBerHandle berElement, string format); + public static int ber_scanf_emptyarg(SafeBerHandle berElement, string format) + { + Debug.Assert(format == "{" || format == "}" || format == "[" || format == "]" || format == "n" || format == "x"); + if (format == "{" || format == "[") + { + int len = 0; + return ber_skip_tag(berElement, ref len); + } + else if (format == "]" || format == "}") + { + return ber_default_successful_return_code; + } + else + { + Debug.Assert(format == "n" || format == "x"); + return ber_get_null(berElement); + } + } + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_skip_tag", CharSet = CharSet.Ansi)] + private static extern int ber_skip_tag(SafeBerHandle berElement, ref int len); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_get_null", CharSet = CharSet.Ansi)] + private static extern int ber_get_null(SafeBerHandle berElement); + + public static int ber_scanf_int(SafeBerHandle berElement, string format, ref int value) + { + if (format == "i") + { + return ber_get_int(berElement, ref value); + } + else if (format == "e") + { + return ber_get_enum(berElement, ref value); + } + else + { + Debug.Assert(format == "b"); + return ber_get_boolean(berElement, ref value); + } + } + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_get_int", CharSet = CharSet.Ansi)] + private static extern int ber_get_int(SafeBerHandle berElement, ref int value); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_get_enum", CharSet = CharSet.Ansi)] + private static extern int ber_get_enum(SafeBerHandle berElement, ref int value); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_get_boolean", CharSet = CharSet.Ansi)] + private static extern int ber_get_boolean(SafeBerHandle berElement, ref int value); + + public static int ber_scanf_bitstring(SafeBerHandle berElement, string format, ref IntPtr value, ref int bitLength) + { + Debug.Assert(format == "B"); + return ber_get_stringb(berElement, ref value, ref bitLength); + } + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_get_stringb", CharSet = CharSet.Ansi)] + private static extern int ber_get_stringb(SafeBerHandle berElement, ref IntPtr value, ref int bitLength); + + public static int ber_scanf_ptr(SafeBerHandle berElement, string format, ref IntPtr value) + { + Debug.Assert(format == "O"); + return ber_get_stringal(berElement, ref value); + } - [DllImport(Libraries.OpenLdap, EntryPoint = "ber_scanf", CharSet = CharSet.Ansi)] - public static extern int ber_scanf_int(SafeBerHandle berElement, string format, ref int value); + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_get_stringal", CharSet = CharSet.Ansi)] + private static extern int ber_get_stringal(SafeBerHandle berElement, ref IntPtr value); - [DllImport(Libraries.OpenLdap, EntryPoint = "ber_scanf", CharSet = CharSet.Ansi)] - public static extern int ber_scanf_bitstring(SafeBerHandle berElement, string format, ref IntPtr value, ref int bitLength); + public static int ber_printf_berarray(SafeBerHandle berElement, string format, IntPtr value, int tag) + { + Debug.Assert(format == "v" || format == "V"); + // V and v are not supported on Unix yet. + return -1; + } - [DllImport(Libraries.OpenLdap, EntryPoint = "ber_scanf", CharSet = CharSet.Ansi)] - public static extern int ber_scanf_ptr(SafeBerHandle berElement, string format, ref IntPtr value); + public static int ber_scanf_multibytearray(SafeBerHandle berElement, string format, ref IntPtr value) + { + Debug.Assert(format == "v" || format == "V"); + // V and v are not supported on Unix yet. + return -1; + } } } diff --git a/src/libraries/Common/src/Interop/Windows/Wldap32/Interop.Ber.cs b/src/libraries/Common/src/Interop/Windows/Wldap32/Interop.Ber.cs index 99fec68cbcc733..0ba2c96ecf7575 100644 --- a/src/libraries/Common/src/Interop/Windows/Wldap32/Interop.Ber.cs +++ b/src/libraries/Common/src/Interop/Windows/Wldap32/Interop.Ber.cs @@ -16,16 +16,7 @@ internal static partial class Ldap public static extern IntPtr ber_alloc(int option); [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_printf", CharSet = CharSet.Unicode)] - public static extern int ber_printf_emptyarg(SafeBerHandle berElement, string format); - - [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_printf", CharSet = CharSet.Unicode)] - public static extern int ber_printf_int(SafeBerHandle berElement, string format, int value); - - [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_printf", CharSet = CharSet.Unicode)] - public static extern int ber_printf_bytearray(SafeBerHandle berElement, string format, HGlobalMemHandle value, int length); - - [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_printf", CharSet = CharSet.Unicode)] - public static extern int ber_printf_berarray(SafeBerHandle berElement, string format, IntPtr value); + public static extern int ber_printf(SafeBerHandle berElement, string format, __arglist); [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_flatten", CharSet = CharSet.Unicode)] public static extern int ber_flatten(SafeBerHandle berElement, ref IntPtr value); @@ -34,16 +25,7 @@ internal static partial class Ldap public static extern IntPtr ber_init(berval value); [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_scanf", CharSet = CharSet.Unicode)] - public static extern int ber_scanf(SafeBerHandle berElement, string format); - - [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_scanf", CharSet = CharSet.Unicode)] - public static extern int ber_scanf_int(SafeBerHandle berElement, string format, ref int value); - - [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_scanf", CharSet = CharSet.Unicode)] - public static extern int ber_scanf_ptr(SafeBerHandle berElement, string format, ref IntPtr value); - - [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_scanf", CharSet = CharSet.Unicode)] - public static extern int ber_scanf_bitstring(SafeBerHandle berElement, string format, ref IntPtr value, ref int bitLength); + public static extern int ber_scanf(SafeBerHandle berElement, string format, __arglist); [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_bvfree", CharSet = CharSet.Unicode)] public static extern int ber_bvfree(IntPtr value); diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Linux.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Linux.cs index b8856cf2d2bda2..359a973463d5f4 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Linux.cs +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Linux.cs @@ -13,15 +13,17 @@ internal static class BerPal internal static int FlattenBerElement(SafeBerHandle berElement, ref IntPtr flattenptr) => Interop.Ldap.ber_flatten(berElement, ref flattenptr); - internal static int PrintBerArray(SafeBerHandle berElement, string format, IntPtr value) => Interop.Ldap.ber_printf_berarray(berElement, format, value); + internal static int PrintBerArray(SafeBerHandle berElement, string format, IntPtr value, int tag) => Interop.Ldap.ber_printf_berarray(berElement, format, value, tag); - internal static int PrintByteArray(SafeBerHandle berElement, string format, HGlobalMemHandle value, int length) => Interop.Ldap.ber_printf_bytearray(berElement, format, value, length); + internal static int PrintByteArray(SafeBerHandle berElement, string format, HGlobalMemHandle value, int length, int tag) => Interop.Ldap.ber_printf_bytearray(berElement, format, value, length, tag); - internal static int PrintEmptyArgument(SafeBerHandle berElement, string format) => Interop.Ldap.ber_printf_emptyarg(berElement, format); + internal static int PrintEmptyArgument(SafeBerHandle berElement, string format, int tag) => Interop.Ldap.ber_printf_emptyarg(berElement, format, tag); - internal static int PrintInt(SafeBerHandle berElement, string format, int value) => Interop.Ldap.ber_printf_int(berElement, format, value); + internal static int PrintInt(SafeBerHandle berElement, string format, int value, int tag) => Interop.Ldap.ber_printf_int(berElement, format, value, tag); - internal static int ScanNext(SafeBerHandle berElement, string format) => Interop.Ldap.ber_scanf(berElement, format); + internal static int PrintTag(SafeBerHandle berElement, string format, int tag) => Interop.Ldap.ber_printf_tag(berElement, format, tag); + + internal static int ScanNext(SafeBerHandle berElement, string format) => Interop.Ldap.ber_scanf_emptyarg(berElement, format); internal static int ScanNextBitString(SafeBerHandle berElement, string format, ref IntPtr ptrResult, ref int bitLength) => Interop.Ldap.ber_scanf_bitstring(berElement, format, ref ptrResult, ref bitLength); @@ -29,6 +31,8 @@ internal static class BerPal internal static int ScanNextPtr(SafeBerHandle berElement, string format, ref IntPtr value) => Interop.Ldap.ber_scanf_ptr(berElement, format, ref value); + internal static int ScanNextMultiByteArray(SafeBerHandle berElement, string format, ref IntPtr value) => Interop.Ldap.ber_scanf_multibytearray(berElement, format, ref value); + internal static bool IsBerDecodeError(int errorCode) => errorCode == -1; } } diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Windows.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Windows.cs index 202737f2cb2815..99532610f6767e 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Windows.cs +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Windows.cs @@ -15,21 +15,25 @@ internal static class BerPal internal static int FlattenBerElement(SafeBerHandle berElement, ref IntPtr flattenptr) => Interop.Ldap.ber_flatten(berElement, ref flattenptr); - internal static int PrintBerArray(SafeBerHandle berElement, string format, IntPtr value) => Interop.Ldap.ber_printf_berarray(berElement, format, value); + internal static int PrintBerArray(SafeBerHandle berElement, string format, IntPtr value, int tag) => Interop.Ldap.ber_printf(berElement, format, __arglist(value)); - internal static int PrintByteArray(SafeBerHandle berElement, string format, HGlobalMemHandle value, int length) => Interop.Ldap.ber_printf_bytearray(berElement, format, value, length); + internal static int PrintByteArray(SafeBerHandle berElement, string format, HGlobalMemHandle value, int length, int tag) => Interop.Ldap.ber_printf(berElement, format, __arglist(value, length)); - internal static int PrintEmptyArgument(SafeBerHandle berElement, string format) => Interop.Ldap.ber_printf_emptyarg(berElement, format); + internal static int PrintEmptyArgument(SafeBerHandle berElement, string format, int tag) => Interop.Ldap.ber_printf(berElement, format, __arglist()); - internal static int PrintInt(SafeBerHandle berElement, string format, int value) => Interop.Ldap.ber_printf_int(berElement, format, value); + internal static int PrintInt(SafeBerHandle berElement, string format, int value, int tag) => Interop.Ldap.ber_printf(berElement, format, __arglist(value)); - internal static int ScanNext(SafeBerHandle berElement, string format) => Interop.Ldap.ber_scanf(berElement, format); + internal static int PrintTag(SafeBerHandle berElement, string format, int tag) => Interop.Ldap.ber_printf(berElement, format, __arglist(tag)); - internal static int ScanNextBitString(SafeBerHandle berElement, string format, ref IntPtr ptrResult, ref int bitLength) => Interop.Ldap.ber_scanf_bitstring(berElement, format, ref ptrResult, ref bitLength); + internal static int ScanNext(SafeBerHandle berElement, string format) => Interop.Ldap.ber_scanf(berElement, format, __arglist()); - internal static int ScanNextInt(SafeBerHandle berElement, string format, ref int result) => Interop.Ldap.ber_scanf_int(berElement, format, ref result); + internal static int ScanNextBitString(SafeBerHandle berElement, string format, ref IntPtr ptrResult, ref int bitLength) => Interop.Ldap.ber_scanf(berElement, format, __arglist(ref ptrResult, ref bitLength)); - internal static int ScanNextPtr(SafeBerHandle berElement, string format, ref IntPtr value) => Interop.Ldap.ber_scanf_ptr(berElement, format, ref value); + internal static int ScanNextInt(SafeBerHandle berElement, string format, ref int result) => Interop.Ldap.ber_scanf(berElement, format, __arglist(ref result)); + + internal static int ScanNextPtr(SafeBerHandle berElement, string format, ref IntPtr value) => Interop.Ldap.ber_scanf(berElement, format, __arglist(ref value)); + + internal static int ScanNextMultiByteArray(SafeBerHandle berElement, string format, ref IntPtr value) => Interop.Ldap.ber_scanf(berElement, format, __arglist(ref value)); internal static bool IsBerDecodeError(int errorCode) => errorCode != 0; } diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/BerConverter.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/BerConverter.cs index 058024fad909b9..36c94f297c6be4 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/BerConverter.cs +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/BerConverter.cs @@ -29,15 +29,29 @@ public static byte[] Encode(string format, params object[] value) int valueCount = 0; int error = 0; + + // We can't use vararg on Unix and can't do ber_printf(tag), so we use ber_put_int(val, tag) + // and this local keeps tag value for the next element. + int tag = 0; + bool tagIsSet = false; for (int formatCount = 0; formatCount < format.Length; formatCount++) { + if (tagIsSet) + { + tagIsSet = false; + } + else + { + const int lberTagDefault = -1; + tag = lberTagDefault; + } char fmt = format[formatCount]; if (fmt == '{' || fmt == '}' || fmt == '[' || fmt == ']' || fmt == 'n') { // no argument needed - error = BerPal.PrintEmptyArgument(berElement, new string(fmt, 1)); + error = BerPal.PrintEmptyArgument(berElement, new string(fmt, 1), tag); } - else if (fmt == 't' || fmt == 'i' || fmt == 'e') + else if (fmt == 'i' || fmt == 'e') { if (valueCount >= value.Length) { @@ -54,7 +68,7 @@ public static byte[] Encode(string format, params object[] value) } // one int argument - error = BerPal.PrintInt(berElement, new string(fmt, 1), (int)value[valueCount]); + error = BerPal.PrintInt(berElement, new string(fmt, 1), (int)value[valueCount], tag); // increase the value count valueCount++; @@ -76,7 +90,7 @@ public static byte[] Encode(string format, params object[] value) } // one int argument - error = BerPal.PrintInt(berElement, new string(fmt, 1), (bool)value[valueCount] ? 1 : 0); + error = BerPal.PrintInt(berElement, new string(fmt, 1), (bool)value[valueCount] ? 1 : 0, tag); // increase the value count valueCount++; @@ -104,7 +118,7 @@ public static byte[] Encode(string format, params object[] value) { tempValue = utf8Encoder.GetBytes((string)value[valueCount]); } - error = EncodingByteArrayHelper(berElement, tempValue, 'o'); + error = EncodingByteArrayHelper(berElement, tempValue, 'o', tag); // increase the value count valueCount++; @@ -128,7 +142,7 @@ public static byte[] Encode(string format, params object[] value) } byte[] tempValue = (byte[])value[valueCount]; - error = EncodingByteArrayHelper(berElement, tempValue, fmt); + error = EncodingByteArrayHelper(berElement, tempValue, fmt, tag); valueCount++; } @@ -164,11 +178,13 @@ public static byte[] Encode(string format, params object[] value) { tempValues[i] = utf8Encoder.GetBytes(s); } + error = EncodingByteArrayHelper(berElement, tempValues[i], 'o', tag); + if (error == -1) + { + break; + } } } - - error = EncodingMultiByteArrayHelper(berElement, tempValues, 'V'); - valueCount++; } else if (fmt == 'V') @@ -191,8 +207,31 @@ public static byte[] Encode(string format, params object[] value) byte[][] tempValue = (byte[][])value[valueCount]; - error = EncodingMultiByteArrayHelper(berElement, tempValue, fmt); + error = EncodingMultiByteArrayHelper(berElement, tempValue, fmt, tag); + + valueCount++; + } + else if (fmt == 't') + { + if (valueCount >= value.Length) + { + // we don't have enough argument for the format string + Debug.WriteLine("value argument is not valid, valueCount >= value.Length\n"); + throw new ArgumentException(SR.BerConverterNotMatch); + } + + if (!(value[valueCount] is int)) + { + // argument is wrong + Debug.WriteLine("type should be int\n"); + throw new ArgumentException(SR.BerConverterNotMatch); + } + tag = (int)value[valueCount]; + tagIsSet = true; + // It will set the tag on Windows and only check the tag on Unix. + error = BerPal.PrintTag(berElement, new string(fmt, 1), tag); + // increase the value count valueCount++; } else @@ -423,7 +462,7 @@ internal static object[] TryDecode(string format, byte[] value, out bool decodeS return decodeResult; } - private static int EncodingByteArrayHelper(SafeBerHandle berElement, byte[] tempValue, char fmt) + private static int EncodingByteArrayHelper(SafeBerHandle berElement, byte[] tempValue, char fmt, int tag) { int error = 0; @@ -433,12 +472,12 @@ private static int EncodingByteArrayHelper(SafeBerHandle berElement, byte[] temp IntPtr tmp = Marshal.AllocHGlobal(tempValue.Length); Marshal.Copy(tempValue, 0, tmp, tempValue.Length); HGlobalMemHandle memHandle = new HGlobalMemHandle(tmp); - error = BerPal.PrintByteArray(berElement, new string(fmt, 1), memHandle, tempValue.Length); + error = BerPal.PrintByteArray(berElement, new string(fmt, 1), memHandle, tempValue.Length, tag); } else { HGlobalMemHandle memHandle = new HGlobalMemHandle(HGlobalMemHandle._dummyPointer); - error = BerPal.PrintByteArray(berElement, new string(fmt, 1), memHandle, 0); + error = BerPal.PrintByteArray(berElement, new string(fmt, 1), memHandle, 0, tag); } return error; @@ -479,7 +518,7 @@ private static byte[] DecodingByteArrayHelper(SafeBerHandle berElement, char fmt return byteArray; } - private static int EncodingMultiByteArrayHelper(SafeBerHandle berElement, byte[][] tempValue, char fmt) + private static int EncodingMultiByteArrayHelper(SafeBerHandle berElement, byte[][] tempValue, char fmt, int tag) { IntPtr berValArray = IntPtr.Zero; IntPtr tempPtr = IntPtr.Zero; @@ -521,7 +560,7 @@ private static int EncodingMultiByteArrayHelper(SafeBerHandle berElement, byte[] Marshal.WriteIntPtr(tempPtr, IntPtr.Zero); } - error = BerPal.PrintBerArray(berElement, new string(fmt, 1), berValArray); + error = BerPal.PrintBerArray(berElement, new string(fmt, 1), berValArray, tag); } finally { diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/BerConverterTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/BerConverterTests.cs index d47ecba69a09c8..ba92d33c2a7b61 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/BerConverterTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/BerConverterTests.cs @@ -29,6 +29,10 @@ public static IEnumerable Encode_TestData() yield return new object[] { "[]", new object[] { "a" }, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 49, 132, 0, 0, 0, 0 } : new byte[] { 49, 0 } }; yield return new object[] { "n", new object[] { "a" }, new byte[] { 5, 0 } }; + yield return new object[] { "e", new object[] { 128 }, new byte[] { 10, 2, 0, 128 } }; + yield return new object[] { "te", new object[] { 128, 0 }, new byte[] { 128, 1, 0 } }; + yield return new object[] { "tet", new object[] { 128, 0, 133 }, new byte[] { 128, 1, 0 } }; + yield return new object[] { "tetie", new object[] { 128, 0, 133, 2, 3 }, new byte[] { 128, 1, 0, 133, 1, 2, 10, 1, 3 } }; yield return new object[] { "{tetie}", new object[] { 128, 0, 133, 2, 3 }, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 9, 128, 1, 0, 133, 1, 2, 10, 1, 3 } : new byte[] { 48, 9, 128, 1, 0, 133, 1, 2, 10, 1, 3 } }; @@ -36,10 +40,16 @@ public static IEnumerable Encode_TestData() yield return new object[] { "{bb}", new object[] { true, false }, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 } : new byte[] { 48, 6, 1, 1, 255, 1, 1, 0 } }; yield return new object[] { "ssss", new object[] { null, "", "abc", "\0" }, new byte[] { 4, 0, 4, 0, 4, 3, 97, 98, 99, 4, 1, 0 } }; + + yield return new object[] { "o", new object[] { null }, new byte[] { 4, 0} }; + yield return new object[] { "X", new object[] { new byte[] { 0, 1, 2, 255 } }, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 3, 4, 0, 1, 2, 255 } : new byte[] { 3, 2, 4, 0 } }; yield return new object[] { "oXo", new object[] { null, new byte[] { 0, 1, 2, 255 }, new byte[0] }, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 4, 0, 3, 4, 0, 1, 2, 255, 4, 0 } : new byte[] { 4, 0, 3, 2, 4, 0, 4, 0 } }; yield return new object[] { "vv", new object[] { null, new string[] { "abc", "", null } }, new byte[] { 4, 3, 97, 98, 99, 4, 0, 4, 0 } }; yield return new object[] { "{vv}", new object[] { null, new string[] { "abc", "", null } }, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 9, 4, 3, 97, 98, 99, 4, 0, 4, 0 } : new byte[] { 48, 9, 4, 3, 97, 98, 99, 4, 0, 4, 0 } }; - yield return new object[] { "VVVV", new object[] { null, new byte[][] { new byte[] { 0, 1, 2, 3 }, null }, new byte[][] { new byte[0] }, new byte[0][] }, new byte[] { 4, 4, 0, 1, 2, 3, 4, 0, 4, 0 } }; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + yield return new object[] { "VVVV", new object[] { null, new byte[][] { new byte[] { 0, 1, 2, 3 }, null }, new byte[][] { new byte[0] }, new byte[0][] }, new byte[] { 4, 4, 0, 1, 2, 3, 4, 0, 4, 0 } }; + } } [Theory] @@ -116,6 +126,7 @@ public static IEnumerable Decode_TestData() { yield return new object[] { "{}", new byte[] { 48, 0, 0, 0, 0, 0 }, new object[0] }; yield return new object[] { "{a}", new byte[] { 48, 132, 0, 0, 0, 5, 4, 3, 97, 98, 99 }, new object[] { "abc" } }; + yield return new object[] { "{i}", new byte[] { 48, 132, 0, 0, 0, 3, 2, 1, 10 }, new object[] { 10 } }; yield return new object[] { "{ie}", new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 }, new object[] { -1, 0 } }; yield return new object[] { "{bb}", new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 }, new object[] { true, false } }; yield return new object[] { "{OO}", new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 }, new object[] { new byte[] { 255 }, new byte[] { 0 } } }; From 990c3c882d51289157927d8c9930f20a5129d4b5 Mon Sep 17 00:00:00 2001 From: Sergey Date: Thu, 29 Apr 2021 18:18:01 -0700 Subject: [PATCH 3/4] Use nuint for Linux. --- .../src/Interop/Linux/OpenLdap/Interop.Ber.cs | 45 ++++++++++--------- .../Protocols/Interop/BerPal.Linux.cs | 12 ++--- .../Protocols/Interop/BerPal.Windows.cs | 12 ++--- .../Protocols/common/BerConverter.Windows.cs | 4 +- .../Protocols/common/BerConverter.cs | 15 ++++--- 5 files changed, 46 insertions(+), 42 deletions(-) diff --git a/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ber.cs b/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ber.cs index 830e56c0562482..fc3bef78afdd14 100644 --- a/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ber.cs +++ b/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ber.cs @@ -21,7 +21,7 @@ internal static partial class Ldap [DllImport(Libraries.OpenLdap, EntryPoint = "ber_free", CharSet = CharSet.Ansi)] public static extern IntPtr ber_free([In] IntPtr berelement, int option); - public static int ber_printf_emptyarg(SafeBerHandle berElement, string format, int tag) + public static int ber_printf_emptyarg(SafeBerHandle berElement, string format, nuint tag) { if (format == "{") { @@ -47,29 +47,29 @@ public static int ber_printf_emptyarg(SafeBerHandle berElement, string format, i } [DllImport(Libraries.OpenLdap, EntryPoint = "ber_start_seq", CharSet = CharSet.Ansi)] - public static extern int ber_start_seq(SafeBerHandle berElement, int tag); + public static extern int ber_start_seq(SafeBerHandle berElement, nuint tag); [DllImport(Libraries.OpenLdap, EntryPoint = "ber_start_set", CharSet = CharSet.Ansi)] - public static extern int ber_start_set(SafeBerHandle berElement, int tag); + public static extern int ber_start_set(SafeBerHandle berElement, nuint tag); [DllImport(Libraries.OpenLdap, EntryPoint = "ber_put_seq", CharSet = CharSet.Ansi)] - public static extern int ber_put_seq(SafeBerHandle berElement, int tag); + public static extern int ber_put_seq(SafeBerHandle berElement, nuint tag); [DllImport(Libraries.OpenLdap, EntryPoint = "ber_put_set", CharSet = CharSet.Ansi)] - public static extern int ber_put_set(SafeBerHandle berElement, int tag); + public static extern int ber_put_set(SafeBerHandle berElement, nuint tag); [DllImport(Libraries.OpenLdap, EntryPoint = "ber_put_null", CharSet = CharSet.Ansi)] - public static extern int ber_put_null(SafeBerHandle berElement, int tag); + public static extern int ber_put_null(SafeBerHandle berElement, nuint tag); - public static int ber_printf_tag(SafeBerHandle berElement, string format, int tag) + public static int ber_printf_tag(SafeBerHandle berElement, string format, nuint tag) { // Ber Linux tags are passed with the values that they affect, like `ber_printf_int(.., tag)`. // So this function does nothing on Linux. return ber_default_successful_return_code; } - public static int ber_printf_int(SafeBerHandle berElement, string format, int value, int tag) + public static int ber_printf_int(SafeBerHandle berElement, string format, int value, nuint tag) { if (format == "i") { @@ -87,15 +87,15 @@ public static int ber_printf_int(SafeBerHandle berElement, string format, int va } [DllImport(Libraries.OpenLdap, EntryPoint = "ber_put_int", CharSet = CharSet.Ansi)] - public static extern int ber_put_int(SafeBerHandle berElement, int value, int tag); + public static extern int ber_put_int(SafeBerHandle berElement, int value, nuint tag); [DllImport(Libraries.OpenLdap, EntryPoint = "ber_put_enum", CharSet = CharSet.Ansi)] - public static extern int ber_put_enum(SafeBerHandle berElement, int value, int tag); + public static extern int ber_put_enum(SafeBerHandle berElement, int value, nuint tag); [DllImport(Libraries.OpenLdap, EntryPoint = "ber_put_boolean", CharSet = CharSet.Ansi)] - public static extern int ber_put_boolean(SafeBerHandle berElement, int value, int tag); + public static extern int ber_put_boolean(SafeBerHandle berElement, int value, nuint tag); - public static int ber_printf_bytearray(SafeBerHandle berElement, string format, HGlobalMemHandle value, int length, int tag) + public static int ber_printf_bytearray(SafeBerHandle berElement, string format, HGlobalMemHandle value, nuint length, nuint tag) { if (format == "o") { @@ -113,13 +113,13 @@ public static int ber_printf_bytearray(SafeBerHandle berElement, string format, } [DllImport(Libraries.OpenLdap, EntryPoint = "ber_put_ostring", CharSet = CharSet.Ansi)] - private static extern int ber_put_ostring(SafeBerHandle berElement, HGlobalMemHandle value, int length, int tag); + private static extern int ber_put_ostring(SafeBerHandle berElement, HGlobalMemHandle value, nuint length, nuint tag); [DllImport(Libraries.OpenLdap, EntryPoint = "ber_put_string", CharSet = CharSet.Ansi)] - private static extern int ber_put_string(SafeBerHandle berElement, HGlobalMemHandle value, int tag); + private static extern int ber_put_string(SafeBerHandle berElement, HGlobalMemHandle value, nuint tag); [DllImport(Libraries.OpenLdap, EntryPoint = "ber_put_bitstring", CharSet = CharSet.Ansi)] - private static extern int ber_put_bitstring(SafeBerHandle berElement, HGlobalMemHandle value, int length, int tag); + private static extern int ber_put_bitstring(SafeBerHandle berElement, HGlobalMemHandle value, nuint length, nuint tag); [DllImport(Libraries.OpenLdap, EntryPoint = "ber_flatten", CharSet = CharSet.Ansi)] public static extern int ber_flatten(SafeBerHandle berElement, ref IntPtr value); @@ -135,7 +135,7 @@ public static int ber_scanf_emptyarg(SafeBerHandle berElement, string format) Debug.Assert(format == "{" || format == "}" || format == "[" || format == "]" || format == "n" || format == "x"); if (format == "{" || format == "[") { - int len = 0; + nuint len = 0; return ber_skip_tag(berElement, ref len); } else if (format == "]" || format == "}") @@ -150,7 +150,7 @@ public static int ber_scanf_emptyarg(SafeBerHandle berElement, string format) } [DllImport(Libraries.OpenLdap, EntryPoint = "ber_skip_tag", CharSet = CharSet.Ansi)] - private static extern int ber_skip_tag(SafeBerHandle berElement, ref int len); + private static extern int ber_skip_tag(SafeBerHandle berElement, ref nuint len); [DllImport(Libraries.OpenLdap, EntryPoint = "ber_get_null", CharSet = CharSet.Ansi)] private static extern int ber_get_null(SafeBerHandle berElement); @@ -181,14 +181,17 @@ public static int ber_scanf_int(SafeBerHandle berElement, string format, ref int [DllImport(Libraries.OpenLdap, EntryPoint = "ber_get_boolean", CharSet = CharSet.Ansi)] private static extern int ber_get_boolean(SafeBerHandle berElement, ref int value); - public static int ber_scanf_bitstring(SafeBerHandle berElement, string format, ref IntPtr value, ref int bitLength) + public static int ber_scanf_bitstring(SafeBerHandle berElement, string format, ref IntPtr value, ref uint bitLength) { Debug.Assert(format == "B"); - return ber_get_stringb(berElement, ref value, ref bitLength); + nuint bitLengthAsNuint = 0; + int res = ber_get_stringb(berElement, ref value, ref bitLengthAsNuint); + bitLength = (uint)bitLengthAsNuint; + return res; } [DllImport(Libraries.OpenLdap, EntryPoint = "ber_get_stringb", CharSet = CharSet.Ansi)] - private static extern int ber_get_stringb(SafeBerHandle berElement, ref IntPtr value, ref int bitLength); + private static extern int ber_get_stringb(SafeBerHandle berElement, ref IntPtr value, ref nuint bitLength); public static int ber_scanf_ptr(SafeBerHandle berElement, string format, ref IntPtr value) { @@ -199,7 +202,7 @@ public static int ber_scanf_ptr(SafeBerHandle berElement, string format, ref Int [DllImport(Libraries.OpenLdap, EntryPoint = "ber_get_stringal", CharSet = CharSet.Ansi)] private static extern int ber_get_stringal(SafeBerHandle berElement, ref IntPtr value); - public static int ber_printf_berarray(SafeBerHandle berElement, string format, IntPtr value, int tag) + public static int ber_printf_berarray(SafeBerHandle berElement, string format, IntPtr value, nuint tag) { Debug.Assert(format == "v" || format == "V"); // V and v are not supported on Unix yet. diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Linux.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Linux.cs index 359a973463d5f4..37b2ee077febc2 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Linux.cs +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Linux.cs @@ -13,19 +13,19 @@ internal static class BerPal internal static int FlattenBerElement(SafeBerHandle berElement, ref IntPtr flattenptr) => Interop.Ldap.ber_flatten(berElement, ref flattenptr); - internal static int PrintBerArray(SafeBerHandle berElement, string format, IntPtr value, int tag) => Interop.Ldap.ber_printf_berarray(berElement, format, value, tag); + internal static int PrintBerArray(SafeBerHandle berElement, string format, IntPtr value, nuint tag) => Interop.Ldap.ber_printf_berarray(berElement, format, value, tag); - internal static int PrintByteArray(SafeBerHandle berElement, string format, HGlobalMemHandle value, int length, int tag) => Interop.Ldap.ber_printf_bytearray(berElement, format, value, length, tag); + internal static int PrintByteArray(SafeBerHandle berElement, string format, HGlobalMemHandle value, nuint length, nuint tag) => Interop.Ldap.ber_printf_bytearray(berElement, format, value, length, tag); - internal static int PrintEmptyArgument(SafeBerHandle berElement, string format, int tag) => Interop.Ldap.ber_printf_emptyarg(berElement, format, tag); + internal static int PrintEmptyArgument(SafeBerHandle berElement, string format, nuint tag) => Interop.Ldap.ber_printf_emptyarg(berElement, format, tag); - internal static int PrintInt(SafeBerHandle berElement, string format, int value, int tag) => Interop.Ldap.ber_printf_int(berElement, format, value, tag); + internal static int PrintInt(SafeBerHandle berElement, string format, int value, nuint tag) => Interop.Ldap.ber_printf_int(berElement, format, value, tag); - internal static int PrintTag(SafeBerHandle berElement, string format, int tag) => Interop.Ldap.ber_printf_tag(berElement, format, tag); + internal static int PrintTag(SafeBerHandle berElement, string format, nuint tag) => Interop.Ldap.ber_printf_tag(berElement, format, tag); internal static int ScanNext(SafeBerHandle berElement, string format) => Interop.Ldap.ber_scanf_emptyarg(berElement, format); - internal static int ScanNextBitString(SafeBerHandle berElement, string format, ref IntPtr ptrResult, ref int bitLength) => Interop.Ldap.ber_scanf_bitstring(berElement, format, ref ptrResult, ref bitLength); + internal static int ScanNextBitString(SafeBerHandle berElement, string format, ref IntPtr ptrResult, ref uint bitLength) => Interop.Ldap.ber_scanf_bitstring(berElement, format, ref ptrResult, ref bitLength); internal static int ScanNextInt(SafeBerHandle berElement, string format, ref int result) => Interop.Ldap.ber_scanf_int(berElement, format, ref result); diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Windows.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Windows.cs index 99532610f6767e..f00f40d876d929 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Windows.cs +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Windows.cs @@ -15,19 +15,19 @@ internal static class BerPal internal static int FlattenBerElement(SafeBerHandle berElement, ref IntPtr flattenptr) => Interop.Ldap.ber_flatten(berElement, ref flattenptr); - internal static int PrintBerArray(SafeBerHandle berElement, string format, IntPtr value, int tag) => Interop.Ldap.ber_printf(berElement, format, __arglist(value)); + internal static int PrintBerArray(SafeBerHandle berElement, string format, IntPtr value, nuint tag) => Interop.Ldap.ber_printf(berElement, format, __arglist(value)); - internal static int PrintByteArray(SafeBerHandle berElement, string format, HGlobalMemHandle value, int length, int tag) => Interop.Ldap.ber_printf(berElement, format, __arglist(value, length)); + internal static int PrintByteArray(SafeBerHandle berElement, string format, HGlobalMemHandle value, uint length, nuint tag) => Interop.Ldap.ber_printf(berElement, format, __arglist(value, length)); - internal static int PrintEmptyArgument(SafeBerHandle berElement, string format, int tag) => Interop.Ldap.ber_printf(berElement, format, __arglist()); + internal static int PrintEmptyArgument(SafeBerHandle berElement, string format, nuint tag) => Interop.Ldap.ber_printf(berElement, format, __arglist()); - internal static int PrintInt(SafeBerHandle berElement, string format, int value, int tag) => Interop.Ldap.ber_printf(berElement, format, __arglist(value)); + internal static int PrintInt(SafeBerHandle berElement, string format, int value, nuint tag) => Interop.Ldap.ber_printf(berElement, format, __arglist(value)); - internal static int PrintTag(SafeBerHandle berElement, string format, int tag) => Interop.Ldap.ber_printf(berElement, format, __arglist(tag)); + internal static int PrintTag(SafeBerHandle berElement, string format, nuint tag) => Interop.Ldap.ber_printf(berElement, format, __arglist(tag)); internal static int ScanNext(SafeBerHandle berElement, string format) => Interop.Ldap.ber_scanf(berElement, format, __arglist()); - internal static int ScanNextBitString(SafeBerHandle berElement, string format, ref IntPtr ptrResult, ref int bitLength) => Interop.Ldap.ber_scanf(berElement, format, __arglist(ref ptrResult, ref bitLength)); + internal static int ScanNextBitString(SafeBerHandle berElement, string format, ref IntPtr ptrResult, ref uint bitLength) => Interop.Ldap.ber_scanf(berElement, format, __arglist(ref ptrResult, ref bitLength)); internal static int ScanNextInt(SafeBerHandle berElement, string format, ref int result) => Interop.Ldap.ber_scanf(berElement, format, __arglist(ref result)); diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/BerConverter.Windows.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/BerConverter.Windows.cs index e4bd5d14c474ed..3bef316a506b96 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/BerConverter.Windows.cs +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/BerConverter.Windows.cs @@ -14,7 +14,7 @@ private static int DecodeBitStringHelper(ArrayList resultList, SafeBerHandle ber int error; // return a bitstring and its length IntPtr ptrResult = IntPtr.Zero; - int length = 0; + uint length = 0; error = BerPal.ScanNextBitString(berElement, "B", ref ptrResult, ref length); if (!BerPal.IsBerDecodeError(error)) @@ -23,7 +23,7 @@ private static int DecodeBitStringHelper(ArrayList resultList, SafeBerHandle ber if (ptrResult != IntPtr.Zero) { byteArray = new byte[length]; - Marshal.Copy(ptrResult, byteArray, 0, length); + Marshal.Copy(ptrResult, byteArray, 0, (int)length); } resultList.Add(byteArray); } diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/BerConverter.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/BerConverter.cs index 36c94f297c6be4..8833ae73e31dc3 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/BerConverter.cs +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/BerConverter.cs @@ -32,7 +32,7 @@ public static byte[] Encode(string format, params object[] value) // We can't use vararg on Unix and can't do ber_printf(tag), so we use ber_put_int(val, tag) // and this local keeps tag value for the next element. - int tag = 0; + nuint tag = 0; bool tagIsSet = false; for (int formatCount = 0; formatCount < format.Length; formatCount++) { @@ -42,8 +42,9 @@ public static byte[] Encode(string format, params object[] value) } else { - const int lberTagDefault = -1; - tag = lberTagDefault; + int lberTagDefaultInt = -1; + nuint lberTagDefaultNuint = (nuint)lberTagDefaultInt; + tag = lberTagDefaultNuint; } char fmt = format[formatCount]; if (fmt == '{' || fmt == '}' || fmt == '[' || fmt == ']' || fmt == 'n') @@ -226,7 +227,7 @@ public static byte[] Encode(string format, params object[] value) Debug.WriteLine("type should be int\n"); throw new ArgumentException(SR.BerConverterNotMatch); } - tag = (int)value[valueCount]; + tag = (uint)(int)value[valueCount]; tagIsSet = true; // It will set the tag on Windows and only check the tag on Unix. error = BerPal.PrintTag(berElement, new string(fmt, 1), tag); @@ -462,7 +463,7 @@ internal static object[] TryDecode(string format, byte[] value, out bool decodeS return decodeResult; } - private static int EncodingByteArrayHelper(SafeBerHandle berElement, byte[] tempValue, char fmt, int tag) + private static int EncodingByteArrayHelper(SafeBerHandle berElement, byte[] tempValue, char fmt, nuint tag) { int error = 0; @@ -472,7 +473,7 @@ private static int EncodingByteArrayHelper(SafeBerHandle berElement, byte[] temp IntPtr tmp = Marshal.AllocHGlobal(tempValue.Length); Marshal.Copy(tempValue, 0, tmp, tempValue.Length); HGlobalMemHandle memHandle = new HGlobalMemHandle(tmp); - error = BerPal.PrintByteArray(berElement, new string(fmt, 1), memHandle, tempValue.Length, tag); + error = BerPal.PrintByteArray(berElement, new string(fmt, 1), memHandle, (uint)tempValue.Length, tag); } else { @@ -518,7 +519,7 @@ private static byte[] DecodingByteArrayHelper(SafeBerHandle berElement, char fmt return byteArray; } - private static int EncodingMultiByteArrayHelper(SafeBerHandle berElement, byte[][] tempValue, char fmt, int tag) + private static int EncodingMultiByteArrayHelper(SafeBerHandle berElement, byte[][] tempValue, char fmt, nuint tag) { IntPtr berValArray = IntPtr.Zero; IntPtr tempPtr = IntPtr.Zero; From f81b2811113d863d1cee9b818b7f79dbe7fff350 Mon Sep 17 00:00:00 2001 From: Sergey Date: Fri, 7 May 2021 11:16:39 -0700 Subject: [PATCH 4/4] review response --- .../Common/src/Interop/Linux/OpenLdap/Interop.Ber.cs | 10 +--------- .../Protocols/Interop/BerPal.Linux.cs | 7 ++++++- .../Protocols/Interop/BerPal.Windows.cs | 10 +++++----- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ber.cs b/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ber.cs index fc3bef78afdd14..4ee4bc8bab9432 100644 --- a/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ber.cs +++ b/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ber.cs @@ -10,7 +10,7 @@ internal static partial class Interop { internal static partial class Ldap { - private const int ber_default_successful_return_code = 0; + public const int ber_default_successful_return_code = 0; [DllImport(Libraries.OpenLdap, EntryPoint = "ber_alloc_t", CharSet = CharSet.Ansi)] public static extern IntPtr ber_alloc(int option); @@ -61,14 +61,6 @@ public static int ber_printf_emptyarg(SafeBerHandle berElement, string format, n [DllImport(Libraries.OpenLdap, EntryPoint = "ber_put_null", CharSet = CharSet.Ansi)] public static extern int ber_put_null(SafeBerHandle berElement, nuint tag); - - public static int ber_printf_tag(SafeBerHandle berElement, string format, nuint tag) - { - // Ber Linux tags are passed with the values that they affect, like `ber_printf_int(.., tag)`. - // So this function does nothing on Linux. - return ber_default_successful_return_code; - } - public static int ber_printf_int(SafeBerHandle berElement, string format, int value, nuint tag) { if (format == "i") diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Linux.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Linux.cs index 37b2ee077febc2..319bdba629bc43 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Linux.cs +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Linux.cs @@ -21,7 +21,12 @@ internal static class BerPal internal static int PrintInt(SafeBerHandle berElement, string format, int value, nuint tag) => Interop.Ldap.ber_printf_int(berElement, format, value, tag); - internal static int PrintTag(SafeBerHandle berElement, string format, nuint tag) => Interop.Ldap.ber_printf_tag(berElement, format, tag); + internal static int PrintTag(SafeBerHandle _1, string _2, nuint _3) + { + // Ber Linux tags are passed with the values that they affect, like `ber_printf_int(.., tag)`. + // So this function does nothing on Linux. + return Interop.Ldap.ber_default_successful_return_code; + } internal static int ScanNext(SafeBerHandle berElement, string format) => Interop.Ldap.ber_scanf_emptyarg(berElement, format); diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Windows.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Windows.cs index f00f40d876d929..586bcd7d39a2cf 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Windows.cs +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Windows.cs @@ -15,15 +15,15 @@ internal static class BerPal internal static int FlattenBerElement(SafeBerHandle berElement, ref IntPtr flattenptr) => Interop.Ldap.ber_flatten(berElement, ref flattenptr); - internal static int PrintBerArray(SafeBerHandle berElement, string format, IntPtr value, nuint tag) => Interop.Ldap.ber_printf(berElement, format, __arglist(value)); + internal static int PrintBerArray(SafeBerHandle berElement, string format, IntPtr value, nuint _) => Interop.Ldap.ber_printf(berElement, format, __arglist(value)); - internal static int PrintByteArray(SafeBerHandle berElement, string format, HGlobalMemHandle value, uint length, nuint tag) => Interop.Ldap.ber_printf(berElement, format, __arglist(value, length)); + internal static int PrintByteArray(SafeBerHandle berElement, string format, HGlobalMemHandle value, uint length, nuint _) => Interop.Ldap.ber_printf(berElement, format, __arglist(value, length)); - internal static int PrintEmptyArgument(SafeBerHandle berElement, string format, nuint tag) => Interop.Ldap.ber_printf(berElement, format, __arglist()); + internal static int PrintEmptyArgument(SafeBerHandle berElement, string format, nuint _) => Interop.Ldap.ber_printf(berElement, format, __arglist()); - internal static int PrintInt(SafeBerHandle berElement, string format, int value, nuint tag) => Interop.Ldap.ber_printf(berElement, format, __arglist(value)); + internal static int PrintInt(SafeBerHandle berElement, string format, int value, nuint _) => Interop.Ldap.ber_printf(berElement, format, __arglist(value)); - internal static int PrintTag(SafeBerHandle berElement, string format, nuint tag) => Interop.Ldap.ber_printf(berElement, format, __arglist(tag)); + internal static int PrintTag(SafeBerHandle berElement, string format, nuint tag) => Interop.Ldap.ber_printf(berElement, format, __arglist((uint)tag)); internal static int ScanNext(SafeBerHandle berElement, string format) => Interop.Ldap.ber_scanf(berElement, format, __arglist());