Convert Marshal test Variant usage to ComVariant#126968
Convert Marshal test Variant usage to ComVariant#126968
Conversation
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/b87f2dcb-ecea-4af2-b091-551b6de94281 Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
|
Tagging subscribers to this area: @dotnet/interop-contrib |
There was a problem hiding this comment.
Pull request overview
This PR migrates GetNativeVariantForObjectTests away from the test-local System.Runtime.InteropServices.Tests.Common.Variant helper to the runtime-supported ComVariant, and removes the obsolete helper from the test project.
Changes:
- Updated
GetNativeVariantForObjectTests(and Windows-specific companion) to allocate/read native VARIANTs usingComVariant, including updated assertions viaVarTypeandGetRawDataRef<T>(). - Added a local
Recordlayout helper struct for validating the VT_RECORD payload. - Deleted
Marshal/Common/Variant.csand removed it from the test project file.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
.../Marshal/GetNativeVariantForObjectTests.cs |
Switches VARIANT interop in tests to ComVariant and updates validation logic. |
.../Marshal/GetNativeVariantForObjectTests.Windows.cs |
Switches Windows-only invalid-array test to allocate using ComVariant. |
.../Marshal/Common/Variant.cs |
Removes obsolete test helper struct. |
System.Runtime.InteropServices.Tests.csproj |
Drops compile include for the removed helper file. |
| Marshal.GetNativeVariantForObject(guid, pNative); | ||
|
|
||
| Variant result = Marshal.PtrToStructure<Variant>(pNative); | ||
| Assert.Equal(VarEnum.VT_RECORD, (VarEnum)result.vt); | ||
| Assert.NotEqual(nint.Zero, result.pRecInfo); // We should have an IRecordInfo instance. | ||
| ComVariant result = Marshal.PtrToStructure<ComVariant>(pNative); | ||
| Assert.Equal(VarEnum.VT_RECORD, result.VarType); | ||
| Assert.NotEqual(nint.Zero, result.GetRawDataRef<Record>()._recordInfo); // We should have an IRecordInfo instance. |
There was a problem hiding this comment.
In the VT_RECORD case, the VARIANT typically owns both the record data and an IRecordInfo COM pointer. This test reads the pointers but doesn’t clear the VARIANT afterwards, so the record allocation/COM reference can leak. Consider disposing/clearing the VARIANT stored at pNative (e.g., ((ComVariant*)pNative)->Dispose() on Windows) once assertions are complete; ensure this is skipped on the NanoServer/exception path where the VARIANT may not have been initialized.
| IntPtr pNative = Marshal.AllocHGlobal(Marshal.SizeOf<ComVariant>()); | ||
| try | ||
| { | ||
| Marshal.GetNativeVariantForObject(primitive, pNative); |
There was a problem hiding this comment.
pNative holds a native VARIANT produced by Marshal.GetNativeVariantForObject. Some inputs in this test data produce VARIANTs that own native resources (e.g., VT_BSTR, VT_ARRAY/SAFEARRAY, COM interface pointers), but the buffer is later freed without clearing the VARIANT, which can leak those resources across the test run. Since this test now uses ComVariant, consider clearing the VARIANT stored at pNative (e.g., via an unsafe cast to ComVariant* and calling Dispose()) before freeing the backing buffer; make sure to guard the dispose so it only runs after GetNativeVariantForObject succeeds.
🤖 Copilot Code Review — PR #126968Note This review was generated by Copilot. Holistic AssessmentMotivation: The PR replaces a custom test-only Approach: Straightforward mechanical replacement. The Summary: ✅ LGTM. The memory layout mapping between the old Detailed Findings✅ Memory Layout Correctness — VerifiedThe old ✅ Allocation Size — CorrectAll ✅ Deleted File Has No Other Consumers — Verified
✅ No New Public API SurfaceAll changes are test-only. No 💡 Minor:
|
Note
This pull request description was generated with AI/Copilot assistance.
Summary
System.Runtime.InteropServices.Tests.Common.Variantusage inGetNativeVariantForObjectTestswithComVariant.ComVariant.VarTypeandGetRawDataRef<T>().Marshal/Common/Variant.csand its project include.Validation
./build.sh clr+libs -rc releasedotnet buildinsrc/libraries/System.Runtime.InteropServicesdotnet build /t:testforSystem.Runtime.InteropServices.Tests.csprojparallel_validationrun (Code Review + CodeQL)Notes
Variantusages are separate test-local structs, and the build/tests pass.