Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / ppapi / proxy / nacl_message_scanner_unittest.cc
1 // Copyright 2013 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 #include "ipc/ipc_message.h"
6 #include "ppapi/proxy/nacl_message_scanner.h"
7 #include "ppapi/proxy/ppapi_messages.h"
8 #include "ppapi/proxy/ppapi_proxy_test.h"
9 #include "ppapi/proxy/serialized_handle.h"
10 #include "ppapi/shared_impl/host_resource.h"
11
12 namespace ppapi {
13 namespace proxy {
14
15 namespace {
16 const PP_Resource kInvalidResource = 0;
17 const PP_Resource kFileSystem = 1;
18 const PP_Resource kFileIO = 2;
19 const int64_t kQuotaReservationAmount = 100;
20 }
21
22 class NaClMessageScannerTest : public PluginProxyTest {
23  public:
24   NaClMessageScannerTest() {}
25
26   uint32 FindPendingSyncMessage(
27       const NaClMessageScanner& scanner,
28       const IPC::Message& msg) {
29     int msg_id = IPC::SyncMessage::GetMessageId(msg);
30     std::map<int, uint32>::const_iterator it =
31         scanner.pending_sync_msgs_.find(msg_id);
32     // O can signal that no message was found.
33     return (it != scanner.pending_sync_msgs_.end()) ? it->second : 0;
34   }
35
36   NaClMessageScanner::FileSystem* FindFileSystem(
37       const NaClMessageScanner& scanner,
38       PP_Resource file_system) {
39     NaClMessageScanner::FileSystemMap::const_iterator it =
40         scanner.file_systems_.find(file_system);
41     return (it != scanner.file_systems_.end()) ? it->second : NULL;
42   }
43
44   NaClMessageScanner::FileIO* FindFileIO(
45       const NaClMessageScanner& scanner,
46       PP_Resource file_io) {
47     NaClMessageScanner::FileIOMap::const_iterator it =
48         scanner.files_.find(file_io);
49     return (it != scanner.files_.end()) ? it->second : NULL;
50   }
51
52   void OpenQuotaFile(NaClMessageScanner* scanner,
53                      PP_Resource file_io,
54                      PP_Resource file_system) {
55     std::vector<SerializedHandle> unused_handles;
56     ResourceMessageReplyParams fio_reply_params(file_io, 0);
57     scoped_ptr<IPC::Message> new_msg_ptr;
58     scanner->ScanMessage(
59       PpapiPluginMsg_ResourceReply(
60           fio_reply_params,
61           PpapiPluginMsg_FileIO_OpenReply(file_system, 0)),
62       &unused_handles,
63       &new_msg_ptr);
64     EXPECT_FALSE(new_msg_ptr);
65   }
66 };
67
68 TEST_F(NaClMessageScannerTest, SyncMessageAndReply) {
69   NaClMessageScanner test;
70   ppapi::proxy::SerializedHandle handle(
71       ppapi::proxy::SerializedHandle::SHARED_MEMORY);
72   IPC::Message msg =
73       PpapiHostMsg_PPBGraphics3D_GetTransferBuffer(
74           ppapi::API_ID_PPB_GRAPHICS_3D,
75           HostResource(),
76           0,  // id
77           &handle);
78   scoped_ptr<IPC::Message> new_msg_ptr;
79   EXPECT_NE(msg.type(), FindPendingSyncMessage(test, msg));
80   test.ScanUntrustedMessage(msg, &new_msg_ptr);
81   EXPECT_FALSE(new_msg_ptr);
82   EXPECT_EQ(msg.type(), FindPendingSyncMessage(test, msg));
83
84   // TODO(bbudge) Figure out how to put together a sync reply message.
85 }
86
87 TEST_F(NaClMessageScannerTest, FileOpenClose) {
88   NaClMessageScanner test;
89   std::vector<SerializedHandle> unused_handles;
90   ResourceMessageCallParams fio_call_params(kFileIO, 0);
91   ResourceMessageCallParams fs_call_params(kFileSystem, 0);
92   ResourceMessageReplyParams fio_reply_params(kFileIO, 0);
93   ResourceMessageReplyParams fs_reply_params(kFileSystem, 0);
94   scoped_ptr<IPC::Message> new_msg_ptr;
95
96   EXPECT_EQ(NULL, FindFileSystem(test, kFileSystem));
97   EXPECT_EQ(NULL, FindFileIO(test, kFileIO));
98
99   // Open a file, not in a quota file system.
100   test.ScanMessage(
101       PpapiPluginMsg_ResourceReply(
102           fio_reply_params,
103           PpapiPluginMsg_FileIO_OpenReply(kInvalidResource, 0)),
104       &unused_handles,
105       &new_msg_ptr);
106   EXPECT_FALSE(new_msg_ptr);
107   EXPECT_FALSE(FindFileSystem(test, kFileSystem));
108   EXPECT_FALSE(FindFileIO(test, kFileIO));
109
110   // Open a file in a quota file system; info objects for it and its file system
111   // should be created.
112   OpenQuotaFile(&test, kFileIO, kFileSystem);
113   NaClMessageScanner::FileSystem* fs = FindFileSystem(test, kFileSystem);
114   NaClMessageScanner::FileIO* fio = FindFileIO(test, kFileIO);
115   EXPECT_TRUE(fs);
116   EXPECT_EQ(0, fs->reserved_quota());
117   EXPECT_TRUE(fio);
118   EXPECT_EQ(0, fio->max_written_offset());
119
120   const int64_t kNewFileSize = 10;
121   fio->SetMaxWrittenOffset(kNewFileSize);
122
123   // We should not be able to under-report max_written_offset when closing.
124   test.ScanUntrustedMessage(
125       PpapiHostMsg_ResourceCall(
126           fio_call_params,
127           PpapiHostMsg_FileIO_Close(FileGrowth(0, 0))),
128       &new_msg_ptr);
129   EXPECT_TRUE(new_msg_ptr);
130   ResourceMessageCallParams call_params;
131   IPC::Message nested_msg;
132   FileGrowth file_growth;
133   EXPECT_TRUE(UnpackMessage<PpapiHostMsg_ResourceCall>(
134                   *new_msg_ptr, &call_params, &nested_msg) &&
135               UnpackMessage<PpapiHostMsg_FileIO_Close>(
136                   nested_msg, &file_growth));
137   new_msg_ptr.reset();
138   EXPECT_EQ(kNewFileSize, file_growth.max_written_offset);
139   EXPECT_FALSE(FindFileIO(test, kFileIO));
140
141   // Reopen the file.
142   OpenQuotaFile(&test, kFileIO, kFileSystem);
143   fio = FindFileIO(test, kFileIO);
144   fio->SetMaxWrittenOffset(kNewFileSize);
145
146   // Close with correct max_written_offset.
147   test.ScanUntrustedMessage(
148       PpapiHostMsg_ResourceCall(
149           fio_call_params,
150           PpapiHostMsg_FileIO_Close(FileGrowth(kNewFileSize, 0))),
151       &new_msg_ptr);
152   EXPECT_FALSE(new_msg_ptr);
153   EXPECT_FALSE(FindFileIO(test, kFileIO));
154
155   // Destroy file system.
156   test.ScanUntrustedMessage(
157       PpapiHostMsg_ResourceCall(
158           fs_call_params,
159           PpapiHostMsg_ResourceDestroyed(kFileSystem)),
160       &new_msg_ptr);
161   EXPECT_FALSE(FindFileSystem(test, kFileSystem));
162 }
163
164 TEST_F(NaClMessageScannerTest, QuotaAuditing) {
165   NaClMessageScanner test;
166   std::vector<SerializedHandle> unused_handles;
167   ResourceMessageCallParams fio_call_params(kFileIO, 0);
168   ResourceMessageCallParams fs_call_params(kFileSystem, 0);
169   ResourceMessageReplyParams fio_reply_params(kFileIO, 0);
170   ResourceMessageReplyParams fs_reply_params(kFileSystem, 0);
171   scoped_ptr<IPC::Message> new_msg_ptr;
172
173   OpenQuotaFile(&test, kFileIO, kFileSystem);
174   NaClMessageScanner::FileSystem* fs = FindFileSystem(test, kFileSystem);
175   NaClMessageScanner::FileIO* fio = FindFileIO(test, kFileIO);
176   EXPECT_TRUE(fs);
177   EXPECT_EQ(0, fs->reserved_quota());
178   EXPECT_TRUE(fio);
179   EXPECT_EQ(0, fio->max_written_offset());
180
181   // Without reserving quota, we should not be able to grow the file.
182   EXPECT_FALSE(fio->Grow(1));
183   EXPECT_EQ(0, fs->reserved_quota());
184   EXPECT_EQ(0, fio->max_written_offset());
185
186   // Receive reserved quota, and updated file sizes.
187   const int64_t kNewFileSize = 10;
188   FileSizeMap file_sizes;
189   file_sizes[kFileIO] = kNewFileSize;
190   test.ScanMessage(
191       PpapiPluginMsg_ResourceReply(
192           fs_reply_params,
193           PpapiPluginMsg_FileSystem_ReserveQuotaReply(
194               kQuotaReservationAmount,
195               file_sizes)),
196       &unused_handles,
197       &new_msg_ptr);
198   EXPECT_FALSE(new_msg_ptr);
199   EXPECT_EQ(kQuotaReservationAmount, fs->reserved_quota());
200   EXPECT_EQ(kNewFileSize, fio->max_written_offset());
201
202   // We should be able to grow the file within quota.
203   EXPECT_TRUE(fio->Grow(1));
204   EXPECT_EQ(kQuotaReservationAmount - 1, fs->reserved_quota());
205   EXPECT_EQ(kNewFileSize + 1, fio->max_written_offset());
206
207   // We should not be able to grow the file over quota.
208   EXPECT_FALSE(fio->Grow(kQuotaReservationAmount));
209   EXPECT_EQ(kQuotaReservationAmount - 1, fs->reserved_quota());
210   EXPECT_EQ(kNewFileSize + 1, fio->max_written_offset());
211
212   // Plugin should not under-report max written offsets when reserving quota.
213   file_sizes[kFileIO] = 0;  // should be kNewFileSize + 1.
214   test.ScanUntrustedMessage(
215       PpapiHostMsg_ResourceCall(
216           fio_call_params,
217           PpapiHostMsg_FileSystem_ReserveQuota(
218               kQuotaReservationAmount,
219               FileSizeMapToFileGrowthMapForTesting(file_sizes))),
220       &new_msg_ptr);
221   EXPECT_TRUE(new_msg_ptr);
222   ResourceMessageCallParams call_params;
223   IPC::Message nested_msg;
224   int64_t amount = 0;
225   FileGrowthMap new_file_growths;
226   EXPECT_TRUE(UnpackMessage<PpapiHostMsg_ResourceCall>(
227                   *new_msg_ptr, &call_params, &nested_msg) &&
228               UnpackMessage<PpapiHostMsg_FileSystem_ReserveQuota>(
229                   nested_msg, &amount, &new_file_growths));
230   new_msg_ptr.reset();
231   EXPECT_EQ(kQuotaReservationAmount, amount);
232   EXPECT_EQ(kNewFileSize + 1, new_file_growths[kFileIO].max_written_offset);
233 }
234
235 TEST_F(NaClMessageScannerTest, SetLength) {
236   NaClMessageScanner test;
237   std::vector<SerializedHandle> unused_handles;
238   ResourceMessageCallParams fio_call_params(kFileIO, 0);
239   ResourceMessageCallParams fs_call_params(kFileSystem, 0);
240   ResourceMessageReplyParams fio_reply_params(kFileIO, 0);
241   ResourceMessageReplyParams fs_reply_params(kFileSystem, 0);
242   scoped_ptr<IPC::Message> new_msg_ptr;
243
244   OpenQuotaFile(&test, kFileIO, kFileSystem);
245   NaClMessageScanner::FileSystem* fs = FindFileSystem(test, kFileSystem);
246   NaClMessageScanner::FileIO* fio = FindFileIO(test, kFileIO);
247
248   // Receive reserved quota, and updated file sizes.
249   const int64_t kNewFileSize = 10;
250   FileSizeMap file_sizes;
251   file_sizes[kFileIO] = 0;
252   test.ScanMessage(
253       PpapiPluginMsg_ResourceReply(
254           fs_reply_params,
255           PpapiPluginMsg_FileSystem_ReserveQuotaReply(
256               kQuotaReservationAmount,
257               file_sizes)),
258       &unused_handles,
259       &new_msg_ptr);
260
261   // We should be able to SetLength within quota.
262   test.ScanUntrustedMessage(
263       PpapiHostMsg_ResourceCall(
264           fio_call_params,
265           PpapiHostMsg_FileIO_SetLength(kNewFileSize)),
266       &new_msg_ptr);
267   EXPECT_FALSE(new_msg_ptr);
268   EXPECT_EQ(kQuotaReservationAmount - kNewFileSize, fs->reserved_quota());
269   EXPECT_EQ(kNewFileSize, fio->max_written_offset());
270
271   // We shouldn't be able to SetLength beyond quota. The message should be
272   // rewritten to fail with length == -1.
273   test.ScanUntrustedMessage(
274       PpapiHostMsg_ResourceCall(
275           fio_call_params,
276           PpapiHostMsg_FileIO_SetLength(kQuotaReservationAmount + 1)),
277       &new_msg_ptr);
278   EXPECT_TRUE(new_msg_ptr);
279   ResourceMessageCallParams call_params;
280   IPC::Message nested_msg;
281   int64_t length = 0;
282   EXPECT_TRUE(UnpackMessage<PpapiHostMsg_ResourceCall>(
283                   *new_msg_ptr, &call_params, &nested_msg) &&
284               UnpackMessage<PpapiHostMsg_FileIO_SetLength>(
285                   nested_msg, &length));
286   new_msg_ptr.reset();
287   EXPECT_EQ(-1, length);
288   EXPECT_EQ(kQuotaReservationAmount - kNewFileSize, fs->reserved_quota());
289   EXPECT_EQ(kNewFileSize, fio->max_written_offset());
290 }
291
292 }  // namespace proxy
293 }  // namespace ppapi