xref: /aosp_15_r20/external/cronet/base/win/wrapped_window_proc_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2011 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/win/wrapped_window_proc.h"
6 #include "testing/gtest/include/gtest/gtest.h"
7 
8 namespace {
9 
10 DWORD kExceptionCode = 12345;
11 WPARAM kCrashMsg = 98765;
12 
13 // A trivial WindowProc that generates an exception.
TestWindowProc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam)14 LRESULT CALLBACK TestWindowProc(HWND hwnd,
15                                 UINT message,
16                                 WPARAM wparam,
17                                 LPARAM lparam) {
18   if (message == kCrashMsg)
19     RaiseException(kExceptionCode, 0, 0, nullptr);
20   return DefWindowProc(hwnd, message, wparam, lparam);
21 }
22 
23 // This class implements an exception filter that can be queried about a past
24 // exception.
25 class TestWrappedExceptionFiter {
26  public:
TestWrappedExceptionFiter()27   TestWrappedExceptionFiter() {
28     EXPECT_FALSE(s_filter_);
29     s_filter_ = this;
30   }
31 
~TestWrappedExceptionFiter()32   ~TestWrappedExceptionFiter() {
33     EXPECT_EQ(s_filter_, this);
34     s_filter_ = nullptr;
35   }
36 
called()37   bool called() { return called_; }
38 
39   // The actual exception filter just records the exception.
Filter(EXCEPTION_POINTERS * info)40   static int Filter(EXCEPTION_POINTERS* info) {
41     EXPECT_FALSE(s_filter_->called_);
42     if (info->ExceptionRecord->ExceptionCode == kExceptionCode)
43       s_filter_->called_ = true;
44     return EXCEPTION_EXECUTE_HANDLER;
45   }
46 
47  private:
48   bool called_ = false;
49   static TestWrappedExceptionFiter* s_filter_;
50 };
51 TestWrappedExceptionFiter* TestWrappedExceptionFiter::s_filter_ = nullptr;
52 
53 }  // namespace.
54 
TEST(WrappedWindowProc,CatchesExceptions)55 TEST(WrappedWindowProc, CatchesExceptions) {
56   HINSTANCE hinst = GetModuleHandle(nullptr);
57   std::wstring class_name(L"TestClass");
58 
59   WNDCLASS wc = {0};
60   wc.lpfnWndProc = base::win::WrappedWindowProc<TestWindowProc>;
61   wc.hInstance = hinst;
62   wc.lpszClassName = class_name.c_str();
63   RegisterClass(&wc);
64 
65   HWND window = CreateWindow(class_name.c_str(), nullptr, 0, 0, 0, 0, 0,
66                              HWND_MESSAGE, nullptr, hinst, nullptr);
67   ASSERT_TRUE(window);
68 
69   // Before generating the exception we make sure that the filter will see it.
70   TestWrappedExceptionFiter wrapper;
71   base::win::WinProcExceptionFilter old_filter =
72       base::win::SetWinProcExceptionFilter(TestWrappedExceptionFiter::Filter);
73 
74   SendMessage(window, kCrashMsg, 0, 0);
75   EXPECT_TRUE(wrapper.called());
76 
77   base::win::SetWinProcExceptionFilter(old_filter);
78 }
79