From 14eb66c26f1a6f537da04860b2fb9c198996fe82 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 12 Mar 2024 11:18:25 -0700 Subject: [PATCH 1/3] Add 0/null checks for various cases in the COM/dynamic VARIANT extensions --- .../Runtime/InteropServices/BuiltInVariantExtensions.cs | 5 ++--- .../RuntimeBinder/ComInterop/DynamicVariantExtensions.cs | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/libraries/Common/src/System/Runtime/InteropServices/BuiltInVariantExtensions.cs b/src/libraries/Common/src/System/Runtime/InteropServices/BuiltInVariantExtensions.cs index 777a1c03b0a7a2..0f5f3a04f1a51d 100644 --- a/src/libraries/Common/src/System/Runtime/InteropServices/BuiltInVariantExtensions.cs +++ b/src/libraries/Common/src/System/Runtime/InteropServices/BuiltInVariantExtensions.cs @@ -154,9 +154,8 @@ public static unsafe void CopyFromIndirect(this ref ComVariant variant, object v VarEnum.VT_DECIMAL => variant.As(), VarEnum.VT_CY => decimal.FromOACurrency(variant.GetRawDataRef()), VarEnum.VT_DATE => variant.As(), - VarEnum.VT_BSTR => Marshal.PtrToStringBSTR(variant.GetRawDataRef()), - VarEnum.VT_UNKNOWN => Marshal.GetObjectForIUnknown(variant.GetRawDataRef()), - VarEnum.VT_DISPATCH => Marshal.GetObjectForIUnknown(variant.GetRawDataRef()), + VarEnum.VT_BSTR => variant.GetRawDataRef() is 0 ? null : Marshal.PtrToStringBSTR(variant.GetRawDataRef()), + VarEnum.VT_UNKNOWN or VarEnum.VT_DISPATCH => variant.GetRawDataRef() is 0 ? null : Marshal.GetObjectForIUnknown(variant.GetRawDataRef()), _ => GetObjectFromNativeVariant(ref variant), }; } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ComInterop/DynamicVariantExtensions.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ComInterop/DynamicVariantExtensions.cs index 27647ed388f28e..3d7551a78346a2 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ComInterop/DynamicVariantExtensions.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ComInterop/DynamicVariantExtensions.cs @@ -381,12 +381,12 @@ public static void SetBstr(this ref ComVariant variant, string value) public static void SetUnknown(this ref ComVariant variant, object value) { - variant = ComVariant.CreateRaw(VarEnum.VT_UNKNOWN, Marshal.GetIUnknownForObject(value)); + variant = ComVariant.CreateRaw(VarEnum.VT_UNKNOWN, value is null ? IntPtr.Zero : Marshal.GetIUnknownForObject(value)); } public static void SetDispatch(this ref ComVariant variant, object value) { - variant = ComVariant.CreateRaw(VarEnum.VT_DISPATCH, Marshal.GetIDispatchForObject(value)); + variant = ComVariant.CreateRaw(VarEnum.VT_DISPATCH, value is null ? IntPtr.Zero : Marshal.GetIDispatchForObject(value)); } public static void SetError(this ref ComVariant variant, int value) From 24149fef89221dd629c2eb6caf3a87a5ac487b65 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 12 Mar 2024 11:55:22 -0700 Subject: [PATCH 2/3] Add null annotations and update tests --- .../Runtime/InteropServices/BuiltInVariantExtensions.cs | 2 +- .../RuntimeBinder/ComInterop/DynamicVariantExtensions.cs | 4 ++-- src/tests/Interop/COM/Dynamic/BasicTest.cs | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libraries/Common/src/System/Runtime/InteropServices/BuiltInVariantExtensions.cs b/src/libraries/Common/src/System/Runtime/InteropServices/BuiltInVariantExtensions.cs index 0f5f3a04f1a51d..daedc25c50456c 100644 --- a/src/libraries/Common/src/System/Runtime/InteropServices/BuiltInVariantExtensions.cs +++ b/src/libraries/Common/src/System/Runtime/InteropServices/BuiltInVariantExtensions.cs @@ -21,7 +21,7 @@ private static unsafe ref T GetByRefDataRef(this ref ComVariant variant) return ref Unsafe.AsRef((void*)variant.GetRawDataRef()); } - public static unsafe void CopyFromIndirect(this ref ComVariant variant, object value) + public static unsafe void CopyFromIndirect(this ref ComVariant variant, object? value) { VarEnum vt = (VarEnum)(((int)variant.VarType) & ~((int)VarEnum.VT_BYREF)); diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ComInterop/DynamicVariantExtensions.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ComInterop/DynamicVariantExtensions.cs index 3d7551a78346a2..c8608ce2c9dfa4 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ComInterop/DynamicVariantExtensions.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ComInterop/DynamicVariantExtensions.cs @@ -379,12 +379,12 @@ public static void SetBstr(this ref ComVariant variant, string value) variant = ComVariant.Create(new BStrWrapper(value)); } - public static void SetUnknown(this ref ComVariant variant, object value) + public static void SetUnknown(this ref ComVariant variant, object? value) { variant = ComVariant.CreateRaw(VarEnum.VT_UNKNOWN, value is null ? IntPtr.Zero : Marshal.GetIUnknownForObject(value)); } - public static void SetDispatch(this ref ComVariant variant, object value) + public static void SetDispatch(this ref ComVariant variant, object? value) { variant = ComVariant.CreateRaw(VarEnum.VT_DISPATCH, value is null ? IntPtr.Zero : Marshal.GetIDispatchForObject(value)); } diff --git a/src/tests/Interop/COM/Dynamic/BasicTest.cs b/src/tests/Interop/COM/Dynamic/BasicTest.cs index 1e6fa7f5604e99..f60de75cb03837 100644 --- a/src/tests/Interop/COM/Dynamic/BasicTest.cs +++ b/src/tests/Interop/COM/Dynamic/BasicTest.cs @@ -423,6 +423,9 @@ private void Null() obj.String_Property = null; Assert.Equal(string.Empty, obj.String_Property); + + obj.Dispatch_Property = null; + Assert.Null(obj.Dispatch_Property); } private void StringWrapper(string toWrap, string expected) From 801576dfb05635adf513631b379fc07b7a959601 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 13 Mar 2024 11:43:19 -0700 Subject: [PATCH 3/3] Use DispatchWrapper to get the correct underlying variant type --- src/tests/Interop/COM/Dynamic/BasicTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/Interop/COM/Dynamic/BasicTest.cs b/src/tests/Interop/COM/Dynamic/BasicTest.cs index f60de75cb03837..4ec5d6fbbdcccd 100644 --- a/src/tests/Interop/COM/Dynamic/BasicTest.cs +++ b/src/tests/Interop/COM/Dynamic/BasicTest.cs @@ -424,7 +424,7 @@ private void Null() obj.String_Property = null; Assert.Equal(string.Empty, obj.String_Property); - obj.Dispatch_Property = null; + obj.Dispatch_Property = new DispatchWrapper(null); Assert.Null(obj.Dispatch_Property); }