| Index: mojo/public/cpp/bindings/tests/validation_context_unittest.cc
|
| diff --git a/mojo/public/cpp/bindings/tests/validation_context_unittest.cc b/mojo/public/cpp/bindings/tests/validation_context_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..aceaf1c0f25a61b6bdc5cc0cdbda8f3221b0187f
|
| --- /dev/null
|
| +++ b/mojo/public/cpp/bindings/tests/validation_context_unittest.cc
|
| @@ -0,0 +1,214 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include <stddef.h>
|
| +#include <stdint.h>
|
| +
|
| +#include <limits>
|
| +
|
| +#include "mojo/public/cpp/bindings/lib/serialization_util.h"
|
| +#include "mojo/public/cpp/bindings/lib/validation_context.h"
|
| +#include "mojo/public/cpp/system/core.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace mojo {
|
| +namespace test {
|
| +namespace {
|
| +
|
| +using Handle_Data = mojo::internal::Handle_Data;
|
| +
|
| +const void* ToPtr(uintptr_t ptr) {
|
| + return reinterpret_cast<const void*>(ptr);
|
| +}
|
| +
|
| +#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
|
| +TEST(ValidationContextTest, ConstructorRangeOverflow) {
|
| + {
|
| + // Test memory range overflow.
|
| + internal::ValidationContext context(
|
| + ToPtr(std::numeric_limits<uintptr_t>::max() - 3000), 5000, 0);
|
| +
|
| + EXPECT_FALSE(context.IsValidRange(
|
| + ToPtr(std::numeric_limits<uintptr_t>::max() - 3000), 1));
|
| + EXPECT_FALSE(context.ClaimMemory(
|
| + ToPtr(std::numeric_limits<uintptr_t>::max() - 3000), 1));
|
| + }
|
| +
|
| + if (sizeof(size_t) > sizeof(uint32_t)) {
|
| + // Test handle index range overflow.
|
| + size_t num_handles =
|
| + static_cast<size_t>(std::numeric_limits<uint32_t>::max()) + 5;
|
| + internal::ValidationContext context(ToPtr(0), 0, num_handles);
|
| +
|
| + EXPECT_FALSE(context.ClaimHandle(Handle_Data(0)));
|
| + EXPECT_FALSE(context.ClaimHandle(
|
| + Handle_Data(std::numeric_limits<uint32_t>::max() - 1)));
|
| +
|
| + EXPECT_TRUE(context.ClaimHandle(
|
| + Handle_Data(internal::kEncodedInvalidHandleValue)));
|
| + }
|
| +}
|
| +#endif
|
| +
|
| +TEST(ValidationContextTest, IsValidRange) {
|
| + {
|
| + internal::ValidationContext context(ToPtr(1234), 100, 0);
|
| +
|
| + // Basics.
|
| + EXPECT_FALSE(context.IsValidRange(ToPtr(100), 5));
|
| + EXPECT_FALSE(context.IsValidRange(ToPtr(1230), 50));
|
| + EXPECT_TRUE(context.IsValidRange(ToPtr(1234), 5));
|
| + EXPECT_TRUE(context.IsValidRange(ToPtr(1240), 50));
|
| + EXPECT_TRUE(context.IsValidRange(ToPtr(1234), 100));
|
| + EXPECT_FALSE(context.IsValidRange(ToPtr(1234), 101));
|
| + EXPECT_FALSE(context.IsValidRange(ToPtr(1240), 100));
|
| + EXPECT_FALSE(context.IsValidRange(ToPtr(1333), 5));
|
| + EXPECT_FALSE(context.IsValidRange(ToPtr(2234), 5));
|
| +
|
| + // ClaimMemory() updates the valid range.
|
| + EXPECT_TRUE(context.ClaimMemory(ToPtr(1254), 10));
|
| +
|
| + EXPECT_FALSE(context.IsValidRange(ToPtr(1234), 1));
|
| + EXPECT_FALSE(context.IsValidRange(ToPtr(1254), 10));
|
| + EXPECT_FALSE(context.IsValidRange(ToPtr(1263), 1));
|
| + EXPECT_FALSE(context.IsValidRange(ToPtr(1263), 10));
|
| + EXPECT_TRUE(context.IsValidRange(ToPtr(1264), 10));
|
| + EXPECT_TRUE(context.IsValidRange(ToPtr(1264), 70));
|
| + EXPECT_FALSE(context.IsValidRange(ToPtr(1264), 71));
|
| + }
|
| +
|
| + {
|
| + internal::ValidationContext context(ToPtr(1234), 100, 0);
|
| + // Should return false for empty ranges.
|
| + EXPECT_FALSE(context.IsValidRange(ToPtr(0), 0));
|
| + EXPECT_FALSE(context.IsValidRange(ToPtr(1200), 0));
|
| + EXPECT_FALSE(context.IsValidRange(ToPtr(1234), 0));
|
| + EXPECT_FALSE(context.IsValidRange(ToPtr(1240), 0));
|
| + EXPECT_FALSE(context.IsValidRange(ToPtr(2234), 0));
|
| + }
|
| +
|
| + {
|
| + // The valid memory range is empty.
|
| + internal::ValidationContext context(ToPtr(1234), 0, 0);
|
| +
|
| + EXPECT_FALSE(context.IsValidRange(ToPtr(1234), 1));
|
| + EXPECT_FALSE(context.IsValidRange(ToPtr(1234), 0));
|
| + }
|
| +
|
| + {
|
| + internal::ValidationContext context(
|
| + ToPtr(std::numeric_limits<uintptr_t>::max() - 2000), 1000, 0);
|
| +
|
| + // Test overflow.
|
| + EXPECT_FALSE(context.IsValidRange(
|
| + ToPtr(std::numeric_limits<uintptr_t>::max() - 1500), 4000));
|
| + EXPECT_FALSE(context.IsValidRange(
|
| + ToPtr(std::numeric_limits<uintptr_t>::max() - 1500),
|
| + std::numeric_limits<uint32_t>::max()));
|
| +
|
| + // This should be fine.
|
| + EXPECT_TRUE(context.IsValidRange(
|
| + ToPtr(std::numeric_limits<uintptr_t>::max() - 1500), 200));
|
| + }
|
| +}
|
| +
|
| +TEST(ValidationContextTest, ClaimHandle) {
|
| + {
|
| + internal::ValidationContext context(ToPtr(0), 0, 10);
|
| +
|
| + // Basics.
|
| + EXPECT_TRUE(context.ClaimHandle(Handle_Data(0)));
|
| + EXPECT_FALSE(context.ClaimHandle(Handle_Data(0)));
|
| +
|
| + EXPECT_TRUE(context.ClaimHandle(Handle_Data(9)));
|
| + EXPECT_FALSE(context.ClaimHandle(Handle_Data(10)));
|
| +
|
| + // Should fail because it is smaller than the max index that has been
|
| + // claimed.
|
| + EXPECT_FALSE(context.ClaimHandle(Handle_Data(8)));
|
| +
|
| + // Should return true for invalid handle.
|
| + EXPECT_TRUE(context.ClaimHandle(
|
| + Handle_Data(internal::kEncodedInvalidHandleValue)));
|
| + EXPECT_TRUE(context.ClaimHandle(
|
| + Handle_Data(internal::kEncodedInvalidHandleValue)));
|
| + }
|
| +
|
| + {
|
| + // No handle to claim.
|
| + internal::ValidationContext context(ToPtr(0), 0, 0);
|
| +
|
| + EXPECT_FALSE(context.ClaimHandle(Handle_Data(0)));
|
| +
|
| + // Should still return true for invalid handle.
|
| + EXPECT_TRUE(context.ClaimHandle(
|
| + Handle_Data(internal::kEncodedInvalidHandleValue)));
|
| + }
|
| +
|
| + {
|
| + // Test the case that |num_handles| is the same value as
|
| + // |internal::kEncodedInvalidHandleValue|.
|
| + EXPECT_EQ(internal::kEncodedInvalidHandleValue,
|
| + std::numeric_limits<uint32_t>::max());
|
| + internal::ValidationContext context(
|
| + ToPtr(0), 0, std::numeric_limits<uint32_t>::max());
|
| +
|
| + EXPECT_TRUE(context.ClaimHandle(
|
| + Handle_Data(std::numeric_limits<uint32_t>::max() - 1)));
|
| + EXPECT_FALSE(context.ClaimHandle(
|
| + Handle_Data(std::numeric_limits<uint32_t>::max() - 1)));
|
| + EXPECT_FALSE(context.ClaimHandle(Handle_Data(0)));
|
| +
|
| + // Should still return true for invalid handle.
|
| + EXPECT_TRUE(context.ClaimHandle(
|
| + Handle_Data(internal::kEncodedInvalidHandleValue)));
|
| + }
|
| +}
|
| +
|
| +TEST(ValidationContextTest, ClaimMemory) {
|
| + {
|
| + internal::ValidationContext context(ToPtr(1000), 2000, 0);
|
| +
|
| + // Basics.
|
| + EXPECT_FALSE(context.ClaimMemory(ToPtr(500), 100));
|
| + EXPECT_FALSE(context.ClaimMemory(ToPtr(800), 300));
|
| + EXPECT_TRUE(context.ClaimMemory(ToPtr(1000), 100));
|
| + EXPECT_FALSE(context.ClaimMemory(ToPtr(1099), 100));
|
| + EXPECT_TRUE(context.ClaimMemory(ToPtr(1100), 200));
|
| + EXPECT_FALSE(context.ClaimMemory(ToPtr(2000), 1001));
|
| + EXPECT_TRUE(context.ClaimMemory(ToPtr(2000), 500));
|
| + EXPECT_FALSE(context.ClaimMemory(ToPtr(2000), 500));
|
| + EXPECT_FALSE(context.ClaimMemory(ToPtr(1400), 100));
|
| + EXPECT_FALSE(context.ClaimMemory(ToPtr(3000), 1));
|
| + EXPECT_TRUE(context.ClaimMemory(ToPtr(2500), 500));
|
| + }
|
| +
|
| + {
|
| + // No memory to claim.
|
| + internal::ValidationContext context(ToPtr(10000), 0, 0);
|
| +
|
| + EXPECT_FALSE(context.ClaimMemory(ToPtr(10000), 1));
|
| + EXPECT_FALSE(context.ClaimMemory(ToPtr(10000), 0));
|
| + }
|
| +
|
| + {
|
| + internal::ValidationContext context(
|
| + ToPtr(std::numeric_limits<uintptr_t>::max() - 1000), 500, 0);
|
| +
|
| + // Test overflow.
|
| + EXPECT_FALSE(context.ClaimMemory(
|
| + ToPtr(std::numeric_limits<uintptr_t>::max() - 750), 4000));
|
| + EXPECT_FALSE(
|
| + context.ClaimMemory(ToPtr(std::numeric_limits<uintptr_t>::max() - 750),
|
| + std::numeric_limits<uint32_t>::max()));
|
| +
|
| + // This should be fine.
|
| + EXPECT_TRUE(context.ClaimMemory(
|
| + ToPtr(std::numeric_limits<uintptr_t>::max() - 750), 200));
|
| + }
|
| +}
|
| +
|
| +} // namespace
|
| +} // namespace test
|
| +} // namespace mojo
|
|
|