Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix ber scanf/printf, fix for a reverted PR. #52178

Merged
merged 4 commits into from
May 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
189 changes: 173 additions & 16 deletions src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ber.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
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);

Expand All @@ -18,17 +21,97 @@ 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, nuint 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, nuint tag);

[DllImport(Libraries.OpenLdap, EntryPoint = "ber_start_set", CharSet = CharSet.Ansi)]
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, nuint tag);

[DllImport(Libraries.OpenLdap, EntryPoint = "ber_put_set", CharSet = CharSet.Ansi)]
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, nuint tag);

public static int ber_printf_int(SafeBerHandle berElement, string format, int value, nuint 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, nuint tag);

[DllImport(Libraries.OpenLdap, EntryPoint = "ber_put_enum", CharSet = CharSet.Ansi)]
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, nuint tag);

[DllImport(Libraries.OpenLdap, EntryPoint = "ber_printf", CharSet = CharSet.Ansi)]
public static extern int ber_printf_int(SafeBerHandle berElement, string format, int value);
public static int ber_printf_bytearray(SafeBerHandle berElement, string format, HGlobalMemHandle value, nuint length, nuint 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_bytearray(SafeBerHandle berElement, string format, HGlobalMemHandle value, int length);
[DllImport(Libraries.OpenLdap, EntryPoint = "ber_put_ostring", CharSet = CharSet.Ansi)]
private static extern int ber_put_ostring(SafeBerHandle berElement, HGlobalMemHandle value, nuint length, nuint 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_string", CharSet = CharSet.Ansi)]
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, nuint length, nuint tag);

[DllImport(Libraries.OpenLdap, EntryPoint = "ber_flatten", CharSet = CharSet.Ansi)]
public static extern int ber_flatten(SafeBerHandle berElement, ref IntPtr value);
Expand All @@ -39,16 +122,90 @@ 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 == "[")
{
nuint 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 nuint 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 uint bitLength)
{
Debug.Assert(format == "B");
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 nuint 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, nuint 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;
}
}
}
22 changes: 2 additions & 20 deletions src/libraries/Common/src/Interop/Windows/Wldap32/Interop.Ber.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,31 @@ 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, nuint 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, nuint length, nuint 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, nuint 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, nuint 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 _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 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_emptyarg(berElement, format);

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);

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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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, nuint _) => 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, uint length, nuint _) => 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, nuint _) => 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, nuint _) => 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, nuint tag) => Interop.Ldap.ber_printf(berElement, format, __arglist((uint)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 uint 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;
}
Expand Down
Loading