| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "third_party/mojo/src/mojo/edk/system/options_validation.h" | 5 #include "mojo/edk/system/options_validation.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include "mojo/public/c/system/macros.h" | 10 #include "mojo/public/c/system/macros.h" |
| 11 #include "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
| 12 | 12 |
| 13 namespace mojo { | 13 namespace mojo { |
| 14 namespace system { | 14 namespace edk { |
| 15 namespace { | 15 namespace { |
| 16 | 16 |
| 17 // Declare a test options struct just as we do in actual public headers. | 17 // Declare a test options struct just as we do in actual public headers. |
| 18 | 18 |
| 19 using TestOptionsFlags = uint32_t; | 19 using TestOptionsFlags = uint32_t; |
| 20 | 20 |
| 21 static_assert(MOJO_ALIGNOF(int64_t) == 8, "int64_t has weird alignment"); | 21 static_assert(MOJO_ALIGNOF(int64_t) == 8, "int64_t has weird alignment"); |
| 22 struct MOJO_ALIGNAS(8) TestOptions { | 22 struct MOJO_ALIGNAS(8) TestOptions { |
| 23 uint32_t struct_size; | 23 uint32_t struct_size; |
| 24 TestOptionsFlags flags; | 24 TestOptionsFlags flags; |
| 25 uint32_t member1; | 25 uint32_t member1; |
| 26 uint32_t member2; | 26 uint32_t member2; |
| 27 }; | 27 }; |
| 28 static_assert(sizeof(TestOptions) == 16, "TestOptions has wrong size"); | 28 static_assert(sizeof(TestOptions) == 16, "TestOptions has wrong size"); |
| 29 | 29 |
| 30 const uint32_t kSizeOfTestOptions = static_cast<uint32_t>(sizeof(TestOptions)); | 30 const uint32_t kSizeOfTestOptions = static_cast<uint32_t>(sizeof(TestOptions)); |
| 31 | 31 |
| 32 TEST(OptionsValidationTest, Valid) { | 32 TEST(OptionsValidationTest, Valid) { |
| 33 { | 33 { |
| 34 const TestOptions kOptions = {kSizeOfTestOptions}; | 34 const TestOptions kOptions = {kSizeOfTestOptions}; |
| 35 UserOptionsReader<TestOptions> reader(MakeUserPointer(&kOptions)); | 35 UserOptionsReader<TestOptions> reader(&kOptions); |
| 36 EXPECT_TRUE(reader.is_valid()); | 36 EXPECT_TRUE(reader.is_valid()); |
| 37 EXPECT_TRUE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, flags, reader)); | 37 EXPECT_TRUE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, flags, reader)); |
| 38 EXPECT_TRUE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, member1, reader)); | 38 EXPECT_TRUE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, member1, reader)); |
| 39 EXPECT_TRUE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, member2, reader)); | 39 EXPECT_TRUE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, member2, reader)); |
| 40 } | 40 } |
| 41 { | 41 { |
| 42 const TestOptions kOptions = {static_cast<uint32_t>( | 42 const TestOptions kOptions = {static_cast<uint32_t>( |
| 43 offsetof(TestOptions, struct_size) + sizeof(uint32_t))}; | 43 offsetof(TestOptions, struct_size) + sizeof(uint32_t))}; |
| 44 UserOptionsReader<TestOptions> reader(MakeUserPointer(&kOptions)); | 44 UserOptionsReader<TestOptions> reader(&kOptions); |
| 45 EXPECT_TRUE(reader.is_valid()); | 45 EXPECT_TRUE(reader.is_valid()); |
| 46 EXPECT_FALSE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, flags, reader)); | 46 EXPECT_FALSE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, flags, reader)); |
| 47 EXPECT_FALSE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, member1, reader)); | 47 EXPECT_FALSE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, member1, reader)); |
| 48 EXPECT_FALSE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, member2, reader)); | 48 EXPECT_FALSE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, member2, reader)); |
| 49 } | 49 } |
| 50 | 50 |
| 51 { | 51 { |
| 52 const TestOptions kOptions = { | 52 const TestOptions kOptions = { |
| 53 static_cast<uint32_t>(offsetof(TestOptions, flags) + sizeof(uint32_t))}; | 53 static_cast<uint32_t>(offsetof(TestOptions, flags) + sizeof(uint32_t))}; |
| 54 UserOptionsReader<TestOptions> reader(MakeUserPointer(&kOptions)); | 54 UserOptionsReader<TestOptions> reader(&kOptions); |
| 55 EXPECT_TRUE(reader.is_valid()); | 55 EXPECT_TRUE(reader.is_valid()); |
| 56 EXPECT_TRUE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, flags, reader)); | 56 EXPECT_TRUE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, flags, reader)); |
| 57 EXPECT_FALSE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, member1, reader)); | 57 EXPECT_FALSE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, member1, reader)); |
| 58 EXPECT_FALSE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, member2, reader)); | 58 EXPECT_FALSE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, member2, reader)); |
| 59 } | 59 } |
| 60 { | 60 { |
| 61 MOJO_ALIGNAS(8) char buf[sizeof(TestOptions) + 100] = {}; | 61 MOJO_ALIGNAS(8) char buf[sizeof(TestOptions) + 100] = {}; |
| 62 TestOptions* options = reinterpret_cast<TestOptions*>(buf); | 62 TestOptions* options = reinterpret_cast<TestOptions*>(buf); |
| 63 options->struct_size = kSizeOfTestOptions + 1; | 63 options->struct_size = kSizeOfTestOptions + 1; |
| 64 UserOptionsReader<TestOptions> reader(MakeUserPointer(options)); | 64 UserOptionsReader<TestOptions> reader(options); |
| 65 EXPECT_TRUE(reader.is_valid()); | 65 EXPECT_TRUE(reader.is_valid()); |
| 66 EXPECT_TRUE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, flags, reader)); | 66 EXPECT_TRUE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, flags, reader)); |
| 67 EXPECT_TRUE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, member1, reader)); | 67 EXPECT_TRUE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, member1, reader)); |
| 68 EXPECT_TRUE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, member2, reader)); | 68 EXPECT_TRUE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, member2, reader)); |
| 69 } | 69 } |
| 70 { | 70 { |
| 71 MOJO_ALIGNAS(8) char buf[sizeof(TestOptions) + 100] = {}; | 71 MOJO_ALIGNAS(8) char buf[sizeof(TestOptions) + 100] = {}; |
| 72 TestOptions* options = reinterpret_cast<TestOptions*>(buf); | 72 TestOptions* options = reinterpret_cast<TestOptions*>(buf); |
| 73 options->struct_size = kSizeOfTestOptions + 4; | 73 options->struct_size = kSizeOfTestOptions + 4; |
| 74 UserOptionsReader<TestOptions> reader(MakeUserPointer(options)); | 74 UserOptionsReader<TestOptions> reader(options); |
| 75 EXPECT_TRUE(reader.is_valid()); | 75 EXPECT_TRUE(reader.is_valid()); |
| 76 EXPECT_TRUE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, flags, reader)); | 76 EXPECT_TRUE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, flags, reader)); |
| 77 EXPECT_TRUE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, member1, reader)); | 77 EXPECT_TRUE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, member1, reader)); |
| 78 EXPECT_TRUE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, member2, reader)); | 78 EXPECT_TRUE(OPTIONS_STRUCT_HAS_MEMBER(TestOptions, member2, reader)); |
| 79 } | 79 } |
| 80 } | 80 } |
| 81 | 81 |
| 82 TEST(OptionsValidationTest, Invalid) { | 82 TEST(OptionsValidationTest, Invalid) { |
| 83 // Size too small: | 83 // Size too small: |
| 84 for (size_t i = 0; i < sizeof(uint32_t); i++) { | 84 for (size_t i = 0; i < sizeof(uint32_t); i++) { |
| 85 TestOptions options = {static_cast<uint32_t>(i)}; | 85 TestOptions options = {static_cast<uint32_t>(i)}; |
| 86 UserOptionsReader<TestOptions> reader(MakeUserPointer(&options)); | 86 UserOptionsReader<TestOptions> reader(&options); |
| 87 EXPECT_FALSE(reader.is_valid()) << i; | 87 EXPECT_FALSE(reader.is_valid()) << i; |
| 88 } | 88 } |
| 89 } | 89 } |
| 90 | 90 |
| 91 // These test invalid arguments that should cause death if we're being paranoid | 91 // These test invalid arguments that should cause death if we're being paranoid |
| 92 // about checking arguments (which we would want to do if, e.g., we were in a | 92 // about checking arguments (which we would want to do if, e.g., we were in a |
| 93 // true "kernel" situation, but we might not want to do otherwise for | 93 // true "kernel" situation, but we might not want to do otherwise for |
| 94 // performance reasons). Probably blatant errors like passing in null pointers | 94 // performance reasons). Probably blatant errors like passing in null pointers |
| 95 // (for required pointer arguments) will still cause death, but perhaps not | 95 // (for required pointer arguments) will still cause death, but perhaps not |
| 96 // predictably. | 96 // predictably. |
| 97 TEST(OptionsValidationTest, InvalidDeath) { | 97 TEST(OptionsValidationTest, InvalidDeath) { |
| 98 const char kMemoryCheckFailedRegex[] = "Check failed"; | 98 const char kMemoryCheckFailedRegex[] = "Check failed"; |
| 99 | 99 |
| 100 // Null: | 100 // Null: |
| 101 EXPECT_DEATH_IF_SUPPORTED( | 101 EXPECT_DEATH_IF_SUPPORTED( |
| 102 { UserOptionsReader<TestOptions> reader((NullUserPointer())); }, | 102 { UserOptionsReader<TestOptions> reader((nullptr)); }, |
| 103 kMemoryCheckFailedRegex); | 103 kMemoryCheckFailedRegex); |
| 104 | 104 |
| 105 // Unaligned: | 105 // Unaligned: |
| 106 EXPECT_DEATH_IF_SUPPORTED( | 106 EXPECT_DEATH_IF_SUPPORTED( |
| 107 { | 107 { |
| 108 UserOptionsReader<TestOptions> reader( | 108 UserOptionsReader<TestOptions> reader( |
| 109 MakeUserPointer(reinterpret_cast<const TestOptions*>(1))); | 109 reinterpret_cast<const TestOptions*>(1)); |
| 110 }, | 110 }, |
| 111 kMemoryCheckFailedRegex); | 111 kMemoryCheckFailedRegex); |
| 112 // Note: The current implementation checks the size only after checking the | 112 // Note: The current implementation checks the size only after checking the |
| 113 // alignment versus that required for the |uint32_t| size, so it won't die in | 113 // alignment versus that required for the |uint32_t| size, so it won't die in |
| 114 // the expected way if you pass, e.g., 4. So we have to manufacture a valid | 114 // the expected way if you pass, e.g., 4. So we have to manufacture a valid |
| 115 // pointer at an offset of alignment 4. | 115 // pointer at an offset of alignment 4. |
| 116 EXPECT_DEATH_IF_SUPPORTED( | 116 EXPECT_DEATH_IF_SUPPORTED( |
| 117 { | 117 { |
| 118 uint32_t buffer[100] = {}; | 118 uint32_t buffer[100] = {}; |
| 119 TestOptions* options = (reinterpret_cast<uintptr_t>(buffer) % 8 == 0) | 119 TestOptions* options = (reinterpret_cast<uintptr_t>(buffer) % 8 == 0) |
| 120 ? reinterpret_cast<TestOptions*>(&buffer[1]) | 120 ? reinterpret_cast<TestOptions*>(&buffer[1]) |
| 121 : reinterpret_cast<TestOptions*>(&buffer[0]); | 121 : reinterpret_cast<TestOptions*>(&buffer[0]); |
| 122 options->struct_size = static_cast<uint32_t>(sizeof(TestOptions)); | 122 options->struct_size = static_cast<uint32_t>(sizeof(TestOptions)); |
| 123 UserOptionsReader<TestOptions> reader(MakeUserPointer(options)); | 123 UserOptionsReader<TestOptions> reader(options); |
| 124 }, | 124 }, |
| 125 kMemoryCheckFailedRegex); | 125 kMemoryCheckFailedRegex); |
| 126 } | 126 } |
| 127 | 127 |
| 128 } // namespace | 128 } // namespace |
| 129 } // namespace system | 129 } // namespace edk |
| 130 } // namespace mojo | 130 } // namespace mojo |
| OLD | NEW |