Upstream version 10.39.225.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   NaClMessageScanner::FileSystem* FindFileSystem(
27       const NaClMessageScanner& scanner,
28       PP_Resource file_system) {
29     NaClMessageScanner::FileSystemMap::const_iterator it =
30         scanner.file_systems_.find(file_system);
31     return (it != scanner.file_systems_.end()) ? it->second : NULL;
32   }
33
34   NaClMessageScanner::FileIO* FindFileIO(
35       const NaClMessageScanner& scanner,
36       PP_Resource file_io) {
37     NaClMessageScanner::FileIOMap::const_iterator it =
38         scanner.files_.find(file_io);
39     return (it != scanner.files_.end()) ? it->second : NULL;
40   }
41
42   void OpenQuotaFile(NaClMessageScanner* scanner,
43                      PP_Resource file_io,
44                      PP_Resource file_system) {
45     std::vector<SerializedHandle> unused_handles;
46     ResourceMessageReplyParams fio_reply_params(file_io, 0);
47     scoped_ptr<IPC::Message> new_msg_ptr;
48     scanner->ScanMessage(
49         PpapiPluginMsg_ResourceReply(
50             fio_reply_params,
51             PpapiPluginMsg_FileIO_OpenReply(file_system, 0)),
52         PpapiPluginMsg_ResourceReply::ID,
53         &unused_handles,
54         &new_msg_ptr);
55     EXPECT_FALSE(new_msg_ptr);
56   }
57 };
58
59 TEST_F(NaClMessageScannerTest, FileOpenClose) {
60   NaClMessageScanner test;
61   std::vector<SerializedHandle> unused_handles;
62   ResourceMessageCallParams fio_call_params(kFileIO, 0);
63   ResourceMessageCallParams fs_call_params(kFileSystem, 0);
64   ResourceMessageReplyParams fio_reply_params(kFileIO, 0);
65   ResourceMessageReplyParams fs_reply_params(kFileSystem, 0);
66   scoped_ptr<IPC::Message> new_msg_ptr;
67
68   EXPECT_EQ(NULL, FindFileSystem(test, kFileSystem));
69   EXPECT_EQ(NULL, FindFileIO(test, kFileIO));
70
71   // Open a file, not in a quota file system.
72   test.ScanMessage(
73       PpapiPluginMsg_ResourceReply(
74           fio_reply_params,
75           PpapiPluginMsg_FileIO_OpenReply(kInvalidResource, 0)),
76       PpapiPluginMsg_ResourceReply::ID,
77       &unused_handles,
78       &new_msg_ptr);
79   EXPECT_FALSE(new_msg_ptr);
80   EXPECT_FALSE(FindFileSystem(test, kFileSystem));
81   EXPECT_FALSE(FindFileIO(test, kFileIO));
82
83   // Open a file in a quota file system; info objects for it and its file system
84   // should be created.
85   OpenQuotaFile(&test, kFileIO, kFileSystem);
86   NaClMessageScanner::FileSystem* fs = FindFileSystem(test, kFileSystem);
87   NaClMessageScanner::FileIO* fio = FindFileIO(test, kFileIO);
88   EXPECT_TRUE(fs);
89   EXPECT_EQ(0, fs->reserved_quota());
90   EXPECT_TRUE(fio);
91   EXPECT_EQ(0, fio->max_written_offset());
92
93   const int64_t kNewFileSize = 10;
94   fio->SetMaxWrittenOffset(kNewFileSize);
95
96   // We should not be able to under-report max_written_offset when closing.
97   test.ScanUntrustedMessage(
98       PpapiHostMsg_ResourceCall(
99           fio_call_params,
100           PpapiHostMsg_FileIO_Close(FileGrowth(0, 0))),
101       &new_msg_ptr);
102   EXPECT_TRUE(new_msg_ptr);
103   ResourceMessageCallParams call_params;
104   IPC::Message nested_msg;
105   FileGrowth file_growth;
106   EXPECT_TRUE(UnpackMessage<PpapiHostMsg_ResourceCall>(
107                   *new_msg_ptr, &call_params, &nested_msg) &&
108               UnpackMessage<PpapiHostMsg_FileIO_Close>(
109                   nested_msg, &file_growth));
110   new_msg_ptr.reset();
111   EXPECT_EQ(kNewFileSize, file_growth.max_written_offset);
112   EXPECT_FALSE(FindFileIO(test, kFileIO));
113
114   // Reopen the file.
115   OpenQuotaFile(&test, kFileIO, kFileSystem);
116   fio = FindFileIO(test, kFileIO);
117   fio->SetMaxWrittenOffset(kNewFileSize);
118
119   // Close with correct max_written_offset.
120   test.ScanUntrustedMessage(
121       PpapiHostMsg_ResourceCall(
122           fio_call_params,
123           PpapiHostMsg_FileIO_Close(FileGrowth(kNewFileSize, 0))),
124       &new_msg_ptr);
125   EXPECT_FALSE(new_msg_ptr);
126   EXPECT_FALSE(FindFileIO(test, kFileIO));
127
128   // Destroy file system.
129   test.ScanUntrustedMessage(
130       PpapiHostMsg_ResourceCall(
131           fs_call_params,
132           PpapiHostMsg_ResourceDestroyed(kFileSystem)),
133       &new_msg_ptr);
134   EXPECT_FALSE(FindFileSystem(test, kFileSystem));
135 }
136
137 TEST_F(NaClMessageScannerTest, QuotaAuditing) {
138   NaClMessageScanner test;
139   std::vector<SerializedHandle> unused_handles;
140   ResourceMessageCallParams fio_call_params(kFileIO, 0);
141   ResourceMessageCallParams fs_call_params(kFileSystem, 0);
142   ResourceMessageReplyParams fio_reply_params(kFileIO, 0);
143   ResourceMessageReplyParams fs_reply_params(kFileSystem, 0);
144   scoped_ptr<IPC::Message> new_msg_ptr;
145
146   OpenQuotaFile(&test, kFileIO, kFileSystem);
147   NaClMessageScanner::FileSystem* fs = FindFileSystem(test, kFileSystem);
148   NaClMessageScanner::FileIO* fio = FindFileIO(test, kFileIO);
149   EXPECT_TRUE(fs);
150   EXPECT_EQ(0, fs->reserved_quota());
151   EXPECT_TRUE(fio);
152   EXPECT_EQ(0, fio->max_written_offset());
153
154   // Without reserving quota, we should not be able to grow the file.
155   EXPECT_FALSE(fio->Grow(1));
156   EXPECT_EQ(0, fs->reserved_quota());
157   EXPECT_EQ(0, fio->max_written_offset());
158
159   // Receive reserved quota, and updated file sizes.
160   const int64_t kNewFileSize = 10;
161   FileSizeMap file_sizes;
162   file_sizes[kFileIO] = kNewFileSize;
163   test.ScanMessage(
164       PpapiPluginMsg_ResourceReply(
165           fs_reply_params,
166           PpapiPluginMsg_FileSystem_ReserveQuotaReply(
167               kQuotaReservationAmount,
168               file_sizes)),
169       PpapiPluginMsg_ResourceReply::ID,
170       &unused_handles,
171       &new_msg_ptr);
172   EXPECT_FALSE(new_msg_ptr);
173   EXPECT_EQ(kQuotaReservationAmount, fs->reserved_quota());
174   EXPECT_EQ(kNewFileSize, fio->max_written_offset());
175
176   // We should be able to grow the file within quota.
177   EXPECT_TRUE(fio->Grow(1));
178   EXPECT_EQ(kQuotaReservationAmount - 1, fs->reserved_quota());
179   EXPECT_EQ(kNewFileSize + 1, fio->max_written_offset());
180
181   // We should not be able to grow the file over quota.
182   EXPECT_FALSE(fio->Grow(kQuotaReservationAmount));
183   EXPECT_EQ(kQuotaReservationAmount - 1, fs->reserved_quota());
184   EXPECT_EQ(kNewFileSize + 1, fio->max_written_offset());
185
186   // Plugin should not under-report max written offsets when reserving quota.
187   file_sizes[kFileIO] = 0;  // should be kNewFileSize + 1.
188   test.ScanUntrustedMessage(
189       PpapiHostMsg_ResourceCall(
190           fio_call_params,
191           PpapiHostMsg_FileSystem_ReserveQuota(
192               kQuotaReservationAmount,
193               FileSizeMapToFileGrowthMapForTesting(file_sizes))),
194       &new_msg_ptr);
195   EXPECT_TRUE(new_msg_ptr);
196   ResourceMessageCallParams call_params;
197   IPC::Message nested_msg;
198   int64_t amount = 0;
199   FileGrowthMap new_file_growths;
200   EXPECT_TRUE(UnpackMessage<PpapiHostMsg_ResourceCall>(
201                   *new_msg_ptr, &call_params, &nested_msg) &&
202               UnpackMessage<PpapiHostMsg_FileSystem_ReserveQuota>(
203                   nested_msg, &amount, &new_file_growths));
204   new_msg_ptr.reset();
205   EXPECT_EQ(kQuotaReservationAmount, amount);
206   EXPECT_EQ(kNewFileSize + 1, new_file_growths[kFileIO].max_written_offset);
207 }
208
209 TEST_F(NaClMessageScannerTest, SetLength) {
210   NaClMessageScanner test;
211   std::vector<SerializedHandle> unused_handles;
212   ResourceMessageCallParams fio_call_params(kFileIO, 0);
213   ResourceMessageCallParams fs_call_params(kFileSystem, 0);
214   ResourceMessageReplyParams fio_reply_params(kFileIO, 0);
215   ResourceMessageReplyParams fs_reply_params(kFileSystem, 0);
216   scoped_ptr<IPC::Message> new_msg_ptr;
217
218   OpenQuotaFile(&test, kFileIO, kFileSystem);
219   NaClMessageScanner::FileSystem* fs = FindFileSystem(test, kFileSystem);
220   NaClMessageScanner::FileIO* fio = FindFileIO(test, kFileIO);
221
222   // Receive reserved quota, and updated file sizes.
223   const int64_t kNewFileSize = 10;
224   FileSizeMap file_sizes;
225   file_sizes[kFileIO] = 0;
226   test.ScanMessage(
227       PpapiPluginMsg_ResourceReply(
228           fs_reply_params,
229           PpapiPluginMsg_FileSystem_ReserveQuotaReply(
230               kQuotaReservationAmount,
231               file_sizes)),
232       PpapiPluginMsg_ResourceReply::ID,
233       &unused_handles,
234       &new_msg_ptr);
235
236   // We should be able to SetLength within quota.
237   test.ScanUntrustedMessage(
238       PpapiHostMsg_ResourceCall(
239           fio_call_params,
240           PpapiHostMsg_FileIO_SetLength(kNewFileSize)),
241       &new_msg_ptr);
242   EXPECT_FALSE(new_msg_ptr);
243   EXPECT_EQ(kQuotaReservationAmount - kNewFileSize, fs->reserved_quota());
244   EXPECT_EQ(kNewFileSize, fio->max_written_offset());
245
246   // We shouldn't be able to SetLength beyond quota. The message should be
247   // rewritten to fail with length == -1.
248   test.ScanUntrustedMessage(
249       PpapiHostMsg_ResourceCall(
250           fio_call_params,
251           PpapiHostMsg_FileIO_SetLength(kQuotaReservationAmount + 1)),
252       &new_msg_ptr);
253   EXPECT_TRUE(new_msg_ptr);
254   ResourceMessageCallParams call_params;
255   IPC::Message nested_msg;
256   int64_t length = 0;
257   EXPECT_TRUE(UnpackMessage<PpapiHostMsg_ResourceCall>(
258                   *new_msg_ptr, &call_params, &nested_msg) &&
259               UnpackMessage<PpapiHostMsg_FileIO_SetLength>(
260                   nested_msg, &length));
261   new_msg_ptr.reset();
262   EXPECT_EQ(-1, length);
263   EXPECT_EQ(kQuotaReservationAmount - kNewFileSize, fs->reserved_quota());
264   EXPECT_EQ(kNewFileSize, fio->max_written_offset());
265 }
266
267 }  // namespace proxy
268 }  // namespace ppapi