Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: chrome_frame/function_stub_unittest.cc

Issue 126143005: Remove Chrome Frame code and resources. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: sync to r244038 Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome_frame/function_stub.cc ('k') | chrome_frame/host.html » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5
6 #include "chrome_frame/function_stub.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "testing/gmock/include/gmock/gmock.h"
9
10 namespace {
11
12 // Test subclass to expose extra stuff.
13 class TestFunctionStub: public FunctionStub {
14 public:
15 static void Init(TestFunctionStub* stub) {
16 stub->FunctionStub::Init(&stub->stub_);
17 }
18
19 // Expose the offset to our signature_ field.
20 static const size_t kSignatureOffset;
21
22 void set_signature(HMODULE signature) { signature_ = signature; }
23 };
24
25 const size_t TestFunctionStub::kSignatureOffset =
26 FIELD_OFFSET(TestFunctionStub, signature_);
27
28 class FunctionStubTest: public testing::Test {
29 public:
30 FunctionStubTest() : stub_(NULL) {
31 }
32
33 virtual void SetUp() {
34 SYSTEM_INFO sys_info;
35 ::GetSystemInfo(&sys_info);
36
37 // Playpen size is a system page.
38 playpen_size_ = sys_info.dwPageSize;
39
40 // Reserve two pages.
41 playpen_ = reinterpret_cast<uint8*>(
42 ::VirtualAlloc(NULL,
43 2 * playpen_size_,
44 MEM_RESERVE,
45 PAGE_EXECUTE_READWRITE));
46 ASSERT_TRUE(playpen_ != NULL);
47
48 // And commit the first one.
49 ASSERT_TRUE(::VirtualAlloc(playpen_,
50 playpen_size_,
51 MEM_COMMIT,
52 PAGE_EXECUTE_READWRITE));
53 }
54
55 virtual void TearDown() {
56 if (stub_ != NULL) {
57 EXPECT_TRUE(FunctionStub::Destroy(stub_));
58 }
59
60 if (playpen_ != NULL) {
61 EXPECT_TRUE(::VirtualFree(playpen_, 0, MEM_RELEASE));
62 }
63 }
64
65 protected:
66 typedef uintptr_t (CALLBACK *FuncPtr0)();
67 typedef uintptr_t (CALLBACK *FuncPtr1)(uintptr_t arg);
68
69 MOCK_METHOD0(Foo0, uintptr_t());
70 MOCK_METHOD1(Foo1, uintptr_t(uintptr_t));
71 MOCK_METHOD0(Bar0, uintptr_t());
72 MOCK_METHOD1(Bar1, uintptr_t(uintptr_t));
73
74 static uintptr_t CALLBACK FooCallback0(FunctionStubTest* test) {
75 return test->Foo0();
76 }
77 static uintptr_t CALLBACK FooCallback1(FunctionStubTest* test,
78 uintptr_t arg) {
79 return test->Foo1(arg);
80 }
81 static uintptr_t CALLBACK BarCallback0(FunctionStubTest* test) {
82 return test->Foo0();
83 }
84 static uintptr_t CALLBACK BarCallback1(FunctionStubTest* test,
85 uintptr_t arg) {
86 return test->Foo1(arg);
87 }
88
89 // If a stub is allocated during testing, assigning it here
90 // will deallocate it at the end of test.
91 FunctionStub* stub_;
92
93 // playpen_[0 .. playpen_size_ - 1] is committed, writable memory.
94 // playpen_[playpen_size_] is uncommitted, defined memory.
95 uint8* playpen_;
96 size_t playpen_size_;
97 };
98
99 const uintptr_t kDivertedRetVal = 0x42;
100 const uintptr_t kFooRetVal = 0xCAFEBABE;
101 const uintptr_t kFooArg = 0xF0F0F0F0;
102
103 uintptr_t CALLBACK Foo() {
104 return kFooRetVal;
105 }
106
107 uintptr_t CALLBACK FooDivert(uintptr_t arg) {
108 return kFooRetVal;
109 }
110
111 } // namespace
112
113 TEST_F(FunctionStubTest, Accessors) {
114 uintptr_t argument = reinterpret_cast<uintptr_t>(this);
115 uintptr_t dest_fn = reinterpret_cast<uintptr_t>(FooDivert);
116 stub_ = FunctionStub::Create(argument, FooDivert);
117
118 EXPECT_FALSE(stub_->is_bypassed());
119 EXPECT_TRUE(stub_->is_valid());
120 EXPECT_TRUE(stub_->code() != NULL);
121
122 // Check that the stub code is executable.
123 MEMORY_BASIC_INFORMATION info = {};
124 EXPECT_NE(0u, ::VirtualQuery(stub_->code(), &info, sizeof(info)));
125 const DWORD kExecutableMask = PAGE_EXECUTE | PAGE_EXECUTE_READ |
126 PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY;
127 EXPECT_NE(0u, info.Protect & kExecutableMask);
128
129 EXPECT_EQ(argument, stub_->argument());
130 EXPECT_TRUE(stub_->bypass_address() != NULL);
131 EXPECT_EQ(dest_fn, stub_->destination_function());
132 }
133
134 TEST_F(FunctionStubTest, ZeroArgumentStub) {
135 stub_ = FunctionStub::Create(reinterpret_cast<uintptr_t>(this),
136 &FunctionStubTest::FooCallback0);
137
138 FuncPtr0 func = reinterpret_cast<FuncPtr0>(stub_->code());
139 EXPECT_CALL(*this, Foo0())
140 .WillOnce(testing::Return(kDivertedRetVal));
141
142 EXPECT_EQ(kDivertedRetVal, func());
143 }
144
145 TEST_F(FunctionStubTest, OneArgumentStub) {
146 stub_ = FunctionStub::Create(reinterpret_cast<uintptr_t>(this),
147 &FunctionStubTest::FooCallback1);
148
149 FuncPtr1 func = reinterpret_cast<FuncPtr1>(stub_->code());
150 EXPECT_CALL(*this, Foo1(kFooArg))
151 .WillOnce(testing::Return(kDivertedRetVal));
152
153 EXPECT_EQ(kDivertedRetVal, func(kFooArg));
154 }
155
156 TEST_F(FunctionStubTest, Bypass) {
157 stub_ = FunctionStub::Create(reinterpret_cast<uintptr_t>(this),
158 &FunctionStubTest::FooCallback0);
159
160 FuncPtr0 func = reinterpret_cast<FuncPtr0>(stub_->code());
161 EXPECT_CALL(*this, Foo0())
162 .WillOnce(testing::Return(kDivertedRetVal));
163
164 // This will call through to foo.
165 EXPECT_EQ(kDivertedRetVal, func());
166
167 // Now bypass to Foo().
168 stub_->BypassStub(Foo);
169 EXPECT_TRUE(stub_->is_bypassed());
170 EXPECT_FALSE(stub_->is_valid());
171
172 // We should not call through anymore.
173 EXPECT_CALL(*this, Foo0())
174 .Times(0);
175
176 EXPECT_EQ(kFooRetVal, func());
177 }
178
179 TEST_F(FunctionStubTest, FromCode) {
180 // We should get NULL and no crash from reserved memory.
181 EXPECT_EQ(NULL, FunctionStub::FromCode(playpen_ + playpen_size_));
182
183 // Create a FunctionStub pointer whose signature_
184 // field hangs just off the playpen.
185 TestFunctionStub* stub =
186 reinterpret_cast<TestFunctionStub*>(playpen_ + playpen_size_ -
187 TestFunctionStub::kSignatureOffset);
188 TestFunctionStub::Init(stub);
189 EXPECT_EQ(NULL, FunctionStub::FromCode(stub));
190
191 // Create a stub in committed memory.
192 stub = reinterpret_cast<TestFunctionStub*>(playpen_);
193 TestFunctionStub::Init(stub);
194 // Signature is NULL, which won't do.
195 EXPECT_EQ(NULL, FunctionStub::FromCode(stub));
196
197 const DWORD kFlags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
198 GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT;
199
200 HMODULE my_module = NULL;
201 EXPECT_TRUE(::GetModuleHandleEx(kFlags,
202 reinterpret_cast<const wchar_t*>(&kDivertedRetVal),
203 &my_module));
204
205 // Set our module as signature.
206 stub->set_signature(my_module);
207 EXPECT_EQ(stub, FunctionStub::FromCode(stub));
208 }
209
OLDNEW
« no previous file with comments | « chrome_frame/function_stub.cc ('k') | chrome_frame/host.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698