mirror of
https://github.com/QuasarApp/LIEF.git
synced 2025-04-29 05:44:32 +00:00
524 lines
12 KiB
C++
524 lines
12 KiB
C++
/* Copyright 2017 - 2021 R. Thomas
|
|
* Copyright 2017 - 2021 Quarkslab
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
#define CATCH_CONFIG_MAIN
|
|
#include <catch.hpp>
|
|
|
|
#include <LIEF/iterators.hpp>
|
|
|
|
using namespace LIEF;
|
|
using it_const_ref_t = const_ref_iterator<std::vector<std::string>>;
|
|
using it_ref_local_t = ref_iterator<std::vector<std::string>>;
|
|
using it_ref_t = ref_iterator<std::vector<std::string>&>;
|
|
|
|
using it_const_ref_ptr_t = const_ref_iterator<std::vector<std::string*>>;
|
|
using it_ref_ptr_t = ref_iterator<std::vector<std::string*>>;
|
|
|
|
using it_filter_ref = filter_iterator<std::vector<std::string>&>;
|
|
using it_filter_ref_local_t = filter_iterator<std::vector<std::string>>;
|
|
using it_filter_ref_ptr = filter_iterator<std::vector<std::string*>>;
|
|
|
|
using it_filter_const_ref = const_filter_iterator<const std::vector<std::string>&>;
|
|
using it_filter_const_ref_local = const_filter_iterator<std::vector<std::string>>;
|
|
using it_filter_const_ref_ptr = const_filter_iterator<std::vector<std::string*>>;
|
|
|
|
struct Dummy {
|
|
Dummy(void) : s_{"dummy"} {}
|
|
Dummy(const Dummy&) = delete;
|
|
Dummy& operator=(const Dummy&) = delete;
|
|
std::string s_;
|
|
};
|
|
|
|
using it_ref_dummies_t = ref_iterator<std::vector<Dummy>&>;
|
|
|
|
struct Foo {
|
|
Foo(void) : dummies_(10) {
|
|
bar.push_back("1");
|
|
bar.push_back("2");
|
|
bar.push_back("3");
|
|
bar.push_back("4");
|
|
bar.push_back("5");
|
|
bar.push_back("6");
|
|
bar.push_back("6");
|
|
bar.push_back("6");
|
|
|
|
bar_ptr.push_back(new std::string{"1"});
|
|
bar_ptr.push_back(new std::string{"2"});
|
|
bar_ptr.push_back(new std::string{"3"});
|
|
bar_ptr.push_back(new std::string{"4"});
|
|
bar_ptr.push_back(new std::string{"5"});
|
|
bar_ptr.push_back(new std::string{"6"});
|
|
bar_ptr.push_back(new std::string{"6"});
|
|
}
|
|
|
|
~Foo(void) {
|
|
for (std::string* ptr : this->bar_ptr) {
|
|
delete ptr;
|
|
}
|
|
}
|
|
|
|
it_const_ref_t get_bar(void) const {
|
|
return {this->bar};
|
|
}
|
|
|
|
|
|
it_ref_t get_bar(void) {
|
|
return {this->bar};
|
|
}
|
|
|
|
it_filter_ref filter_always_true(void) {
|
|
return {this->bar, [] (const std::string& v) { return true; }};
|
|
}
|
|
|
|
it_filter_ref get_bar_filter(void) {
|
|
return {this->bar, [] (const std::string& v) { return v == "6" or v == "1" or v == "foo"; }};
|
|
}
|
|
|
|
|
|
it_filter_ref get_bar_filter_empty(void) {
|
|
return {this->bar, [] (const std::string& v) { return v == "foo"; }};
|
|
}
|
|
|
|
|
|
it_filter_const_ref get_bar_filter(void) const {
|
|
return {this->bar, [] (const std::string& v) { return v == "6" or v == "1" or v == "foo"; }};
|
|
}
|
|
|
|
|
|
it_filter_ref_ptr get_bar_ptr_filter(void) {
|
|
return {this->bar_ptr, [] (const std::string* v) { return *v == "6"; }};
|
|
}
|
|
|
|
it_filter_const_ref_ptr get_bar_ptr_filter(void) const {
|
|
return {this->bar_ptr, [] (const std::string* v) { return *v == "6"; }};
|
|
}
|
|
|
|
|
|
it_ref_local_t get_bar_local(void) {
|
|
std::vector<std::string> local = {"a", "b", "c"};
|
|
return {local};
|
|
}
|
|
|
|
|
|
it_filter_const_ref_local get_bar_const_filter_local(void) const {
|
|
std::vector<std::string> local = {"a", "b", "c", "a", "a"};
|
|
return {local, [] (const std::string& v) { return v == "a"; }};
|
|
}
|
|
|
|
|
|
|
|
it_ref_dummies_t get_dummies(void) {
|
|
return {this->dummies_};
|
|
}
|
|
|
|
it_const_ref_ptr_t get_bar_ptr(void) const {
|
|
return {bar_ptr};
|
|
}
|
|
|
|
it_ref_ptr_t get_bar_ptr(void) {
|
|
return {bar_ptr};
|
|
}
|
|
|
|
std::vector<Dummy> dummies_;
|
|
std::vector<std::string> bar;
|
|
std::vector<std::string*> bar_ptr;
|
|
};
|
|
|
|
|
|
TEST_CASE("Test const ref iterators", "[lief][iterators][const_ref]") {
|
|
|
|
const Foo foo;
|
|
|
|
SECTION("operator++") {
|
|
it_const_ref_t bars = foo.get_bar();
|
|
REQUIRE(*(bars++) == "1");
|
|
REQUIRE(*bars == "2");
|
|
}
|
|
|
|
|
|
SECTION("operator++(int)") {
|
|
it_const_ref_t bars = foo.get_bar();
|
|
REQUIRE(*(++bars) == "2");
|
|
REQUIRE(*(++bars) == "3");
|
|
REQUIRE(*(++bars) == "4");
|
|
}
|
|
|
|
|
|
SECTION("operator--") {
|
|
it_const_ref_t bars = foo.get_bar();
|
|
++bars;
|
|
REQUIRE(*(bars--) == "2");
|
|
REQUIRE(*bars == "1");
|
|
}
|
|
|
|
|
|
SECTION("operator--(int)") {
|
|
it_const_ref_t bars = foo.get_bar();
|
|
|
|
++bars;
|
|
REQUIRE(*(--bars) == "1");
|
|
REQUIRE(*bars == "1");
|
|
}
|
|
|
|
|
|
SECTION("operator+=") {
|
|
it_const_ref_t bars = foo.get_bar();
|
|
bars += 2;
|
|
REQUIRE(*bars == "3");
|
|
}
|
|
|
|
|
|
SECTION("operator-=") {
|
|
it_const_ref_t bars = foo.get_bar();
|
|
bars += 4;
|
|
REQUIRE(*bars == "5");
|
|
|
|
bars -= 2;
|
|
REQUIRE(*bars == "3");
|
|
}
|
|
|
|
SECTION("operator[]") {
|
|
it_const_ref_t bars = foo.get_bar();
|
|
REQUIRE(bars[4] == "5");
|
|
}
|
|
|
|
|
|
SECTION("operator+") {
|
|
it_const_ref_t bars = foo.get_bar();
|
|
REQUIRE(*(bars + 5) == "6");
|
|
}
|
|
|
|
|
|
SECTION("operator-") {
|
|
it_const_ref_t bars = foo.get_bar();
|
|
bars += 4;
|
|
REQUIRE(*(bars - 1) == "4");
|
|
}
|
|
|
|
|
|
SECTION("Comparaisons") {
|
|
it_const_ref_t bars_lhs = foo.get_bar();
|
|
it_const_ref_t bars_rhs = foo.get_bar();
|
|
REQUIRE(bars_lhs == bars_rhs);
|
|
REQUIRE(std::begin(bars_lhs) == std::begin(bars_rhs));
|
|
REQUIRE(std::end(bars_lhs) == std::end(bars_rhs));
|
|
REQUIRE(std::end(bars_lhs) != std::begin(bars_rhs));
|
|
|
|
REQUIRE((bars_lhs + 5) == (bars_rhs + 5));
|
|
REQUIRE((bars_lhs + 5) != (bars_rhs + 6));
|
|
|
|
it_const_ref_t it1 = bars_lhs + 5;
|
|
it_const_ref_t it2 = bars_rhs + 4;
|
|
|
|
REQUIRE(it1 != it2);
|
|
REQUIRE((it1 - 1) == it2);
|
|
REQUIRE((it1 - it2) == 1);
|
|
|
|
REQUIRE(it1 > it2);
|
|
REQUIRE(it1 >= it1);
|
|
|
|
|
|
REQUIRE(it2 < it1);
|
|
REQUIRE(it2 <= it2);
|
|
}
|
|
|
|
|
|
SECTION("Internal management") {
|
|
it_const_ref_t bars = foo.get_bar();
|
|
it_const_ref_ptr_t bars_ptr = foo.get_bar_ptr();
|
|
|
|
REQUIRE(bars.size() == foo.bar.size());
|
|
REQUIRE(bars_ptr.size() == foo.bar_ptr.size());
|
|
REQUIRE(*bars_ptr == "1");
|
|
REQUIRE(std::string(bars_ptr->c_str()) == "1");
|
|
REQUIRE(bars_ptr[2] == "3");
|
|
|
|
REQUIRE(std::string(bars->c_str()) == "1");
|
|
REQUIRE(std::string(bars_ptr->c_str()) == "1");
|
|
size_t count = std::count_if(
|
|
std::begin(bars),
|
|
std::end(bars),
|
|
[] (const std::string& s) {
|
|
return s == "6";
|
|
});
|
|
|
|
REQUIRE(count == 3);
|
|
|
|
it_const_ref_t bar_operator_equal{bars};
|
|
bar_operator_equal += 2;
|
|
//bar_operator_equal.operator=(bars);
|
|
//REQUIRE(bar_operator_equal == bars);
|
|
|
|
}
|
|
}
|
|
|
|
TEST_CASE("Test ref iterators", "[lief][iterators][ref]") {
|
|
Foo foo;
|
|
|
|
SECTION("operator++") {
|
|
it_ref_t bars = foo.get_bar();
|
|
REQUIRE(*(bars++) == "1");
|
|
REQUIRE(*bars == "2");
|
|
}
|
|
|
|
SECTION("operator++(int)") {
|
|
it_ref_t bars = foo.get_bar();
|
|
REQUIRE(*(++bars) == "2");
|
|
REQUIRE(*(++bars) == "3");
|
|
REQUIRE(*(++bars) == "4");
|
|
}
|
|
|
|
|
|
SECTION("operator--") {
|
|
it_ref_t bars = foo.get_bar();
|
|
++bars;
|
|
REQUIRE(*(bars--) == "2");
|
|
REQUIRE(*bars == "1");
|
|
}
|
|
|
|
|
|
SECTION("operator--(int)") {
|
|
it_ref_t bars = foo.get_bar();
|
|
|
|
++bars;
|
|
REQUIRE(*(--bars) == "1");
|
|
REQUIRE(*bars == "1");
|
|
}
|
|
|
|
|
|
SECTION("operator+=") {
|
|
it_ref_t bars = foo.get_bar();
|
|
bars += 2;
|
|
REQUIRE(*bars == "3");
|
|
}
|
|
|
|
|
|
SECTION("operator-=") {
|
|
it_ref_t bars = foo.get_bar();
|
|
bars += 4;
|
|
REQUIRE(*bars == "5");
|
|
|
|
bars -= 2;
|
|
REQUIRE(*bars == "3");
|
|
}
|
|
|
|
SECTION("operator[]") {
|
|
it_ref_t bars = foo.get_bar();
|
|
REQUIRE(bars[4] == "5");
|
|
}
|
|
|
|
|
|
SECTION("operator+") {
|
|
it_ref_t bars = foo.get_bar();
|
|
REQUIRE(*(bars + 5) == "6");
|
|
}
|
|
|
|
|
|
SECTION("operator-") {
|
|
it_ref_t bars = foo.get_bar();
|
|
bars += 4;
|
|
REQUIRE(*(bars - 1) == "4");
|
|
}
|
|
|
|
|
|
SECTION("Comparaisons") {
|
|
it_ref_t bars_lhs = foo.get_bar();
|
|
it_ref_t bars_rhs = foo.get_bar();
|
|
REQUIRE(bars_lhs == bars_rhs);
|
|
REQUIRE(std::begin(bars_lhs) == std::begin(bars_lhs));
|
|
REQUIRE(std::end(bars_lhs) == std::end(bars_lhs));
|
|
|
|
REQUIRE(std::begin(bars_lhs) == std::begin(bars_rhs));
|
|
REQUIRE(std::end(bars_lhs) == std::end(bars_rhs));
|
|
REQUIRE(std::end(bars_lhs) != std::begin(bars_rhs));
|
|
|
|
REQUIRE((bars_lhs + 5) == (bars_rhs + 5));
|
|
REQUIRE((bars_lhs + 5) != (bars_rhs + 6));
|
|
|
|
it_ref_t it1 = bars_lhs + 5;
|
|
it_ref_t it2 = bars_rhs + 4;
|
|
|
|
REQUIRE(it1 != it2);
|
|
REQUIRE((it1 - 1) == it2);
|
|
REQUIRE((it1 - it2) == 1);
|
|
|
|
REQUIRE(it1 > it2);
|
|
REQUIRE(it1 >= it1);
|
|
|
|
|
|
REQUIRE(it2 < it1);
|
|
REQUIRE(it2 <= it2);
|
|
}
|
|
|
|
|
|
SECTION("Internal management") {
|
|
it_ref_t bars = foo.get_bar();
|
|
it_ref_ptr_t bars_ptr = foo.get_bar_ptr();
|
|
|
|
REQUIRE(bars.size() == foo.bar.size());
|
|
REQUIRE(bars_ptr.size() == foo.bar_ptr.size());
|
|
REQUIRE(*bars_ptr == "1");
|
|
REQUIRE(std::string(bars_ptr->c_str()) == "1");
|
|
REQUIRE(bars_ptr[2] == "3");
|
|
|
|
REQUIRE(std::string(bars->c_str()) == "1");
|
|
REQUIRE(std::string(bars_ptr->c_str()) == "1");
|
|
size_t count = std::count_if(
|
|
std::begin(bars),
|
|
std::end(bars),
|
|
[] (const std::string& s) {
|
|
return s == "6";
|
|
});
|
|
|
|
REQUIRE(count == 3);
|
|
|
|
it_ref_t bar_operator_equal{bars};
|
|
bar_operator_equal += 2;
|
|
bar_operator_equal.operator=(bars);
|
|
REQUIRE(bar_operator_equal == bars);
|
|
|
|
std::string& first_one_ptr = *bars_ptr;
|
|
first_one_ptr = "123456";
|
|
REQUIRE(foo.get_bar_ptr()[0] == "123456");
|
|
|
|
|
|
*foo.get_bar() = "123456";
|
|
CHECK(*foo.get_bar() == "123456");
|
|
auto&& dummies = foo.get_dummies();
|
|
Dummy& d = dummies[0];
|
|
d.s_ = "zigzag";
|
|
|
|
CHECK(foo.get_dummies()->s_ == "zigzag");
|
|
|
|
|
|
it_ref_local_t local = foo.get_bar_local();
|
|
CHECK(*local == "a");
|
|
CHECK(std::begin(local) == std::begin(local));
|
|
CHECK(std::end(local) == std::end(local));
|
|
|
|
}
|
|
}
|
|
|
|
|
|
TEST_CASE("Test filter ref iterators", "[lief][iterators][filter][ref]") {
|
|
Foo foo;
|
|
|
|
SECTION("Always true") {
|
|
it_filter_ref true_list = foo.filter_always_true();
|
|
CHECK(true_list.size() == 8);
|
|
}
|
|
|
|
SECTION("operator++") {
|
|
|
|
it_filter_ref bar_filtred = foo.get_bar_filter();
|
|
it_filter_ref_ptr bar_ptr_filtred = foo.get_bar_ptr_filter();
|
|
|
|
CHECK(std::begin(bar_filtred) == std::begin(bar_filtred));
|
|
|
|
CHECK(*bar_filtred == "1");
|
|
CHECK(*(++bar_filtred) == "6");
|
|
CHECK(*(bar_filtred++) == "6");
|
|
CHECK(*(++bar_filtred) == "6");
|
|
CHECK(*(bar_filtred++) == "6");
|
|
|
|
CHECK(bar_filtred == std::end(bar_filtred));
|
|
|
|
}
|
|
|
|
SECTION("size()") {
|
|
|
|
it_filter_ref bar_filtred = foo.get_bar_filter();
|
|
it_filter_ref bar_filtred_empty = foo.get_bar_filter_empty();
|
|
it_filter_ref_ptr bar_ptr_filtred = foo.get_bar_ptr_filter();
|
|
|
|
CHECK(bar_filtred.size() == 4);
|
|
CHECK(bar_filtred_empty.size() == 0);
|
|
CHECK(bar_ptr_filtred.size() == 2);
|
|
}
|
|
|
|
|
|
SECTION("operator[]") {
|
|
|
|
it_filter_ref bar_filtred = foo.get_bar_filter();
|
|
it_filter_ref_ptr bar_ptr_filtred = foo.get_bar_ptr_filter();
|
|
|
|
CHECK(bar_filtred[0] == "1");
|
|
}
|
|
|
|
|
|
SECTION("Internal management") {
|
|
it_filter_ref bar_filtred = foo.get_bar_filter();
|
|
it_filter_ref_ptr bar_ptr_filtred = foo.get_bar_ptr_filter();
|
|
|
|
bar_ptr_filtred[1] = "7";
|
|
bar_filtred[0] = "foo";
|
|
|
|
CHECK(foo.get_bar_filter()[0] == "foo");
|
|
CHECK(foo.get_bar_ptr_filter().size() == 1);
|
|
}
|
|
|
|
}
|
|
|
|
TEST_CASE("Test const filter ref iterators", "[lief][iterators][filter][const_ref]") {
|
|
const Foo foo;
|
|
|
|
SECTION("operator++") {
|
|
|
|
it_filter_const_ref bar_filtred = foo.get_bar_filter();
|
|
it_filter_const_ref_ptr bar_ptr_filtred = foo.get_bar_ptr_filter();
|
|
|
|
CHECK(std::begin(bar_filtred) == std::begin(bar_filtred));
|
|
|
|
CHECK(*bar_filtred == "1");
|
|
CHECK(*(++bar_filtred) == "6");
|
|
CHECK(*(bar_filtred++) == "6");
|
|
CHECK(*(++bar_filtred) == "6");
|
|
CHECK(*(bar_filtred++) == "6");
|
|
|
|
CHECK(bar_filtred == std::end(bar_filtred));
|
|
|
|
}
|
|
|
|
SECTION("size()") {
|
|
|
|
it_filter_const_ref bar_filtred = foo.get_bar_filter();
|
|
it_filter_const_ref_ptr bar_ptr_filtred = foo.get_bar_ptr_filter();
|
|
|
|
CHECK(bar_filtred.size() == 4);
|
|
CHECK(bar_ptr_filtred.size() == 2);
|
|
}
|
|
|
|
|
|
SECTION("operator[]") {
|
|
|
|
it_filter_const_ref bar_filtred = foo.get_bar_filter();
|
|
it_filter_const_ref_ptr bar_ptr_filtred = foo.get_bar_ptr_filter();
|
|
|
|
CHECK(bar_filtred[1] == "6");
|
|
CHECK(bar_filtred[0] == "1");
|
|
|
|
CHECK(bar_ptr_filtred[1] == "6");
|
|
CHECK(bar_ptr_filtred[0] == "6");
|
|
}
|
|
|
|
|
|
SECTION("local") {
|
|
it_filter_const_ref_local bar_ptr_filtred = foo.get_bar_const_filter_local();
|
|
CHECK(bar_ptr_filtred.size() == 3);
|
|
|
|
}
|
|
|
|
}
|