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