• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "mojo/system/data_pipe.h"
6  
7  #include <stddef.h>
8  #include <stdint.h>
9  
10  #include <limits>
11  
12  #include "mojo/system/constants.h"
13  #include "testing/gtest/include/gtest/gtest.h"
14  
15  namespace mojo {
16  namespace system {
17  namespace {
18  
19  const uint32_t kSizeOfCreateOptions =
20      static_cast<uint32_t>(sizeof(MojoCreateDataPipeOptions));
21  
22  // Does a cursory sanity check of |validated_options|. Calls
23  // |ValidateCreateOptions()| on already-validated options. The validated options
24  // should be valid, and the revalidated copy should be the same.
RevalidateCreateOptions(const MojoCreateDataPipeOptions & validated_options)25  void RevalidateCreateOptions(
26      const MojoCreateDataPipeOptions& validated_options) {
27    EXPECT_EQ(kSizeOfCreateOptions, validated_options.struct_size);
28    // Nothing to check for flags.
29    EXPECT_GT(validated_options.element_num_bytes, 0u);
30    EXPECT_GT(validated_options.capacity_num_bytes, 0u);
31    EXPECT_EQ(0u,
32              validated_options.capacity_num_bytes %
33                  validated_options.element_num_bytes);
34  
35    MojoCreateDataPipeOptions revalidated_options = {};
36    EXPECT_EQ(MOJO_RESULT_OK,
37              DataPipe::ValidateCreateOptions(MakeUserPointer(&validated_options),
38                                              &revalidated_options));
39    EXPECT_EQ(validated_options.struct_size, revalidated_options.struct_size);
40    EXPECT_EQ(validated_options.element_num_bytes,
41              revalidated_options.element_num_bytes);
42    EXPECT_EQ(validated_options.capacity_num_bytes,
43              revalidated_options.capacity_num_bytes);
44    EXPECT_EQ(validated_options.flags, revalidated_options.flags);
45  }
46  
47  // Checks that a default-computed capacity is correct. (Does not duplicate the
48  // checks done by |RevalidateCreateOptions()|.)
CheckDefaultCapacity(const MojoCreateDataPipeOptions & validated_options)49  void CheckDefaultCapacity(const MojoCreateDataPipeOptions& validated_options) {
50    EXPECT_LE(validated_options.capacity_num_bytes,
51              kDefaultDataPipeCapacityBytes);
52    EXPECT_GT(validated_options.capacity_num_bytes +
53                  validated_options.element_num_bytes,
54              kDefaultDataPipeCapacityBytes);
55  }
56  
57  // Tests valid inputs to |ValidateCreateOptions()|.
TEST(DataPipeTest,ValidateCreateOptionsValid)58  TEST(DataPipeTest, ValidateCreateOptionsValid) {
59    // Default options.
60    {
61      MojoCreateDataPipeOptions validated_options = {};
62      EXPECT_EQ(
63          MOJO_RESULT_OK,
64          DataPipe::ValidateCreateOptions(NullUserPointer(), &validated_options));
65      RevalidateCreateOptions(validated_options);
66      CheckDefaultCapacity(validated_options);
67    }
68  
69    // Size member, but nothing beyond.
70    {
71      MojoCreateDataPipeOptions options = {
72          offsetof(MojoCreateDataPipeOptions, flags)  // |struct_size|.
73      };
74      MojoCreateDataPipeOptions validated_options = {};
75      EXPECT_EQ(MOJO_RESULT_OK,
76                DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
77                                                &validated_options));
78      RevalidateCreateOptions(validated_options);
79      CheckDefaultCapacity(validated_options);
80    }
81  
82    // Different flags.
83    MojoCreateDataPipeOptionsFlags flags_values[] = {
84        MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
85        MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD};
86    for (size_t i = 0; i < arraysize(flags_values); i++) {
87      const MojoCreateDataPipeOptionsFlags flags = flags_values[i];
88  
89      // Flags member, but nothing beyond.
90      {
91        MojoCreateDataPipeOptions options = {
92            // |struct_size|.
93            offsetof(MojoCreateDataPipeOptions, element_num_bytes),
94            flags  // |flags|.
95        };
96        MojoCreateDataPipeOptions validated_options = {};
97        EXPECT_EQ(MOJO_RESULT_OK,
98                  DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
99                                                  &validated_options));
100        RevalidateCreateOptions(validated_options);
101        EXPECT_EQ(options.flags, validated_options.flags);
102        CheckDefaultCapacity(validated_options);
103      }
104  
105      // Different capacities (size 1).
106      for (uint32_t capacity = 1; capacity <= 100 * 1000 * 1000; capacity *= 10) {
107        MojoCreateDataPipeOptions options = {
108            kSizeOfCreateOptions,  // |struct_size|.
109            flags,                 // |flags|.
110            1,                     // |element_num_bytes|.
111            capacity               // |capacity_num_bytes|.
112        };
113        MojoCreateDataPipeOptions validated_options = {};
114        EXPECT_EQ(MOJO_RESULT_OK,
115                  DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
116                                                  &validated_options))
117            << capacity;
118        RevalidateCreateOptions(validated_options);
119        EXPECT_EQ(options.flags, validated_options.flags);
120        EXPECT_EQ(options.element_num_bytes, validated_options.element_num_bytes);
121        EXPECT_EQ(options.capacity_num_bytes,
122                  validated_options.capacity_num_bytes);
123      }
124  
125      // Small sizes.
126      for (uint32_t size = 1; size < 100; size++) {
127        // Different capacities.
128        for (uint32_t elements = 1; elements <= 1000 * 1000; elements *= 10) {
129          MojoCreateDataPipeOptions options = {
130              kSizeOfCreateOptions,  // |struct_size|.
131              flags,                 // |flags|.
132              size,                  // |element_num_bytes|.
133              size * elements        // |capacity_num_bytes|.
134          };
135          MojoCreateDataPipeOptions validated_options = {};
136          EXPECT_EQ(MOJO_RESULT_OK,
137                    DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
138                                                    &validated_options))
139              << size << ", " << elements;
140          RevalidateCreateOptions(validated_options);
141          EXPECT_EQ(options.flags, validated_options.flags);
142          EXPECT_EQ(options.element_num_bytes,
143                    validated_options.element_num_bytes);
144          EXPECT_EQ(options.capacity_num_bytes,
145                    validated_options.capacity_num_bytes);
146        }
147  
148        // Default capacity.
149        {
150          MojoCreateDataPipeOptions options = {
151              kSizeOfCreateOptions,  // |struct_size|.
152              flags,                 // |flags|.
153              size,                  // |element_num_bytes|.
154              0                      // |capacity_num_bytes|.
155          };
156          MojoCreateDataPipeOptions validated_options = {};
157          EXPECT_EQ(MOJO_RESULT_OK,
158                    DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
159                                                    &validated_options))
160              << size;
161          RevalidateCreateOptions(validated_options);
162          EXPECT_EQ(options.flags, validated_options.flags);
163          EXPECT_EQ(options.element_num_bytes,
164                    validated_options.element_num_bytes);
165          CheckDefaultCapacity(validated_options);
166        }
167  
168        // No capacity field.
169        {
170          MojoCreateDataPipeOptions options = {
171              // |struct_size|.
172              offsetof(MojoCreateDataPipeOptions, capacity_num_bytes),
173              flags,  // |flags|.
174              size    // |element_num_bytes|.
175          };
176          MojoCreateDataPipeOptions validated_options = {};
177          EXPECT_EQ(MOJO_RESULT_OK,
178                    DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
179                                                    &validated_options))
180              << size;
181          RevalidateCreateOptions(validated_options);
182          EXPECT_EQ(options.flags, validated_options.flags);
183          EXPECT_EQ(options.element_num_bytes,
184                    validated_options.element_num_bytes);
185          CheckDefaultCapacity(validated_options);
186        }
187      }
188  
189      // Larger sizes.
190      for (uint32_t size = 100; size <= 100 * 1000; size *= 10) {
191        // Capacity of 1000 elements.
192        {
193          MojoCreateDataPipeOptions options = {
194              kSizeOfCreateOptions,  // |struct_size|.
195              flags,                 // |flags|.
196              size,                  // |element_num_bytes|.
197              1000 * size            // |capacity_num_bytes|.
198          };
199          MojoCreateDataPipeOptions validated_options = {};
200          EXPECT_EQ(MOJO_RESULT_OK,
201                    DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
202                                                    &validated_options))
203              << size;
204          RevalidateCreateOptions(validated_options);
205          EXPECT_EQ(options.flags, validated_options.flags);
206          EXPECT_EQ(options.element_num_bytes,
207                    validated_options.element_num_bytes);
208          EXPECT_EQ(options.capacity_num_bytes,
209                    validated_options.capacity_num_bytes);
210        }
211  
212        // Default capacity.
213        {
214          MojoCreateDataPipeOptions options = {
215              kSizeOfCreateOptions,  // |struct_size|.
216              flags,                 // |flags|.
217              size,                  // |element_num_bytes|.
218              0                      // |capacity_num_bytes|.
219          };
220          MojoCreateDataPipeOptions validated_options = {};
221          EXPECT_EQ(MOJO_RESULT_OK,
222                    DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
223                                                    &validated_options))
224              << size;
225          RevalidateCreateOptions(validated_options);
226          EXPECT_EQ(options.flags, validated_options.flags);
227          EXPECT_EQ(options.element_num_bytes,
228                    validated_options.element_num_bytes);
229          CheckDefaultCapacity(validated_options);
230        }
231  
232        // No capacity field.
233        {
234          MojoCreateDataPipeOptions options = {
235              // |struct_size|.
236              offsetof(MojoCreateDataPipeOptions, capacity_num_bytes),
237              flags,  // |flags|.
238              size    // |element_num_bytes|.
239          };
240          MojoCreateDataPipeOptions validated_options = {};
241          EXPECT_EQ(MOJO_RESULT_OK,
242                    DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
243                                                    &validated_options))
244              << size;
245          RevalidateCreateOptions(validated_options);
246          EXPECT_EQ(options.flags, validated_options.flags);
247          EXPECT_EQ(options.element_num_bytes,
248                    validated_options.element_num_bytes);
249          CheckDefaultCapacity(validated_options);
250        }
251      }
252    }
253  }
254  
TEST(DataPipeTest,ValidateCreateOptionsInvalid)255  TEST(DataPipeTest, ValidateCreateOptionsInvalid) {
256    // Invalid |struct_size|.
257    {
258      MojoCreateDataPipeOptions options = {
259          1,                                        // |struct_size|.
260          MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,  // |flags|.
261          1,                                        // |element_num_bytes|.
262          0                                         // |capacity_num_bytes|.
263      };
264      MojoCreateDataPipeOptions unused;
265      EXPECT_EQ(
266          MOJO_RESULT_INVALID_ARGUMENT,
267          DataPipe::ValidateCreateOptions(MakeUserPointer(&options), &unused));
268    }
269  
270    // Unknown |flags|.
271    {
272      MojoCreateDataPipeOptions options = {
273          kSizeOfCreateOptions,  // |struct_size|.
274          ~0u,                   // |flags|.
275          1,                     // |element_num_bytes|.
276          0                      // |capacity_num_bytes|.
277      };
278      MojoCreateDataPipeOptions unused;
279      EXPECT_EQ(
280          MOJO_RESULT_UNIMPLEMENTED,
281          DataPipe::ValidateCreateOptions(MakeUserPointer(&options), &unused));
282    }
283  
284    // Invalid |element_num_bytes|.
285    {
286      MojoCreateDataPipeOptions options = {
287          kSizeOfCreateOptions,                     // |struct_size|.
288          MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,  // |flags|.
289          0,                                        // |element_num_bytes|.
290          1000                                      // |capacity_num_bytes|.
291      };
292      MojoCreateDataPipeOptions unused;
293      EXPECT_EQ(
294          MOJO_RESULT_INVALID_ARGUMENT,
295          DataPipe::ValidateCreateOptions(MakeUserPointer(&options), &unused));
296    }
297    // |element_num_bytes| too big.
298    {
299      MojoCreateDataPipeOptions options = {
300          kSizeOfCreateOptions,                     // |struct_size|.
301          MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,  // |flags|.
302          std::numeric_limits<uint32_t>::max(),     // |element_num_bytes|.
303          std::numeric_limits<uint32_t>::max()      // |capacity_num_bytes|.
304      };
305      MojoCreateDataPipeOptions unused;
306      EXPECT_EQ(
307          MOJO_RESULT_RESOURCE_EXHAUSTED,
308          DataPipe::ValidateCreateOptions(MakeUserPointer(&options), &unused));
309    }
310    {
311      MojoCreateDataPipeOptions options = {
312          kSizeOfCreateOptions,                         // |struct_size|.
313          MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,      // |flags|.
314          std::numeric_limits<uint32_t>::max() - 1000,  // |element_num_bytes|.
315          std::numeric_limits<uint32_t>::max() - 1000   // |capacity_num_bytes|.
316      };
317      MojoCreateDataPipeOptions unused;
318      EXPECT_EQ(
319          MOJO_RESULT_RESOURCE_EXHAUSTED,
320          DataPipe::ValidateCreateOptions(MakeUserPointer(&options), &unused));
321    }
322  
323    // Invalid |capacity_num_bytes|.
324    {
325      MojoCreateDataPipeOptions options = {
326          kSizeOfCreateOptions,                     // |struct_size|.
327          MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,  // |flags|.
328          2,                                        // |element_num_bytes|.
329          1                                         // |capacity_num_bytes|.
330      };
331      MojoCreateDataPipeOptions unused;
332      EXPECT_EQ(
333          MOJO_RESULT_INVALID_ARGUMENT,
334          DataPipe::ValidateCreateOptions(MakeUserPointer(&options), &unused));
335    }
336    {
337      MojoCreateDataPipeOptions options = {
338          kSizeOfCreateOptions,                     // |struct_size|.
339          MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,  // |flags|.
340          2,                                        // |element_num_bytes|.
341          111                                       // |capacity_num_bytes|.
342      };
343      MojoCreateDataPipeOptions unused;
344      EXPECT_EQ(
345          MOJO_RESULT_INVALID_ARGUMENT,
346          DataPipe::ValidateCreateOptions(MakeUserPointer(&options), &unused));
347    }
348    {
349      MojoCreateDataPipeOptions options = {
350          kSizeOfCreateOptions,                     // |struct_size|.
351          MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,  // |flags|.
352          5,                                        // |element_num_bytes|.
353          104                                       // |capacity_num_bytes|.
354      };
355      MojoCreateDataPipeOptions unused;
356      EXPECT_EQ(
357          MOJO_RESULT_INVALID_ARGUMENT,
358          DataPipe::ValidateCreateOptions(MakeUserPointer(&options), &unused));
359    }
360    // |capacity_num_bytes| too big.
361    {
362      MojoCreateDataPipeOptions options = {
363          kSizeOfCreateOptions,                     // |struct_size|.
364          MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,  // |flags|.
365          8,                                        // |element_num_bytes|.
366          0xffff0000                                // |capacity_num_bytes|.
367      };
368      MojoCreateDataPipeOptions unused;
369      EXPECT_EQ(
370          MOJO_RESULT_RESOURCE_EXHAUSTED,
371          DataPipe::ValidateCreateOptions(MakeUserPointer(&options), &unused));
372    }
373  }
374  
375  }  // namespace
376  }  // namespace system
377  }  // namespace mojo
378