cppwinrt/test
David Machaj b82340f3fc
Bug: Projected winrt::consume_ methods will nullptr crash if the underlying QueryInterface call fails (#1442)
# Why is this change being made?
The generated projection code for interfaces that the metadata declares as required for a runtimeclass assume that QueryInterface never fails. Assuming the metadata is correct in the first place, this is a valid assumption for inproc calls.

However, for cross-process calls the QI can fail even if the metadata is correct and the class really does implement all of the required interfaces. It can fail with E_ACCESSDENIED and a variety of other RPC error codes.

When this happens there is a nullptr crash in the generated consume method. This can be very painful to debug because the HRESULT is lost by the time it crashes.

# Briefly summarize what changed
This set of changes fixes the crash by detecting the QueryInterface error and throwing an exception when that occurs during one of these required casts. The try_as method was changed to capture COM error context when the QI fails. The code gen surrounding WINRT_IMPL_STUB was changed to save the result into a temporary variable and then pass it to a new check_cast_result method. check_cast_result is marked noinline so that the binary size impact of throwing exceptions is limited to a single function instead of inlining into high-volume generated code.

If the cast succeeded then nothing happens. If the cast failed, returning null, then the stored COM exception is retrieved. Assuming it is available the HRESULT is pulled out of it and it is thrown. This then propagates like any other exception. Callers are free to try and catch it or let it go uncaught and crash. Now they have the choice.

I also added a new file of test code that exercises this code path. The test_component IDL declares a runtimeclass that implements IStringable. And then the implementation fails to implement IStringable. When ToString is called on this object it hits the failure path. The cppwinrt code gen will not allow this to happen so I had to directly use winrt::implements.

# How was this change tested?
Besides the new test cases I also wrote a little console app that crashes this way. I built and ran it using the latest stable cppwinrt as well as my private new one. As expected the debugger blame is far more useful with these changes.
2024-10-30 09:54:35 -07:00
..
nuget Compliance and test cleanup (#1291) 2023-03-27 18:34:35 -07:00
old_tests Spelling (#1412) 2024-04-06 07:17:18 -05:00
test Bug: Projected winrt::consume_ methods will nullptr crash if the underlying QueryInterface call fails (#1442) 2024-10-30 09:54:35 -07:00
test_component Bug: Projected winrt::consume_ methods will nullptr crash if the underlying QueryInterface call fails (#1442) 2024-10-30 09:54:35 -07:00
test_component_base Spelling (#1412) 2024-04-06 07:17:18 -05:00
test_component_derived Hide protected and overridable members from public projections (#1319) 2023-07-11 21:38:42 -05:00
test_component_fast CI: Build ARM64 cppwinrt and tests (not run) (#1211) 2022-10-20 10:42:42 -05:00
test_component_folders CI: Build ARM64 cppwinrt and tests (not run) (#1211) 2022-10-20 10:42:42 -05:00
test_component_no_pch CI: Build ARM64 cppwinrt and tests (not run) (#1211) 2022-10-20 10:42:42 -05:00
test_cpp20 Pipeline changes to build, publish, and test (#1400) 2024-03-28 18:06:25 -07:00
test_cpp20_no_sourcelocation Add a mechanism to suppress `std::source_location` (#1260) 2023-01-09 16:52:54 -06:00
test_fast Cleaning up some warnings for Clang and GCC (#1255) 2023-01-09 08:57:33 -06:00
test_fast_fwd Cleaning up some warnings for Clang and GCC (#1255) 2023-01-09 08:57:33 -06:00
test_module_lock_custom Cleaning up some warnings for Clang and GCC (#1255) 2023-01-09 08:57:33 -06:00
test_module_lock_none Compliance and test cleanup (#1291) 2023-03-27 18:34:35 -07:00
test_slow Cleaning up some warnings for Clang and GCC (#1255) 2023-01-09 08:57:33 -06:00
CMakeLists.txt Remove old Windows 7 support code (#1348) 2023-08-28 08:35:09 -05:00
catch.hpp Spelling (#1412) 2024-04-06 07:17:18 -05:00
mingw_com_support.h Add CMake build and a limited subset of tests for llvm-mingw (#1216) 2022-11-09 10:26:19 -06:00