☠☠ backed out by e64f0b3c8194 ☠ ☠ | |
author | june wilde <jewilde@mozilla.com> |
Tue, 17 Nov 2020 04:18:48 +0000 | |
changeset 557570 | 49e43292c047851a549e5a9a814d8f2578e6ddb4 |
parent 557569 | 46f96d192bbde81b758d6bc0662aa07d2b37c9cc |
child 557571 | 59a027d6beb52af2678a30854a4ab0240c6dc182 |
push id | 37959 |
push user | btara@mozilla.com |
push date | Tue, 17 Nov 2020 21:55:29 +0000 |
treeherder | mozilla-central@9dd0b13d77b9 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | tjr, sg |
bugs | 1658755 |
milestone | 85.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
mfbt/Tainting.h | file | annotate | diff | comparison | revisions | |
mfbt/tests/TestTainting.cpp | file | annotate | diff | comparison | revisions | |
mfbt/tests/gtest/TestTainting.cpp | file | annotate | diff | comparison | revisions | |
mfbt/tests/gtest/moz.build | file | annotate | diff | comparison | revisions | |
mfbt/tests/moz.build | file | annotate | diff | comparison | revisions |
--- a/mfbt/Tainting.h +++ b/mfbt/Tainting.h @@ -108,17 +108,17 @@ class Tainted { /* * Macros to validate and un-taint a value. * * All macros accept the tainted variable as the first argument, and a * condition as the second argument. If the condition is satisfied, * then the value is considered valid. * * This file contains documentation and examples for the functions; - * more usage examples are present in mfbt/tests/TestTainting.cpp + * more usage examples are present in mfbt/tests/gtest/TestTainting.cpp */ /* * MOZ_VALIDATE_AND_GET is the bread-and-butter validation function. * It confirms the value abides by the condition specified and then * returns the untainted value. * * If the condition is not satisified, we RELEASE_ASSERT. @@ -263,16 +263,55 @@ class Tainted { * condition - a comparison involving the tainted value * alternate_value - the value to use if the condition is false */ #define MOZ_VALIDATE_OR(tainted_value, condition, alternate_value) \ (MOZ_IS_VALID(tainted_value, condition) ? tainted_value.Coerce() \ : alternate_value) /* + * MOZ_FIND_AND_VALIDATE is for testing validity of a tainted value by comparing + * it against a list of known safe values. Returns a pointer to the matched + * safe value or nullptr if none was found. + * + * Note that for the comparison the macro will loop over the list and that the + * current element being tested against is provided as list_item. + * + * Example: + * + * Tainted<int> aId; + * NSTArray<Person> list; + * const Person* foo = MOZ_FIND_AND_VALIDATE(aId, list_item.id == aId, list); + * + * // Typically you would do nothing if invalid data is passed: + * if (MOZ_UNLIKELY(!foo)) { + * return; + * } + * + * // Or alternately you can crash on invalid data + * MOZ_RELEASE_ASSERT(foo != nullptr, "Invalid person id sent from content + * process."); + * + * Arguments: + * tainted_value - the name of the Tainted<> variable + * condition - a condition involving the tainted value and list_item + * validation_list - a list of known safe values to compare against + */ +#define MOZ_FIND_AND_VALIDATE(tainted_value, condition, validation_list) \ + [&]() { \ + auto& tmp = tainted_value.Coerce(); \ + auto& tainted_value = tmp; \ + const auto macro_find_it = \ + std::find_if(validation_list.cbegin(), validation_list.cend(), \ + [&](const auto& list_item) { return condition; }); \ + return macro_find_it != validation_list.cend() ? &*macro_find_it \ + : nullptr; \ + }() + +/* * MOZ_NO_VALIDATE allows unsafe removal of the Taint wrapper. * A justification string is required to explain why this is acceptable. * * Example: * * bar = MOZ_NO_VALIDATE( * foo, * "Value is used to match against a dictionary key in the parent."
rename from mfbt/tests/TestTainting.cpp rename to mfbt/tests/gtest/TestTainting.cpp --- a/mfbt/tests/TestTainting.cpp +++ b/mfbt/tests/gtest/TestTainting.cpp @@ -1,279 +1,484 @@ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "gtest/gtest.h" #include <math.h> #include "mozilla/Assertions.h" +#include "mozilla/Range.h" #include "mozilla/Tainting.h" +#include "nsTHashtable.h" +#include "nsHashKeys.h" +#include "nsTArray.h" +#include <array> +#include <deque> +#include <forward_list> +#include <list> +#include <map> +#include <set> +#include <unordered_map> +#include <unordered_set> +#include <vector> using mozilla::Tainted; -#define EXPECTED_VALUE 10 +#define EXPECTED_INT 10 +#define EXPECTED_CHAR 'z' static bool externalFunction(int arg) { return arg > 2; } -static void TestTainting() { +// ================================================================== +// MOZ_VALIDATE_AND_GET ============================================= +TEST(Tainting, moz_validate_and_get) +{ int bar; - Tainted<int> foo = Tainted<int>(EXPECTED_VALUE); - - // ================================================================== - // MOZ_VALIDATE_AND_GET ============================================= + int comparisonVariable = 20; + Tainted<int> foo = Tainted<int>(EXPECTED_INT); bar = MOZ_VALIDATE_AND_GET(foo, foo < 20); - MOZ_RELEASE_ASSERT(bar == EXPECTED_VALUE); + ASSERT_EQ(bar, EXPECTED_INT); // This test is for comparison to an external variable, testing the // default capture mode of the lambda used inside the macro. - int comparisonVariable = 20; bar = MOZ_VALIDATE_AND_GET(foo, foo < comparisonVariable); - MOZ_RELEASE_ASSERT(bar == EXPECTED_VALUE); + ASSERT_EQ(bar, EXPECTED_INT); bar = MOZ_VALIDATE_AND_GET( foo, foo < 20, "foo must be less than 20 because higher values represent decibel" "levels greater than a a jet engine inside your ear."); - MOZ_RELEASE_ASSERT(bar == EXPECTED_VALUE); + ASSERT_EQ(bar, EXPECTED_INT); // Test an external variable with a comment. bar = MOZ_VALIDATE_AND_GET(foo, foo < comparisonVariable, "Test comment"); - MOZ_RELEASE_ASSERT(bar == EXPECTED_VALUE); + ASSERT_EQ(bar, EXPECTED_INT); // Test an external function with a comment. bar = MOZ_VALIDATE_AND_GET(foo, externalFunction(foo), "Test comment"); - MOZ_RELEASE_ASSERT(bar == EXPECTED_VALUE); + ASSERT_EQ(bar, EXPECTED_INT); // Lambda Tests - bar = MOZ_VALIDATE_AND_GET(foo, ([&foo]() { - bool intermediateResult = externalFunction(foo); - if (intermediateResult) { - return true; - } - return false; - }())); - MOZ_RELEASE_ASSERT(bar == EXPECTED_VALUE); + bar = + MOZ_VALIDATE_AND_GET(foo, ([&foo]() { return externalFunction(foo); }())); + ASSERT_EQ(bar, EXPECTED_INT); // This test is for the lambda variant with a supplied assertion // string. - bar = MOZ_VALIDATE_AND_GET(foo, ([&foo]() { - bool intermediateResult = externalFunction(foo); - if (intermediateResult) { - return true; - } - return false; - }()), - "This tests a comment"); - MOZ_RELEASE_ASSERT(bar == EXPECTED_VALUE); + bar = + MOZ_VALIDATE_AND_GET(foo, ([&foo]() { return externalFunction(foo); }()), + "This tests a comment"); + ASSERT_EQ(bar, EXPECTED_INT); // This test is for the lambda variant with a captured variable - bar = - MOZ_VALIDATE_AND_GET(foo, ([&foo, &comparisonVariable] { - bool intermediateResult = externalFunction(foo); - if (intermediateResult || comparisonVariable < 4) { - return true; - } - return false; - }()), - "This tests a comment"); - MOZ_RELEASE_ASSERT(bar == EXPECTED_VALUE); + bar = MOZ_VALIDATE_AND_GET(foo, ([&foo, &comparisonVariable] { + bool intermediateResult = externalFunction(foo); + return intermediateResult || + comparisonVariable < 4; + }()), + "This tests a comment"); + ASSERT_EQ(bar, EXPECTED_INT); // This test is for the lambda variant with full capture mode - bar = - MOZ_VALIDATE_AND_GET(foo, ([&] { - bool intermediateResult = externalFunction(foo); - if (intermediateResult || comparisonVariable < 4) { - return true; - } - return false; - }()), - "This tests a comment"); - MOZ_RELEASE_ASSERT(bar == EXPECTED_VALUE); + bar = MOZ_VALIDATE_AND_GET(foo, ([&] { + bool intermediateResult = externalFunction(foo); + return intermediateResult || + comparisonVariable < 4; + }()), + "This tests a comment"); + ASSERT_EQ(bar, EXPECTED_INT); // External lambdas - auto lambda1 = [](int foo) { + auto lambda1 = [](int foo) { return externalFunction(foo); }; + + auto lambda2 = [&](int foo) { bool intermediateResult = externalFunction(foo); - if (intermediateResult) { - return true; - } - return false; + return intermediateResult || comparisonVariable < 4; }; + + // Test with an explicit capture + auto lambda3 = [&comparisonVariable](int foo) { + bool intermediateResult = externalFunction(foo); + return intermediateResult || comparisonVariable < 4; + }; + bar = MOZ_VALIDATE_AND_GET(foo, lambda1(foo)); - MOZ_RELEASE_ASSERT(bar == EXPECTED_VALUE); + ASSERT_EQ(bar, EXPECTED_INT); // Test with a comment bar = MOZ_VALIDATE_AND_GET(foo, lambda1(foo), "Test comment."); - MOZ_RELEASE_ASSERT(bar == EXPECTED_VALUE); + ASSERT_EQ(bar, EXPECTED_INT); // Test with a default capture mode + bar = MOZ_VALIDATE_AND_GET(foo, lambda2(foo), "Test comment."); + ASSERT_EQ(bar, EXPECTED_INT); + + bar = MOZ_VALIDATE_AND_GET(foo, lambda3(foo), "Test comment."); + ASSERT_EQ(bar, EXPECTED_INT); + + // We can't test MOZ_VALIDATE_AND_GET failing, because that triggers + // a release assert. +} + +// ================================================================== +// MOZ_IS_VALID ===================================================== +TEST(Tainting, moz_is_valid) +{ + int comparisonVariable = 20; + Tainted<int> foo = Tainted<int>(EXPECTED_INT); + + ASSERT_TRUE(MOZ_IS_VALID(foo, foo < 20)); + + ASSERT_FALSE(MOZ_IS_VALID(foo, foo > 20)); + + ASSERT_TRUE(MOZ_IS_VALID(foo, foo < comparisonVariable)); + + ASSERT_TRUE( + MOZ_IS_VALID(foo, ([&foo]() { return externalFunction(foo); }()))); + + ASSERT_TRUE(MOZ_IS_VALID(foo, ([&foo, &comparisonVariable]() { + bool intermediateResult = externalFunction(foo); + return intermediateResult || + comparisonVariable < 4; + }()))); + + // External lambdas + auto lambda1 = [](int foo) { return externalFunction(foo); }; + auto lambda2 = [&](int foo) { bool intermediateResult = externalFunction(foo); - if (intermediateResult || comparisonVariable < 4) { - return true; - } - return false; + return intermediateResult || comparisonVariable < 4; + }; + + // Test with an explicit capture + auto lambda3 = [&comparisonVariable](int foo) { + bool intermediateResult = externalFunction(foo); + return intermediateResult || comparisonVariable < 4; }; - bar = MOZ_VALIDATE_AND_GET(foo, lambda2(foo), "Test comment."); - MOZ_RELEASE_ASSERT(bar == EXPECTED_VALUE); + + ASSERT_TRUE(MOZ_IS_VALID(foo, lambda1(foo))); + + ASSERT_TRUE(MOZ_IS_VALID(foo, lambda2(foo))); + + ASSERT_TRUE(MOZ_IS_VALID(foo, lambda3(foo))); +} + +// ================================================================== +// MOZ_VALIDATE_OR ================================================== +TEST(Tainting, moz_validate_or) +{ + int result; + int comparisonVariable = 20; + Tainted<int> foo = Tainted<int>(EXPECTED_INT); + + result = MOZ_VALIDATE_OR(foo, foo < 20, 100); + ASSERT_EQ(result, EXPECTED_INT); + + result = MOZ_VALIDATE_OR(foo, foo > 20, 100); + ASSERT_EQ(result, 100); + + result = MOZ_VALIDATE_OR(foo, foo < comparisonVariable, 100); + ASSERT_EQ(result, EXPECTED_INT); + + // External lambdas + auto lambda1 = [](int foo) { return externalFunction(foo); }; + + auto lambda2 = [&](int foo) { + bool intermediateResult = externalFunction(foo); + return intermediateResult || comparisonVariable < 4; + }; // Test with an explicit capture auto lambda3 = [&comparisonVariable](int foo) { bool intermediateResult = externalFunction(foo); - if (intermediateResult || comparisonVariable < 4) { - return true; - } - return false; + return intermediateResult || comparisonVariable < 4; }; - bar = MOZ_VALIDATE_AND_GET(foo, lambda3(foo), "Test comment."); - MOZ_RELEASE_ASSERT(bar == EXPECTED_VALUE); - - // We can't test MOZ_VALIDATE_AND_GET failing, because that triggers - // a release assert. - - // ================================================================== - // MOZ_IS_VALID ===================================================== - if (MOZ_IS_VALID(foo, foo < 20)) { - MOZ_RELEASE_ASSERT(true); - } else { - MOZ_RELEASE_ASSERT(false); - } - - if (MOZ_IS_VALID(foo, foo > 20)) { - MOZ_RELEASE_ASSERT(false); - } else { - MOZ_RELEASE_ASSERT(true); - } - - if (MOZ_IS_VALID(foo, foo < comparisonVariable)) { - MOZ_RELEASE_ASSERT(true); - } else { - MOZ_RELEASE_ASSERT(false); - } - - if (MOZ_IS_VALID(foo, ([&foo]() { - bool intermediateResult = externalFunction(foo); - if (intermediateResult) { - return true; - } - return false; - }()))) { - MOZ_RELEASE_ASSERT(true); - } else { - MOZ_RELEASE_ASSERT(false); - } - - if (MOZ_IS_VALID(foo, ([&foo, &comparisonVariable]() { - bool intermediateResult = externalFunction(foo); - if (intermediateResult || comparisonVariable < 4) { - return true; - } - return false; - }()))) { - MOZ_RELEASE_ASSERT(true); - } else { - MOZ_RELEASE_ASSERT(false); - } - - if (MOZ_IS_VALID(foo, lambda1(foo))) { - MOZ_RELEASE_ASSERT(true); - } else { - MOZ_RELEASE_ASSERT(false); - } - - if (MOZ_IS_VALID(foo, lambda2(foo))) { - MOZ_RELEASE_ASSERT(true); - } else { - MOZ_RELEASE_ASSERT(false); - } - - if (MOZ_IS_VALID(foo, lambda3(foo))) { - MOZ_RELEASE_ASSERT(true); - } else { - MOZ_RELEASE_ASSERT(false); - } - - // ================================================================== - // MOZ_VALIDATE_OR ================================================== - - int result; - - result = MOZ_VALIDATE_OR(foo, foo < 20, 100); - MOZ_RELEASE_ASSERT(result == EXPECTED_VALUE); - - result = MOZ_VALIDATE_OR(foo, foo > 20, 100); - MOZ_RELEASE_ASSERT(result == 100); - - result = MOZ_VALIDATE_OR(foo, foo < comparisonVariable, 100); - MOZ_RELEASE_ASSERT(result == EXPECTED_VALUE); result = MOZ_VALIDATE_OR(foo, lambda1(foo), 100); - MOZ_RELEASE_ASSERT(result == EXPECTED_VALUE); + ASSERT_EQ(result, EXPECTED_INT); result = MOZ_VALIDATE_OR(foo, lambda2(foo), 100); - MOZ_RELEASE_ASSERT(result == EXPECTED_VALUE); + ASSERT_EQ(result, EXPECTED_INT); result = MOZ_VALIDATE_OR(foo, lambda3(foo), 100); - MOZ_RELEASE_ASSERT(result == EXPECTED_VALUE); + ASSERT_EQ(result, EXPECTED_INT); - result = MOZ_VALIDATE_OR(foo, ([&foo]() { - bool intermediateResult = externalFunction(foo); - if (intermediateResult) { - return true; - } - return false; - }()), - 100); - MOZ_RELEASE_ASSERT(result == EXPECTED_VALUE); + result = + MOZ_VALIDATE_OR(foo, ([&foo]() { return externalFunction(foo); }()), 100); + ASSERT_EQ(result, EXPECTED_INT); // This test is for the lambda variant with a supplied assertion // string. - result = MOZ_VALIDATE_OR(foo, ([&foo] { - bool intermediateResult = externalFunction(foo); - if (intermediateResult) { - return true; - } - return false; - }()), - 100); - MOZ_RELEASE_ASSERT(result == EXPECTED_VALUE); + result = + MOZ_VALIDATE_OR(foo, ([&foo] { return externalFunction(foo); }()), 100); + ASSERT_EQ(result, EXPECTED_INT); // This test is for the lambda variant with a captured variable - result = MOZ_VALIDATE_OR(foo, ([&foo, &comparisonVariable] { - bool intermediateResult = externalFunction(foo); - if (intermediateResult || comparisonVariable < 4) { - return true; - } - return false; - }()), - 100); - MOZ_RELEASE_ASSERT(result == EXPECTED_VALUE); + result = + MOZ_VALIDATE_OR(foo, ([&foo, &comparisonVariable] { + bool intermediateResult = externalFunction(foo); + return intermediateResult || comparisonVariable < 4; + }()), + 100); + ASSERT_EQ(result, EXPECTED_INT); // This test is for the lambda variant with full capture mode - result = MOZ_VALIDATE_OR(foo, ([&] { - bool intermediateResult = externalFunction(foo); - if (intermediateResult || comparisonVariable < 4) { - return true; - } - return false; - }()), - 100); - MOZ_RELEASE_ASSERT(result == EXPECTED_VALUE); + result = + MOZ_VALIDATE_OR(foo, ([&] { + bool intermediateResult = externalFunction(foo); + return intermediateResult || comparisonVariable < 4; + }()), + 100); + ASSERT_EQ(result, EXPECTED_INT); +} + +// ================================================================== +// MOZ_FIND_AND_VALIDATE ============================================ +TEST(Tainting, moz_find_and_validate) +{ + Tainted<int> foo = Tainted<int>(EXPECTED_INT); + Tainted<char> baz = Tainted<char>(EXPECTED_CHAR); + + //------------------------------- + const mozilla::Array<int, 6> mozarrayWithFoo(0, 5, EXPECTED_INT, 15, 20, 25); + const mozilla::Array<int, 5> mozarrayWithoutFoo(0, 5, 15, 20, 25); + + ASSERT_TRUE(*MOZ_FIND_AND_VALIDATE(foo, list_item == foo, mozarrayWithFoo) == + mozarrayWithFoo[2]); + + ASSERT_TRUE(MOZ_FIND_AND_VALIDATE(foo, list_item == foo, + mozarrayWithoutFoo) == nullptr); + + //------------------------------- + class TestClass { + public: + int a; + int b; + + TestClass(int a, int b) { + this->a = a; + this->b = b; + } + + bool operator==(const TestClass& other) const { + return this->a == other.a && this->b == other.b; + } + }; + + const mozilla::Array<TestClass, 5> mozarrayOfClassesWithFoo( + TestClass(0, 1), TestClass(2, 3), TestClass(EXPECTED_INT, EXPECTED_INT), + TestClass(4, 5), TestClass(6, 7)); + + ASSERT_TRUE(*MOZ_FIND_AND_VALIDATE( + foo, foo == list_item.a && foo == list_item.b, + mozarrayOfClassesWithFoo) == mozarrayOfClassesWithFoo[2]); + + ASSERT_TRUE(*MOZ_FIND_AND_VALIDATE( + foo, (foo == list_item.a && foo == list_item.b), + mozarrayOfClassesWithFoo) == mozarrayOfClassesWithFoo[2]); + + ASSERT_TRUE( + *MOZ_FIND_AND_VALIDATE( + foo, + (foo == list_item.a && foo == list_item.b && externalFunction(foo)), + mozarrayOfClassesWithFoo) == mozarrayOfClassesWithFoo[2]); + + ASSERT_TRUE(*MOZ_FIND_AND_VALIDATE( + foo, ([](int tainted_val, TestClass list_item) { + return tainted_val == list_item.a && + tainted_val == list_item.b; + }(foo, list_item)), + mozarrayOfClassesWithFoo) == mozarrayOfClassesWithFoo[2]); + + auto lambda4 = [](int tainted_val, TestClass list_item) { + return tainted_val == list_item.a && tainted_val == list_item.b; + }; + + ASSERT_TRUE(*MOZ_FIND_AND_VALIDATE(foo, lambda4(foo, list_item), + mozarrayOfClassesWithFoo) == + mozarrayOfClassesWithFoo[2]); + + //------------------------------- + const char m = 'm'; + const char o = 'o'; + const char z = EXPECTED_CHAR; + const char l = 'l'; + const char a = 'a'; + + nsTHashtable<nsCharPtrHashKey> hashtableWithBaz; + hashtableWithBaz.PutEntry(&m); + hashtableWithBaz.PutEntry(&o); + hashtableWithBaz.PutEntry(&z); + hashtableWithBaz.PutEntry(&l); + hashtableWithBaz.PutEntry(&a); + nsTHashtable<nsCharPtrHashKey> hashtableWithoutBaz; + hashtableWithoutBaz.PutEntry(&m); + hashtableWithoutBaz.PutEntry(&o); + hashtableWithoutBaz.PutEntry(&l); + hashtableWithoutBaz.PutEntry(&a); + + ASSERT_TRUE(MOZ_FIND_AND_VALIDATE(baz, *list_item.GetKey() == baz, + hashtableWithBaz) == + hashtableWithBaz.GetEntry(&z)); + + ASSERT_TRUE(MOZ_FIND_AND_VALIDATE(baz, *list_item.GetKey() == baz, + hashtableWithoutBaz) == nullptr); + + //------------------------------- + const nsTArray<int> nsTArrayWithFoo = {0, 5, EXPECTED_INT, 15, 20, 25}; + const nsTArray<int> nsTArrayWithoutFoo = {0, 5, 15, 20, 25}; + + ASSERT_TRUE(*MOZ_FIND_AND_VALIDATE(foo, list_item == foo, nsTArrayWithFoo) == + nsTArrayWithFoo[2]); + + ASSERT_TRUE(MOZ_FIND_AND_VALIDATE(foo, list_item == foo, + nsTArrayWithoutFoo) == nullptr); + + //------------------------------- + const std::array<int, 6> arrayWithFoo{0, 5, EXPECTED_INT, 15, 20, 25}; + const std::array<int, 5> arrayWithoutFoo{0, 5, 15, 20, 25}; + + ASSERT_TRUE(*MOZ_FIND_AND_VALIDATE(foo, list_item == foo, arrayWithFoo) == + arrayWithFoo[2]); + + ASSERT_TRUE(MOZ_FIND_AND_VALIDATE(foo, list_item == foo, arrayWithoutFoo) == + nullptr); - // ================================================================== - // MOZ_NO_VALIDATE ================================================== + //------------------------------- + const std::deque<int> dequeWithFoo{0, 5, EXPECTED_INT, 15, 20, 25}; + const std::deque<int> dequeWithoutFoo{0, 5, 15, 20, 25}; + + ASSERT_TRUE(*MOZ_FIND_AND_VALIDATE(foo, list_item == foo, dequeWithFoo) == + dequeWithFoo[2]); + + ASSERT_TRUE(MOZ_FIND_AND_VALIDATE(foo, list_item == foo, dequeWithoutFoo) == + nullptr); + + //------------------------------- + const std::forward_list<int> forwardWithFoo{0, 5, EXPECTED_INT, 15, 20, 25}; + const std::forward_list<int> forwardWithoutFoo{0, 5, 15, 20, 25}; + + auto forwardListIt = forwardWithFoo.begin(); + std::advance(forwardListIt, 2); + + ASSERT_TRUE(*MOZ_FIND_AND_VALIDATE(foo, list_item == foo, forwardWithFoo) == + *forwardListIt); + + ASSERT_TRUE(MOZ_FIND_AND_VALIDATE(foo, list_item == foo, forwardWithoutFoo) == + nullptr); + + //------------------------------- + const std::list<int> listWithFoo{0, 5, EXPECTED_INT, 15, 20, 25}; + const std::list<int> listWithoutFoo{0, 5, 15, 20, 25}; + + auto listIt = listWithFoo.begin(); + std::advance(listIt, 2); + + ASSERT_TRUE(*MOZ_FIND_AND_VALIDATE(foo, list_item == foo, listWithFoo) == + *listIt); + + ASSERT_TRUE(MOZ_FIND_AND_VALIDATE(foo, list_item == foo, listWithoutFoo) == + nullptr); + + //------------------------------- + const std::map<std::string, int> mapWithFoo{{ + {"zero", 0}, + {"five", 5}, + {"ten", EXPECTED_INT}, + {"fifteen", 15}, + {"twenty", 20}, + {"twenty-five", 25}, + }}; + const std::map<std::string, int> mapWithoutFoo{{ + {"zero", 0}, + {"five", 5}, + {"fifteen", 15}, + {"twenty", 20}, + {"twenty-five", 25}, + }}; + + const auto map_it = mapWithFoo.find("ten"); + + ASSERT_TRUE( + MOZ_FIND_AND_VALIDATE(foo, list_item.second == foo, mapWithFoo)->second == + map_it->second); + + ASSERT_TRUE(MOZ_FIND_AND_VALIDATE(foo, list_item.second == foo, + mapWithoutFoo) == nullptr); + + //------------------------------- + const std::set<int> setWithFoo{0, 5, EXPECTED_INT, 15, 20, 25}; + const std::set<int> setWithoutFoo{0, 5, 15, 20, 25}; + + auto setIt = setWithFoo.find(EXPECTED_INT); + + ASSERT_TRUE(*MOZ_FIND_AND_VALIDATE(foo, list_item == foo, setWithFoo) == + *setIt); + + ASSERT_TRUE(MOZ_FIND_AND_VALIDATE(foo, list_item == foo, setWithoutFoo) == + nullptr); + + //------------------------------- + const std::unordered_map<std::string, int> unordermapWithFoo = { + {"zero", 0}, {"five", 5}, {"ten", EXPECTED_INT}, + {"fifteen", 15}, {"twenty", 20}, {"twenty-five", 25}, + }; + const std::unordered_map<std::string, int> unordermapWithoutFoo{{ + {"zero", 0}, + {"five", 5}, + {"fifteen", 15}, + {"twenty", 20}, + {"twenty-five", 25}, + }}; + + auto unorderedMapIt = unordermapWithFoo.find("ten"); + + ASSERT_TRUE( + MOZ_FIND_AND_VALIDATE(foo, list_item.second == foo, unordermapWithFoo) + ->second == unorderedMapIt->second); + + ASSERT_TRUE(MOZ_FIND_AND_VALIDATE(foo, list_item.second == foo, + unordermapWithoutFoo) == nullptr); + + //------------------------------- + const std::unordered_set<int> unorderedsetWithFoo{0, 5, EXPECTED_INT, + 15, 20, 25}; + const std::unordered_set<int> unorderedsetWithoutFoo{0, 5, 15, 20, 25}; + + auto unorderedSetIt = unorderedsetWithFoo.find(EXPECTED_INT); + + ASSERT_TRUE(*MOZ_FIND_AND_VALIDATE(foo, list_item == foo, + unorderedsetWithFoo) == *unorderedSetIt); + + ASSERT_TRUE(MOZ_FIND_AND_VALIDATE(foo, list_item == foo, + unorderedsetWithoutFoo) == nullptr); + + //------------------------------- + const std::vector<int> vectorWithFoo{0, 5, EXPECTED_INT, 15, 20, 25}; + const std::vector<int> vectorWithoutFoo{0, 5, 15, 20, 25}; + + ASSERT_TRUE(*MOZ_FIND_AND_VALIDATE(foo, list_item == foo, vectorWithFoo) == + vectorWithFoo[2]); + + ASSERT_TRUE(MOZ_FIND_AND_VALIDATE(foo, list_item == foo, vectorWithoutFoo) == + nullptr); +} + +// ================================================================== +// MOZ_NO_VALIDATE ================================================== +TEST(Tainting, moz_no_validate) +{ + int result; + Tainted<int> foo = Tainted<int>(EXPECTED_INT); + result = MOZ_NO_VALIDATE( foo, "Value is used to match against a dictionary key in the parent." "If there's no key present, there won't be a match." "There is no risk of grabbing a cross-origin value from the dictionary," "because the IPC actor is instatiated per-content-process and the " "dictionary is not shared between actors."); - MOZ_RELEASE_ASSERT(result == EXPECTED_VALUE); + ASSERT_TRUE(result == EXPECTED_INT); } - -int main() { - TestTainting(); - - return 0; -}
--- a/mfbt/tests/gtest/moz.build +++ b/mfbt/tests/gtest/moz.build @@ -4,28 +4,29 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. UNIFIED_SOURCES += [ "TestBuffer.cpp", "TestLinkedList.cpp", "TestReverseIterator.cpp", "TestSpan.cpp", + "TestTainting.cpp", ] SOURCES += [ "TestAlgorithm.cpp", "TestInitializedOnce.cpp", "TestMainThreadWeakPtr.cpp", "TestResultExtensions.cpp", ] if not CONFIG["MOZILLA_OFFICIAL"]: UNIFIED_SOURCES += [ # MOZ_DBG is not defined in MOZILLA_OFFICIAL builds. "TestMozDbg.cpp", ] # LOCAL_INCLUDES += [ -# '../../base', +# "../../base", # ] FINAL_LIBRARY = "xul-gtest"
--- a/mfbt/tests/moz.build +++ b/mfbt/tests/moz.build @@ -55,17 +55,16 @@ CppUnitTests( "TestRollingMean", "TestSaturate", "TestScopeExit", "TestSegmentedVector", "TestSHA1", "TestSmallPointerArray", "TestSplayTree", "TestSPSCQueue", - "TestTainting", "TestTemplateLib", "TestTextUtils", "TestThreadSafeWeakPtr", "TestTuple", "TestTypedEnum", "TestTypeTraits", "TestUniquePtr", "TestVariant",