diff --git a/src/condition/lfi_detector.cpp b/src/condition/lfi_detector.cpp index f467472a..463904d5 100644 --- a/src/condition/lfi_detector.cpp +++ b/src/condition/lfi_detector.cpp @@ -101,7 +101,7 @@ lfi_result lfi_impl(std::string_view path, const ddwaf_object ¶ms, lfi_fn = &lfi_impl_windows; } - kv_iterator it(¶ms, {}, objects_excluded, limits); + kv_iterator it(params, {}, objects_excluded, limits); for (; it; ++it) { if (deadline.expired()) { throw ddwaf::timeout_exception(); diff --git a/src/condition/match_iterator.hpp b/src/condition/match_iterator.hpp index 5d99dc42..b44add9c 100644 --- a/src/condition/match_iterator.hpp +++ b/src/condition/match_iterator.hpp @@ -14,7 +14,7 @@ template class matc public: static constexpr std::size_t npos = std::string_view::npos; - explicit match_iterator(std::string_view resource, const ddwaf_object *obj, + explicit match_iterator(std::string_view resource, const ddwaf_object &obj, const exclusion::object_set_ref &exclude, const object_limits &limits = object_limits()) : resource_(resource), it_(obj, {}, exclude, limits) { diff --git a/src/condition/scalar_condition.cpp b/src/condition/scalar_condition.cpp index b9adbb99..b1550464 100644 --- a/src/condition/scalar_condition.cpp +++ b/src/condition/scalar_condition.cpp @@ -164,11 +164,11 @@ eval_result scalar_condition::eval(condition_cache &cache, const object_store &s std::optional match; // TODO: iterators could be cached to avoid reinitialisation if (target.source == data_source::keys) { - key_iterator it(object, target.key_path, objects_excluded, limits_); + key_iterator it(*object, target.key_path, objects_excluded, limits_); match = eval_target>( it, target.name, ephemeral, *matcher, target.transformers, limits_, deadline); } else { - value_iterator it(object, target.key_path, objects_excluded, limits_); + value_iterator it(*object, target.key_path, objects_excluded, limits_); match = eval_target>( it, target.name, ephemeral, *matcher, target.transformers, limits_, deadline); } @@ -212,11 +212,11 @@ eval_result scalar_negated_condition::eval(condition_cache &cache, const object_ bool match = false; if (target_.source == data_source::keys) { - key_iterator it(object, target_.key_path, objects_excluded, limits_); + key_iterator it(*object, target_.key_path, objects_excluded, limits_); match = eval_target( it, target_.name, ephemeral, *matcher, target_.transformers, limits_, deadline); } else { - value_iterator it(object, target_.key_path, objects_excluded, limits_); + value_iterator it(*object, target_.key_path, objects_excluded, limits_); match = eval_target( it, target_.name, ephemeral, *matcher, target_.transformers, limits_, deadline); } diff --git a/src/condition/shi_detector.cpp b/src/condition/shi_detector.cpp index 06a31c08..ccb4aeae 100644 --- a/src/condition/shi_detector.cpp +++ b/src/condition/shi_detector.cpp @@ -39,7 +39,7 @@ std::optional shi_string_impl(std::string_view resource, const exclusion::object_set_ref &objects_excluded, const object_limits &limits, ddwaf::timer &deadline) { - match_iterator it(resource, ¶ms, objects_excluded, limits); + match_iterator it(resource, params, objects_excluded, limits); for (; it; ++it) { if (deadline.expired()) { throw ddwaf::timeout_exception(); diff --git a/src/condition/sqli_detector.cpp b/src/condition/sqli_detector.cpp index e55d57d0..899af65c 100644 --- a/src/condition/sqli_detector.cpp +++ b/src/condition/sqli_detector.cpp @@ -467,7 +467,7 @@ sqli_result sqli_impl(std::string_view resource, std::vector &resourc { static constexpr std::size_t min_str_len = 3; - match_iterator it(resource, ¶ms, objects_excluded, limits); + match_iterator it(resource, params, objects_excluded, limits); for (; it; ++it) { if (deadline.expired()) { throw ddwaf::timeout_exception(); diff --git a/src/condition/ssrf_detector.cpp b/src/condition/ssrf_detector.cpp index 955fbce2..2494dc1c 100644 --- a/src/condition/ssrf_detector.cpp +++ b/src/condition/ssrf_detector.cpp @@ -167,7 +167,7 @@ ssrf_result ssrf_impl(const uri_decomposed &uri, const ddwaf_object ¶ms, std::optional parameter_injection; - match_iterator it{uri.raw, ¶ms, objects_excluded, limits}; + match_iterator it{uri.raw, params, objects_excluded, limits}; for (; it; ++it) { if (deadline.expired()) { throw ddwaf::timeout_exception(); diff --git a/src/iterator.cpp b/src/iterator.cpp index c9f02ad2..11411d49 100644 --- a/src/iterator.cpp +++ b/src/iterator.cpp @@ -126,7 +126,7 @@ void value_iterator::initialise_cursor_with_path( const std::string_view key = path[i]; auto &parent_it = stack_.back(); - std::pair child; + std::pair child; if (parent_it.container_type() == object_type::map) { for (; parent_it; ++parent_it) { auto possible_child = *parent_it; @@ -146,21 +146,25 @@ void value_iterator::initialise_cursor_with_path( } } + if (!child.second.has_value()) { + return; + } + // If we find a scalar and it's the last element, // we found a valid element within the path. - if (child.second.is_scalar() && (i + 1) == path.size()) { + if (child.second->is_scalar() && (i + 1) == path.size()) { current_ = child; // We want to keep the stack pointing to the container // in the last key of the key path, since the last element // of the key path is a scalar, we clear the stack. stack_.clear(); - } else if (child.second.is_container()) { + } else if (child.second->is_container()) { if ((i + 1) == limits_.max_container_depth) { break; } // Replace the stack top - stack_.back() = child.second.begin(limits_); + stack_.back() = child.second->begin(limits_); if ((i + 1) < path.size()) { continue; @@ -199,16 +203,16 @@ void value_iterator::set_cursor_to_next_object() continue; } - if (child.is_container()) { + if (child->is_container()) { if (depth() < limits_.max_container_depth) { ++parent_it; // Push can invalidate the current references to the parent // so we increment the index before a potential reallocation // and prevent any further use of the references. - stack_.emplace_back(child.begin(limits_)); + stack_.emplace_back(child->begin(limits_)); continue; } - } else if (child.is_scalar()) { + } else if (child->is_scalar()) { current_.first = parent_it.key(); current_.second = child; } @@ -258,7 +262,7 @@ void key_iterator::initialise_cursor_with_path( const std::string_view key = path[i]; auto &parent_it = stack_.back(); - std::pair child; + std::pair child; if (parent_it.container_type() == object_type::map) { for (; parent_it; ++parent_it) { auto possible_child = *parent_it; @@ -277,8 +281,12 @@ void key_iterator::initialise_cursor_with_path( } } - if (child.second.is_container()) { - stack_.back() = child.second.begin(limits_); + if (!child.second.has_value()) { + return; + } + + if (child.second->is_container()) { + stack_.back() = child.second->begin(limits_); if ((i + 1) < path.size()) { continue; @@ -317,7 +325,7 @@ void key_iterator::set_cursor_to_next_object() continue; } - if (child.second.is_container()) { + if (child.second->is_container()) { if (previous.second != child.second && !child.first.empty()) { current_ = child; // Break to ensure the index isn't increased and this container @@ -330,7 +338,7 @@ void key_iterator::set_cursor_to_next_object() // so we increment the index before a potential reallocation // and prevent any further use of the references. ++parent_it; - stack_.emplace_back(child.second.begin(limits_)); + stack_.emplace_back(child.second->begin(limits_)); continue; } } else if (!child.first.empty()) { @@ -390,7 +398,7 @@ void kv_iterator::initialise_cursor_with_path( const std::string_view key = path[i]; auto &parent_it = stack_.back(); - std::pair child; + std::pair child; if (parent_it.container_type() == object_type::map) { for (; parent_it; ++parent_it) { auto possible_child = *parent_it; @@ -409,22 +417,26 @@ void kv_iterator::initialise_cursor_with_path( } } + if (!child.second.has_value()) { + return; + } + // If we find a scalar and it's the last element, // we found a valid element within the path. - if (child.second.is_scalar() && (i + 1) == path.size()) { + if (child.second->is_scalar() && (i + 1) == path.size()) { current_ = child; scalar_value_ = true; // We want to keep the stack pointing to the container // in the last key of the key path, since the last element // of the key path is a scalar, we clear the stack. stack_.clear(); - } else if (child.second.is_container()) { + } else if (child.second->is_container()) { if ((i + 1) == limits_.max_container_depth) { break; } // Replace the stack top - stack_.back() = child.second.begin(limits_); + stack_.back() = child.second->begin(limits_); if ((i + 1) < path.size()) { continue; @@ -464,7 +476,7 @@ void kv_iterator::set_cursor_to_next_object() continue; } - if (child.second.is_container()) { + if (child.second->is_container()) { if (previous.second != child.second && !child.first.empty()) { current_ = child; scalar_value_ = false; @@ -478,10 +490,10 @@ void kv_iterator::set_cursor_to_next_object() // so we increment the index before a potential reallocation // and prevent any further use of the references. ++parent_it; - stack_.emplace_back(child.second.begin(limits_)); + stack_.emplace_back(child.second->begin(limits_)); continue; } - } else if (child.second.is_scalar()) { + } else if (child.second->is_scalar()) { if (previous.second != child.second) { current_ = child; if (current_.first.empty()) { diff --git a/src/iterator.hpp b/src/iterator.hpp index 73d1c964..280ae9f3 100644 --- a/src/iterator.hpp +++ b/src/iterator.hpp @@ -38,7 +38,7 @@ template class iterator_base { [[nodiscard]] explicit operator bool() const { return current_.second.has_value(); } [[nodiscard]] size_t depth() { return stack_.size() + path_.size(); } [[nodiscard]] std::vector get_current_path() const; - [[nodiscard]] object_view get_underlying_object() { return current_.second; } + [[nodiscard]] optional_object_view get_underlying_object() { return current_.second; } protected: static constexpr std::size_t initial_stack_size = 32; @@ -51,7 +51,7 @@ template class iterator_base { std::vector path_; std::vector stack_; - std::pair current_; + std::pair current_; const exclusion::object_set_ref &excluded_; }; @@ -69,9 +69,9 @@ class value_iterator : public iterator_base { value_iterator &operator=(const value_iterator &) = delete; value_iterator &operator=(value_iterator &&) = delete; - [[nodiscard]] object_view operator*() { return current_.second; } + [[nodiscard]] optional_object_view operator*() { return current_.second; } - [[nodiscard]] object_type type() const { return current_.second.type(); } + [[nodiscard]] object_type type() const { return current_.second->type(); } protected: void initialise_cursor(object_view obj, const std::span &path); @@ -100,7 +100,7 @@ class key_iterator : public iterator_base { return !current_.first.empty() ? object_type::string : object_type::invalid; } - [[nodiscard]] object_view operator*() + [[nodiscard]] optional_object_view operator*() { if (current_.first.empty()) { return {}; @@ -136,7 +136,7 @@ class kv_iterator : public iterator_base { { if (current_.second.has_value()) { if (scalar_value_) { - return current_.second.type_unchecked(); + return current_.second->type(); } if (!current_.first.empty()) { @@ -146,7 +146,7 @@ class kv_iterator : public iterator_base { return object_type::invalid; } - [[nodiscard]] object_view operator*() + [[nodiscard]] optional_object_view operator*() { if (current_.second.has_value()) { if (scalar_value_) { diff --git a/src/object_view.hpp b/src/object_view.hpp index f46aaacc..53c31b67 100644 --- a/src/object_view.hpp +++ b/src/object_view.hpp @@ -24,23 +24,70 @@ using object = ddwaf_object; template struct converter; -class object_view { +class object_view; + +class optional_object_view { public: // The default constructor results in a view without value - object_view() = default; + optional_object_view() = default; + // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) + optional_object_view(object_view view); + // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) + optional_object_view(const detail::object *underlying_object) : obj_(underlying_object) {} + + ~optional_object_view() = default; + optional_object_view(const optional_object_view &) = default; + optional_object_view(optional_object_view &&) = default; + optional_object_view &operator=(const optional_object_view &) = default; + optional_object_view &operator=(optional_object_view &&) = default; + + [[nodiscard]] const detail::object &ref() const noexcept { return *obj_; } + [[nodiscard]] const detail::object *ptr() const noexcept { return obj_; } + + template bool operator==(const T &other) const + { + if constexpr (std::is_same_v) { + return ptr() == nullptr; + } else if constexpr (std::is_same_v) { + return ptr() == other; + } else { + return ptr() == other.ptr(); + } + } + template bool operator!=(const T &other) const + { + if constexpr (std::is_same_v) { + return ptr() != nullptr; + } else if constexpr (std::is_same_v) { + return ptr() != other; + } else { + return ptr() != other.ptr(); + } + } + + [[nodiscard]] bool has_value() const noexcept { return obj_ != nullptr; } + + // This method should only be called if the presence of a value has been + // checked by using has_value(); + [[nodiscard]] object_view operator->() const noexcept; + +protected: + const detail::object *obj_{nullptr}; +}; +class object_view { +public: // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) - object_view(const detail::object *underlying_object) : obj_(underlying_object) {} + object_view(const detail::object &underlying_object) : obj_(underlying_object) {} ~object_view() = default; object_view(const object_view &) = default; object_view(object_view &&) = default; - object_view &operator=(const object_view &) = default; - object_view &operator=(object_view &&) = default; + object_view &operator=(const object_view &) = delete; + object_view &operator=(object_view &&) = delete; - [[nodiscard]] const detail::object *ptr() const { return obj_; } - bool operator==(const object_view other) const { return ptr() == other.ptr(); } - bool operator!=(const object_view other) const { return ptr() != other.ptr(); } + [[nodiscard]] const detail::object *ptr() const noexcept { return &obj_; } + [[nodiscard]] const detail::object &ref() const noexcept { return obj_; } // The unchecked API assumes that the caller has already verified that the // method preconditions are met: @@ -51,31 +98,43 @@ class object_view { // The checked API (without suffix), always validates preconditions so it is // safer but introduces small overheads. - [[nodiscard]] bool has_value() const noexcept { return obj_ != nullptr; } - - [[nodiscard]] object_type type_unchecked() const noexcept + template bool operator==(const T &other) const { - return static_cast(obj_->type); + if constexpr (std::is_same_v) { + return false; + } else if constexpr (std::is_same_v) { + return ptr() == other; + } else { + return ptr() == other.ptr(); + } } - - [[nodiscard]] object_type type() const noexcept + template bool operator!=(const T &other) const { - return obj_ != nullptr ? type_unchecked() : object_type::invalid; + if constexpr (std::is_same_v) { + return true; + } else if constexpr (std::is_same_v) { + return ptr() != other; + } else { + return ptr() != other.ptr(); + } } - // Size and empty methods apply to both containers and strings - [[nodiscard]] std::size_t size_unchecked() const noexcept - { - return static_cast(obj_->nbEntries); - } + [[nodiscard]] object_type type() const noexcept { return static_cast(obj_.type); } + [[nodiscard]] std::size_t size() const noexcept { - return obj_ != nullptr ? size_unchecked() : 0; + return static_cast(obj_.nbEntries); } - [[nodiscard]] bool empty_unchecked() const noexcept { return obj_->nbEntries == 0; } + [[nodiscard]] bool empty() const noexcept { return obj_.nbEntries == 0; } - [[nodiscard]] bool empty() const noexcept { return obj_ != nullptr ? empty_unchecked() : true; } + // These is_* methods provide further checks for consistency, albeit these + // perhaps should be replaced by assertions. + [[nodiscard]] bool is_container() const noexcept + { + return (type() & container_object_type) != 0; + } + [[nodiscard]] bool is_scalar() const noexcept { return (type() & scalar_object_type) != 0; } // is check whether the underlying type is compatible with the required // type. When it comes to numeric types, the request type must match the @@ -83,34 +142,24 @@ class object_view { // a smaller size. template [[nodiscard]] bool is() const noexcept { - return obj_ != nullptr && is_compatible_type(type_unchecked()); - } - - // These is_* methods provide further checks for consistency, albeit these - // perhaps should be replaced by assertions. - [[nodiscard]] bool is_container() const noexcept - { - return obj_ != nullptr && (type_unchecked() & container_object_type) != 0; - } - [[nodiscard]] bool is_scalar() const noexcept - { - return obj_ != nullptr && (type_unchecked() & scalar_object_type) != 0; + return is_compatible_type(type()); } // Access the key and value at index. If the container is an array, the key // will be an empty string. - [[nodiscard]] std::pair at_unchecked( + [[nodiscard]] std::pair at_unchecked( std::size_t index) const noexcept { - auto &slot = obj_->array[index]; + const auto &slot = obj_.array[index]; std::string_view key{ slot.parameterName, static_cast(slot.parameterNameLength)}; - return {key, object_view{&slot}}; + return {key, optional_object_view{&slot}}; } - [[nodiscard]] std::pair at(std::size_t index) const noexcept + [[nodiscard]] std::pair at( + std::size_t index) const noexcept { - if (!is_container() || index > static_cast(obj_->nbEntries)) { + if (!is_container() || index > size()) { [[unlikely]] return {}; } return at_unchecked(index); @@ -128,42 +177,42 @@ class object_view { [[nodiscard]] T as_unchecked() const noexcept requires std::is_same_v { - return obj_->boolean; + return obj_.boolean; } template [[nodiscard]] T as_unchecked() const noexcept requires std::is_same_v { - return static_cast(obj_->intValue); + return static_cast(obj_.intValue); } template [[nodiscard]] T as_unchecked() const noexcept requires std::is_same_v { - return static_cast(obj_->uintValue); + return static_cast(obj_.uintValue); } template [[nodiscard]] T as_unchecked() const noexcept requires std::is_same_v { - return static_cast(obj_->f64); + return static_cast(obj_.f64); } template [[nodiscard]] T as_unchecked() const noexcept requires std::is_same_v || std::is_same_v { - return {obj_->stringValue, size()}; + return {obj_.stringValue, size()}; } template [[nodiscard]] T as_unchecked() const noexcept requires std::is_same_v { - return obj_->stringValue; + return obj_.stringValue; } // Access the underlying value based on the required type, these methods @@ -217,7 +266,7 @@ class object_view { return key; } - [[nodiscard]] object_view value() const + [[nodiscard]] optional_object_view value() const { if (index_ >= size_) { [[unlikely]] return {}; @@ -226,7 +275,7 @@ class object_view { return &obj_->array[index_]; } - std::pair operator*() const + std::pair operator*() const { if (index_ >= size_) { [[unlikely]] return {}; @@ -284,7 +333,7 @@ class object_view { if (!is_container()) { [[unlikely]] return {}; } - return iterator{obj_, limits}; + return iterator{&obj_, limits}; } iterator end() @@ -293,286 +342,23 @@ class object_view { if (!is_container()) { [[unlikely]] return {}; } - return iterator{obj_, {}, static_cast(obj_->nbEntries)}; - } - - // Container abstractions, for convenience - - // Array abstraction, allows access only to values, but not keys - class array { - public: - array() = default; - ~array() = default; - array(const array &) = default; - array(array &&) = default; - array &operator=(const array &) = default; - array &operator=(array &&) = default; - - [[nodiscard]] bool has_value() const noexcept { return obj_ != nullptr; } - - // Size and empty methods apply to both containers and strings - [[nodiscard]] std::size_t size_unchecked() const noexcept - { - return static_cast(obj_->nbEntries); - } - [[nodiscard]] std::size_t size() const noexcept - { - return obj_ != nullptr ? size_unchecked() : 0; - } - - [[nodiscard]] bool empty_unchecked() const noexcept { return obj_->nbEntries == 0; } - - [[nodiscard]] bool empty() const noexcept - { - return obj_ != nullptr ? empty_unchecked() : true; - } - - [[nodiscard]] const detail::object *ptr() const noexcept { return obj_; } - - // Access the key and value at index. If the container is an array, the key - // will be an empty string. - [[nodiscard]] object_view at_unchecked(std::size_t index) const noexcept - { - return &obj_->array[index]; - } - - [[nodiscard]] object_view at(std::size_t index) const noexcept - { - if (obj_ != nullptr || index > size_unchecked()) { - [[unlikely]] return {}; - } - return at_unchecked(index); - } - - class iterator { - public: - bool operator!=(const iterator &rhs) const noexcept { return current_ != rhs.current_; } - - object_view operator*() const noexcept { return current_ != end_ ? current_ : nullptr; } - - iterator &operator++() noexcept - { - if (current_ != end_) { - [[likely]] current_++; - } - return *this; - } - - protected: - iterator() = default; - explicit iterator(array &ov, size_t index = 0) - : current_(ov.obj_->array), end_(ov.obj_->array + ov.size()) - { - if (index >= ov.size()) { - current_ = end_; - } else { - current_ += index; - } - } - - detail::object *current_{nullptr}; - detail::object *end_{nullptr}; - - friend class array; - }; - - iterator begin() { return obj_ != nullptr ? iterator{*this} : iterator{}; } - iterator end() - { - return obj_ != nullptr ? iterator{*this, static_cast(obj_->nbEntries)} - : iterator{}; - } - - protected: - // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) - explicit array(const detail::object *underlying_object) : obj_(underlying_object) {} - - const detail::object *obj_{nullptr}; - - friend class object_view; - }; - - template - [[nodiscard]] std::optional as() const noexcept - requires std::is_same_v - { - if (type() != object_type::array) { - [[unlikely]] return std::nullopt; - } - return as_unchecked(); - } - - template - [[nodiscard]] T as_unchecked() const noexcept - requires std::is_same_v - { - return T{obj_}; - } - - class map { - public: - map() = default; - ~map() = default; - map(const map &) = default; - map(map &&) = default; - map &operator=(const map &) = default; - map &operator=(map &&) = default; - - // Size and empty methods apply to both containers and strings - [[nodiscard]] std::size_t size_unchecked() const noexcept - { - return static_cast(obj_->nbEntries); - } - [[nodiscard]] std::size_t size() const noexcept - { - return obj_ != nullptr ? size_unchecked() : 0; - } - - [[nodiscard]] bool empty_unchecked() const noexcept { return obj_->nbEntries == 0; } - - [[nodiscard]] bool empty() const noexcept - { - return obj_ != nullptr ? empty_unchecked() : true; - } - - [[nodiscard]] const detail::object *ptr() const noexcept { return obj_; } - - [[nodiscard]] object_view at(std::string_view key) const - { - if (obj_ == nullptr) { - [[unlikely]] return {}; - } - - for (std::size_t i = 0; i < size(); ++i) { - auto &slot = obj_->array[i]; - std::string_view current_key{ - slot.parameterName, static_cast(slot.parameterNameLength)}; - if (current_key == key) { - return {&slot}; - } - } - return {}; - } - - template - std::optional> at(std::size_t index) - requires std::is_same_v || - std::is_same_v || - std::is_same_v - { - if (obj_ == nullptr || index > size_unchecked()) { - [[unlikely]] return std::nullopt; - } - return at_unchecked(index); - } - - template - std::pair at_unchecked(std::size_t index) - requires std::is_same_v || - std::is_same_v || - std::is_same_v - { - auto &slot = obj_->array[index]; - std::string_view key{ - slot.parameterName, static_cast(slot.parameterNameLength)}; - return {key, object_view{&slot}}; - } - - class iterator { - public: - bool operator!=(const iterator &rhs) const noexcept { return current_ != rhs.current_; } - - [[nodiscard]] std::string_view key() const noexcept - { - if (current_ == end_) { - [[unlikely]] return {}; - } - return {current_->parameterName, - static_cast(current_->parameterNameLength)}; - } - - std::pair operator*() const noexcept - { - if (current_ == end_) { - [[unlikely]] return {{}, nullptr}; - } - return {key(), value()}; - } - - [[nodiscard]] object_view value() const noexcept - { - if (current_ == end_) { - [[unlikely]] return nullptr; - } - return {current_}; - } - - iterator &operator++() noexcept - { - if (current_ != end_) { - [[likely]] current_++; - } - return *this; - } - - protected: - iterator() = default; - explicit iterator(map &ov, size_t index = 0) - : current_(ov.obj_->array), end_(ov.obj_->array + ov.size()) - { - if (index >= ov.size()) { - current_ = end_; - } else { - current_ += index; - } - } - - detail::object *current_{nullptr}; - detail::object *end_{nullptr}; - - friend class map; - }; - - iterator begin() { return obj_ != nullptr ? iterator{*this} : iterator{}; } - - iterator end() - { - return obj_ != nullptr ? iterator{*this, static_cast(obj_->nbEntries)} - : iterator{}; - } - - protected: - // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) - explicit map(const detail::object *underlying_object) : obj_(underlying_object) {} - - const detail::object *obj_{nullptr}; - - friend class object_view; - }; - - template - [[nodiscard]] std::optional as() const noexcept - requires std::is_same_v - { - if (type() != object_type::map) { - [[unlikely]] return std::nullopt; - } - return as_unchecked(); + return iterator{&obj_, {}, static_cast(obj_.nbEntries)}; } - template - [[nodiscard]] T as_unchecked() const noexcept - requires std::is_same_v - { - return T{obj_}; - } + [[nodiscard]] const object_view *operator->() const noexcept { return this; } + [[nodiscard]] object_view *operator->() noexcept { return this; } protected: - const detail::object *obj_{nullptr}; + // NOLINTNEXTLINE(cppcoreguidelines-avoid-const-or-ref-data-members) + const detail::object &obj_; }; static_assert(sizeof(object_view) == sizeof(void *)); +inline optional_object_view::optional_object_view(object_view view) : obj_(view.ptr()) {} + +inline class object_view optional_object_view::operator->() const noexcept { return *obj_; } + } // namespace ddwaf namespace std { diff --git a/tests/condition/match_iterator_test.cpp b/tests/condition/match_iterator_test.cpp index d2d402eb..60d4ddde 100644 --- a/tests/condition/match_iterator_test.cpp +++ b/tests/condition/match_iterator_test.cpp @@ -18,7 +18,7 @@ TEST(TestMatchIterator, InvalidIterator) std::string resource = "this is the resource"; exclusion::object_set_ref exclude; - ddwaf::match_iterator it(resource, &object, exclude); + ddwaf::match_iterator it(resource, object, exclude); EXPECT_FALSE((bool)it); auto path = it.get_current_path(); @@ -34,7 +34,7 @@ TEST(TestMatchIterator, NoMatch) std::string resource = "this is the resource"; exclusion::object_set_ref exclude; - ddwaf::match_iterator it(resource, &object, exclude); + ddwaf::match_iterator it(resource, object, exclude); EXPECT_FALSE((bool)it); auto path = it.get_current_path(); @@ -52,7 +52,7 @@ TEST(TestMatchIterator, SingleMatch) std::string resource = "this is the resource"; exclusion::object_set_ref exclude; - ddwaf::match_iterator it(resource, &object, exclude); + ddwaf::match_iterator it(resource, object, exclude); EXPECT_TRUE((bool)it); auto [param, index] = *it; @@ -74,7 +74,7 @@ TEST(TestMatchIterator, MultipleMatches) std::string resource = "resource resource resource resource"; exclusion::object_set_ref exclude; - ddwaf::match_iterator it(resource, &object, exclude); + ddwaf::match_iterator it(resource, object, exclude); for (std::size_t i = 0; i < 4; ++i) { EXPECT_TRUE((bool)it); @@ -100,7 +100,7 @@ TEST(TestMatchIterator, OverlappingMatches) std::string resource = "eeeeeeeeee"; exclusion::object_set_ref exclude; - ddwaf::match_iterator it(resource, &object, exclude); + ddwaf::match_iterator it(resource, object, exclude); EXPECT_TRUE((bool)it); for (std::size_t i = 0; i < 9; ++i) { diff --git a/tests/key_iterator_test.cpp b/tests/key_iterator_test.cpp index 49750bc4..caf5f7a9 100644 --- a/tests/key_iterator_test.cpp +++ b/tests/key_iterator_test.cpp @@ -18,7 +18,7 @@ TEST(TestKeyIterator, TestInvalidIterator) ddwaf_object_invalid(&object); exclusion::object_set_ref exclude; - ddwaf::key_iterator it(&object, {}, exclude); + ddwaf::key_iterator it(object, {}, exclude); EXPECT_FALSE((bool)it); auto path = it.get_current_path(); @@ -33,7 +33,7 @@ TEST(TestKeyIterator, TestStringScalar) ddwaf_object_string(&object, "value"); exclusion::object_set_ref exclude; - ddwaf::key_iterator it(&object, {}, exclude); + ddwaf::key_iterator it(object, {}, exclude); EXPECT_FALSE((bool)it); auto path = it.get_current_path(); @@ -50,7 +50,7 @@ TEST(TestKeyIterator, TestUnsignedScalar) ddwaf_object_unsigned(&object, 22); exclusion::object_set_ref exclude; - ddwaf::key_iterator it(&object, {}, exclude); + ddwaf::key_iterator it(object, {}, exclude); EXPECT_FALSE((bool)it); auto path = it.get_current_path(); @@ -65,7 +65,7 @@ TEST(TestKeyIterator, TestSignedScalar) ddwaf_object_signed(&object, 22); exclusion::object_set_ref exclude; - ddwaf::key_iterator it(&object, {}, exclude); + ddwaf::key_iterator it(object, {}, exclude); EXPECT_FALSE((bool)it); auto path = it.get_current_path(); @@ -81,7 +81,7 @@ TEST(TestKeyIterator, TestArraySingleItem) ddwaf_object_array_add(&object, ddwaf_object_string(&tmp, "string")); exclusion::object_set_ref exclude; - ddwaf::key_iterator it(&object, {}, exclude); + ddwaf::key_iterator it(object, {}, exclude); EXPECT_FALSE((bool)it); EXPECT_FALSE(++it); @@ -100,7 +100,7 @@ TEST(TestKeyIterator, TestArrayMultipleItems) } exclusion::object_set_ref exclude; - ddwaf::key_iterator it(&object, {}, exclude); + ddwaf::key_iterator it(object, {}, exclude); EXPECT_FALSE((bool)it); EXPECT_FALSE(++it); @@ -121,7 +121,7 @@ TEST(TestKeyIterator, TestArrayPastSizeLimit) } exclusion::object_set_ref exclude; - ddwaf::key_iterator it(&object, {}, exclude); + ddwaf::key_iterator it(object, {}, exclude); EXPECT_FALSE((bool)it); EXPECT_FALSE(++it); @@ -151,7 +151,7 @@ TEST(TestKeyIterator, TestDeepArray) } exclusion::object_set_ref exclude; - ddwaf::key_iterator it(&object, {}, exclude); + ddwaf::key_iterator it(object, {}, exclude); EXPECT_FALSE((bool)it); EXPECT_FALSE(++it); @@ -182,7 +182,7 @@ TEST(TestKeyIterator, TestDeepArrayPastLimit) } exclusion::object_set_ref exclude; - ddwaf::key_iterator it(&object, {}, exclude); + ddwaf::key_iterator it(object, {}, exclude); EXPECT_FALSE((bool)it); EXPECT_FALSE(++it); @@ -199,7 +199,7 @@ TEST(TestKeyIterator, TestArrayNoScalars) for (unsigned i = 0; i < 50; i++) { ddwaf_object_array_add(&object, ddwaf_object_array(&tmp)); } exclusion::object_set_ref exclude; - ddwaf::key_iterator it(&object, {}, exclude); + ddwaf::key_iterator it(object, {}, exclude); EXPECT_FALSE((bool)it); EXPECT_FALSE(++it); @@ -214,10 +214,10 @@ TEST(TestKeyIterator, TestMapSingleItem) ddwaf_object_map_add(&object, "key", ddwaf_object_string(&tmp, "value")); exclusion::object_set_ref exclude; - ddwaf::key_iterator it(&object, {}, exclude); + ddwaf::key_iterator it(object, {}, exclude); EXPECT_TRUE((bool)it); EXPECT_EQ((*it).ptr()->parameterName, nullptr); - EXPECT_STREQ((*it).as_unchecked(), "key"); + EXPECT_STREQ((*it)->as_unchecked(), "key"); auto path = it.get_current_path(); EXPECT_EQ(path.size(), 1); @@ -241,14 +241,14 @@ TEST(TestKeyIterator, TestMapMultipleItems) } exclusion::object_set_ref exclude; - ddwaf::key_iterator it(&object, {}, exclude); + ddwaf::key_iterator it(object, {}, exclude); for (unsigned i = 0; i < 50; i++) { auto index = std::to_string(i); std::string key = "key" + index; EXPECT_TRUE((bool)it); - EXPECT_STREQ((*it).as_unchecked(), key.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), key.c_str()); auto path = it.get_current_path(); EXPECT_EQ(path.size(), 1); @@ -288,7 +288,7 @@ TEST(TestKeyIterator, TestMapMultipleNullAndInvalid) } exclusion::object_set_ref exclude; - ddwaf::key_iterator it(&object, {}, exclude); + ddwaf::key_iterator it(object, {}, exclude); for (unsigned i = 0; i < 25; i++) { { @@ -296,7 +296,7 @@ TEST(TestKeyIterator, TestMapMultipleNullAndInvalid) std::string key = "key" + index; EXPECT_TRUE((bool)it); - EXPECT_STREQ((*it).as_unchecked(), key.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), key.c_str()); auto path = it.get_current_path(); EXPECT_EQ(path.size(), 1); @@ -350,7 +350,7 @@ TEST(TestKeyIterator, TestMapPastSizeLimit) } exclusion::object_set_ref exclude; - ddwaf::key_iterator it(&object, {}, exclude); + ddwaf::key_iterator it(object, {}, exclude); for (unsigned i = 0; i < limits.max_container_size; i++) { auto index = std::to_string(i); @@ -358,7 +358,7 @@ TEST(TestKeyIterator, TestMapPastSizeLimit) std::string value = "value" + index; EXPECT_TRUE((bool)it); - EXPECT_STREQ((*it).as_unchecked(), key.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), key.c_str()); auto path = it.get_current_path(); EXPECT_EQ(path.size(), 1); @@ -392,13 +392,13 @@ TEST(TestKeyIterator, TestDeepMap) } exclusion::object_set_ref exclude; - ddwaf::key_iterator it(&object, {}, exclude); + ddwaf::key_iterator it(object, {}, exclude); for (unsigned i = 0; i < 10; i++) { auto index = std::to_string(i); EXPECT_EQ((*it).ptr()->parameterName, nullptr); - EXPECT_STREQ((*it).as_unchecked(), ("str" + index).c_str()); + EXPECT_STREQ((*it)->as_unchecked(), ("str" + index).c_str()); { auto path = it.get_current_path(); @@ -412,7 +412,7 @@ TEST(TestKeyIterator, TestDeepMap) EXPECT_TRUE(++it); EXPECT_EQ((*it).ptr()->parameterName, nullptr); - EXPECT_STREQ((*it).as_unchecked(), ("map" + index).c_str()); + EXPECT_STREQ((*it)->as_unchecked(), ("map" + index).c_str()); { auto path = it.get_current_path(); @@ -453,13 +453,13 @@ TEST(TestKeyIterator, TestMapPastDepthLimit) } exclusion::object_set_ref exclude; - ddwaf::key_iterator it(&object, {}, exclude); + ddwaf::key_iterator it(object, {}, exclude); for (unsigned i = 0; i < limits.max_container_depth; i++) { auto index = std::to_string(i); EXPECT_EQ((*it).ptr()->parameterName, nullptr); - EXPECT_STREQ((*it).as_unchecked(), ("str" + index).c_str()); + EXPECT_STREQ((*it)->as_unchecked(), ("str" + index).c_str()); { auto path = it.get_current_path(); @@ -473,7 +473,7 @@ TEST(TestKeyIterator, TestMapPastDepthLimit) EXPECT_TRUE(++it); EXPECT_EQ((*it).ptr()->parameterName, nullptr); - EXPECT_STREQ((*it).as_unchecked(), ("map" + index).c_str()); + EXPECT_STREQ((*it)->as_unchecked(), ("map" + index).c_str()); { auto path = it.get_current_path(); @@ -505,10 +505,10 @@ TEST(TestKeyIterator, TestNoRootKey) ddwaf_object_map_add(&root, "root", &object); exclusion::object_set_ref exclude; - ddwaf::key_iterator it(&root.array[0], {}, exclude); + ddwaf::key_iterator it(root.array[0], {}, exclude); EXPECT_TRUE((bool)it); EXPECT_EQ((*it).ptr()->parameterName, nullptr); - EXPECT_STREQ((*it).as_unchecked(), "key"); + EXPECT_STREQ((*it)->as_unchecked(), "key"); auto path = it.get_current_path(); EXPECT_EQ(path.size(), 1); @@ -539,7 +539,7 @@ TEST(TestKeyIterator, TestContainerMix) { exclusion::object_set_ref exclude; - ddwaf::key_iterator it(&object, {}, exclude); + ddwaf::key_iterator it(object, {}, exclude); std::vector>> values = { {"root", {"root"}}, @@ -553,7 +553,7 @@ TEST(TestKeyIterator, TestContainerMix) }; for (auto &[value, path] : values) { - EXPECT_STREQ((*it).as_unchecked(), value.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), value.c_str()); auto it_path = it.get_current_path(); EXPECT_EQ(path, it_path); @@ -575,11 +575,11 @@ TEST(TestKeyIterator, TestMapNoScalars) } exclusion::object_set_ref exclude; - ddwaf::key_iterator it(&object, {}, exclude); + ddwaf::key_iterator it(object, {}, exclude); for (unsigned i = 0; i < 50; i++) { EXPECT_TRUE((bool)it); - EXPECT_STREQ((*it).as_unchecked(), "key"); + EXPECT_STREQ((*it)->as_unchecked(), "key"); auto path = it.get_current_path(); EXPECT_EQ(path.size(), 1); @@ -599,7 +599,7 @@ TEST(TestKeyIterator, TestInvalidObjectPath) exclusion::object_set_ref exclude; std::vector key_path{"key", "0", "value"}; - ddwaf::key_iterator it(&object, key_path, exclude); + ddwaf::key_iterator it(object, key_path, exclude); EXPECT_FALSE((bool)it); auto path = it.get_current_path(); @@ -619,14 +619,14 @@ TEST(TestKeyIterator, TestSimplePath) { std::vector key_path{"key"}; - ddwaf::key_iterator it(&object, key_path, {}); + ddwaf::key_iterator it(object, key_path, {}); EXPECT_FALSE((bool)it); EXPECT_FALSE(++it); } { std::vector key_path{"key", "0"}; - ddwaf::key_iterator it(&object, key_path, {}); + ddwaf::key_iterator it(object, key_path, {}); EXPECT_FALSE((bool)it); auto path = it.get_current_path(); @@ -637,7 +637,7 @@ TEST(TestKeyIterator, TestSimplePath) { std::vector key_path{"key", "0", "value"}; - ddwaf::key_iterator it(&object, key_path, {}); + ddwaf::key_iterator it(object, key_path, {}); EXPECT_FALSE((bool)it); auto path = it.get_current_path(); @@ -674,10 +674,10 @@ TEST(TestKeyIterator, TestMultiPath) }; std::vector key_path{"first"}; - ddwaf::key_iterator it(&object, key_path, exclude); + ddwaf::key_iterator it(object, key_path, exclude); for (auto &[value, path] : values) { - EXPECT_STREQ((*it).as_unchecked(), value.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), value.c_str()); auto it_path = it.get_current_path(); EXPECT_EQ(path, it_path); @@ -694,10 +694,10 @@ TEST(TestKeyIterator, TestMultiPath) }; std::vector key_path{"first", "second"}; - ddwaf::key_iterator it(&object, key_path, exclude); + ddwaf::key_iterator it(object, key_path, exclude); for (auto &[value, path] : values) { - EXPECT_STREQ((*it).as_unchecked(), value.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), value.c_str()); auto it_path = it.get_current_path(); EXPECT_EQ(path, it_path); @@ -709,7 +709,7 @@ TEST(TestKeyIterator, TestMultiPath) { std::vector key_path{"first", "second", "third"}; - ddwaf::key_iterator it(&object, key_path, exclude); + ddwaf::key_iterator it(object, key_path, exclude); EXPECT_FALSE((bool)it); } @@ -737,9 +737,9 @@ TEST(TestKeyIterator, TestContainerMixPath) exclusion::object_set_ref exclude; { std::vector key_path{"root", "key0"}; - ddwaf::key_iterator it(&object, key_path, exclude); + ddwaf::key_iterator it(object, key_path, exclude); EXPECT_TRUE((bool)it); - EXPECT_STREQ((*it).as_unchecked(), "key0_0"); + EXPECT_STREQ((*it)->as_unchecked(), "key0_0"); auto it_path = it.get_current_path(); std::vector path = {"root", "key0", "2", "key0_0"}; @@ -751,7 +751,7 @@ TEST(TestKeyIterator, TestContainerMixPath) { std::vector key_path{"root", "key1"}; - ddwaf::key_iterator it(&object, key_path, exclude); + ddwaf::key_iterator it(object, key_path, exclude); EXPECT_FALSE((bool)it); EXPECT_FALSE(++it); } @@ -764,10 +764,10 @@ TEST(TestKeyIterator, TestContainerMixPath) }; std::vector key_path{"root", "key2"}; - ddwaf::key_iterator it(&object, key_path, exclude); + ddwaf::key_iterator it(object, key_path, exclude); for (auto &[value, path] : values) { - EXPECT_STREQ((*it).as_unchecked(), value.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), value.c_str()); auto it_path = it.get_current_path(); EXPECT_EQ(path, it_path); @@ -801,19 +801,19 @@ TEST(TestKeyIterator, TestContainerMixInvalidPath) exclusion::object_set_ref exclude; { std::vector key_path{"rat"}; - ddwaf::key_iterator it(&object, key_path, exclude); + ddwaf::key_iterator it(object, key_path, exclude); EXPECT_FALSE((bool)it); } { std::vector key_path{"root", "cat"}; - ddwaf::key_iterator it(&object, key_path, exclude); + ddwaf::key_iterator it(object, key_path, exclude); EXPECT_FALSE((bool)it); } { std::vector key_path{"root", "key2", "key2_2", "0", "1", "2", "3"}; - ddwaf::key_iterator it(&object, key_path, exclude); + ddwaf::key_iterator it(object, key_path, exclude); EXPECT_FALSE((bool)it); } @@ -843,7 +843,7 @@ TEST(TestKeyIterator, TestMapDepthLimitPath) { limits.max_container_depth = 3; std::vector key_path{"root", "child", "grandchild"}; - ddwaf::key_iterator it(&object, key_path, exclude, limits); + ddwaf::key_iterator it(object, key_path, exclude, limits); EXPECT_FALSE(it); } @@ -851,7 +851,7 @@ TEST(TestKeyIterator, TestMapDepthLimitPath) { limits.max_container_depth = 4; std::vector key_path{"root", "child", "grandchild"}; - ddwaf::key_iterator it(&object, key_path, exclude, limits); + ddwaf::key_iterator it(object, key_path, exclude, limits); EXPECT_TRUE(it); { @@ -880,7 +880,7 @@ TEST(TestKeyIterator, TestMapDepthLimitPath) /*exclusion::object_set_ref exclude;*/ /*root.nbEntries = 30;*/ /*{*/ -/*ddwaf::key_iterator it(&root, {}, exclude);*/ +/*ddwaf::key_iterator it(root, {}, exclude);*/ /*EXPECT_FALSE(it);*/ /*}*/ @@ -889,7 +889,7 @@ TEST(TestKeyIterator, TestMapDepthLimitPath) /*root.nbEntries = 0;*/ /*{*/ -/*ddwaf::key_iterator it(&root, {}, exclude);*/ +/*ddwaf::key_iterator it(root, {}, exclude);*/ /*EXPECT_FALSE(it);*/ /*}*/ /*root.nbEntries = 1;*/ @@ -897,7 +897,7 @@ TEST(TestKeyIterator, TestMapDepthLimitPath) /*ddwaf_object_map_add(&root, "other", ddwaf_object_map(&tmp));*/ /*root.array[1].nbEntries = 30;*/ /*{*/ -/*ddwaf::key_iterator it(&root, {}, exclude);*/ +/*ddwaf::key_iterator it(root, {}, exclude);*/ /*EXPECT_TRUE(it);*/ /*EXPECT_TRUE(++it);*/ /*EXPECT_FALSE(++it);*/ @@ -916,13 +916,13 @@ TEST(TestKeyIterator, TestMapDepthLimitPath) /*root.array[0].parameterName = nullptr;*/ /*{*/ -/*ddwaf::key_iterator it(&root, {}, exclude);*/ +/*ddwaf::key_iterator it(root, {}, exclude);*/ /*EXPECT_FALSE(it);*/ /*}*/ /*ddwaf_object_map_add(&root, "other", ddwaf_object_string(&tmp, "value"));*/ /*{*/ -/*ddwaf::key_iterator it(&root, {}, exclude);*/ +/*ddwaf::key_iterator it(root, {}, exclude);*/ /*EXPECT_TRUE(it);*/ /*EXPECT_FALSE(++it);*/ /*}*/ @@ -941,7 +941,7 @@ TEST(TestKeyIterator, TestMapDepthLimitPath) /*exclusion::object_set_ref exclude;*/ /*{*/ /*std::vector key_path{"key"};*/ -/*ddwaf::key_iterator it(&root, key_path, exclude);*/ +/*ddwaf::key_iterator it(root, key_path, exclude);*/ /*EXPECT_FALSE(it);*/ /*}*/ @@ -951,7 +951,7 @@ TEST(TestKeyIterator, TestMapDepthLimitPath) /*{*/ /*std::vector key_path{"other"};*/ -/*ddwaf::key_iterator it(&root, key_path, exclude);*/ +/*ddwaf::key_iterator it(root, key_path, exclude);*/ /*EXPECT_TRUE(it);*/ /*EXPECT_FALSE(++it);*/ /*}*/ @@ -969,7 +969,7 @@ TEST(TestKeyIterator, TestRecursiveMap) root.array = &root; exclusion::object_set_ref exclude; - ddwaf::key_iterator it(&root, {}, exclude); + ddwaf::key_iterator it(root, {}, exclude); EXPECT_TRUE(it); EXPECT_FALSE(++it); } @@ -983,7 +983,7 @@ TEST(TestKeyIterator, TestExcludeSingleObject) std::unordered_set persistent{&object.array[0]}; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::key_iterator it(&object, {}, exclude); + ddwaf::key_iterator it(object, {}, exclude); EXPECT_FALSE(it); @@ -1003,19 +1003,19 @@ TEST(TestKeyIterator, TestExcludeMultipleObjects) std::unordered_set persistent{&root.array[0], &map.array[1]}; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::key_iterator it(&root, {}, exclude); + ddwaf::key_iterator it(root, {}, exclude); EXPECT_TRUE(it); - EXPECT_STREQ((*it).as_unchecked(), "other"); + EXPECT_STREQ((*it)->as_unchecked(), "other"); auto path = it.get_current_path(); EXPECT_EQ(path.size(), 1); EXPECT_STREQ(path[0].c_str(), "other"); - EXPECT_STREQ((*it).as_unchecked(), "other"); + EXPECT_STREQ((*it)->as_unchecked(), "other"); EXPECT_TRUE(++it); - EXPECT_STREQ((*it).as_unchecked(), "hello_key"); + EXPECT_STREQ((*it)->as_unchecked(), "hello_key"); path = it.get_current_path(); EXPECT_EQ(path.size(), 2); @@ -1039,7 +1039,7 @@ TEST(TestKeyIterator, TestExcludeObjectInKeyPath) std::unordered_set persistent{&child.array[0]}; exclusion::object_set_ref exclude{persistent, {}}; std::vector key_path{"parent", "child"}; - ddwaf::key_iterator it(&root, key_path, exclude); + ddwaf::key_iterator it(root, key_path, exclude); EXPECT_FALSE(it); @@ -1058,7 +1058,7 @@ TEST(TestKeyIterator, TestExcludeRootOfKeyPath) std::unordered_set persistent{&root.array[0]}; exclusion::object_set_ref exclude{persistent, {}}; std::vector key_path{"parent", "child"}; - ddwaf::key_iterator it(&root, key_path, exclude); + ddwaf::key_iterator it(root, key_path, exclude); EXPECT_FALSE(it); diff --git a/tests/kv_iterator_test.cpp b/tests/kv_iterator_test.cpp index a9e1490b..34f18a64 100644 --- a/tests/kv_iterator_test.cpp +++ b/tests/kv_iterator_test.cpp @@ -18,7 +18,7 @@ TEST(TestKVIterator, TestInvalidIterator) ddwaf_object_invalid(&object); exclusion::object_set_ref exclude; - ddwaf::kv_iterator it(&object, {}, exclude); + ddwaf::kv_iterator it(object, {}, exclude); EXPECT_FALSE((bool)it); EXPECT_EQ(*it, nullptr); @@ -34,7 +34,7 @@ TEST(TestKVIterator, TestStringScalar) ddwaf_object_string(&object, "value"); exclusion::object_set_ref exclude; - ddwaf::kv_iterator it(&object, {}, exclude); + ddwaf::kv_iterator it(object, {}, exclude); EXPECT_TRUE((bool)it); EXPECT_EQ(*it, &object); @@ -53,7 +53,7 @@ TEST(TestKVIterator, TestUnsignedScalar) ddwaf_object_unsigned(&object, 22); exclusion::object_set_ref exclude; - ddwaf::kv_iterator it(&object, {}, exclude); + ddwaf::kv_iterator it(object, {}, exclude); EXPECT_TRUE((bool)it); EXPECT_EQ(*it, &object); @@ -69,7 +69,7 @@ TEST(TestKVIterator, TestSignedScalar) ddwaf_object_signed(&object, 22); exclusion::object_set_ref exclude; - ddwaf::kv_iterator it(&object, {}, exclude); + ddwaf::kv_iterator it(object, {}, exclude); EXPECT_TRUE((bool)it); EXPECT_EQ(*it, &object); @@ -87,9 +87,9 @@ TEST(TestKVIterator, TestArraySingleItem) ddwaf_object_array_add(&object, ddwaf_object_string(&tmp, "string")); exclusion::object_set_ref exclude; - ddwaf::kv_iterator it(&object, {}, exclude); + ddwaf::kv_iterator it(object, {}, exclude); EXPECT_TRUE(it); - EXPECT_STREQ((*it).as_unchecked(), "string"); + EXPECT_STREQ((*it)->as_unchecked(), "string"); auto path = it.get_current_path(); EXPECT_EQ(path.size(), 1); @@ -111,13 +111,13 @@ TEST(TestKVIterator, TestArrayMultipleItems) std::unordered_set persistent; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::kv_iterator it(&object, {}, exclude); + ddwaf::kv_iterator it(object, {}, exclude); unsigned index = 0; do { auto index_str = std::to_string(index); EXPECT_TRUE(it); - EXPECT_STREQ((*it).as_unchecked(), index_str.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), index_str.c_str()); auto path = it.get_current_path(); EXPECT_EQ(path.size(), 1); @@ -145,13 +145,13 @@ TEST(TestKVIterator, TestArrayMultipleNullAndInvalid) std::unordered_set persistent; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::kv_iterator it(&object, {}, exclude); + ddwaf::kv_iterator it(object, {}, exclude); // Null and invalid objects should be skipped unsigned index = 0; do { EXPECT_TRUE(it); - EXPECT_STREQ((*it).as_unchecked(), std::to_string(index).c_str()); + EXPECT_STREQ((*it)->as_unchecked(), std::to_string(index).c_str()); auto path = it.get_current_path(); EXPECT_EQ(path.size(), 1); @@ -177,12 +177,12 @@ TEST(TestKVIterator, TestArrayPastSizeLimit) std::unordered_set persistent; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::kv_iterator it(&object, {}, exclude); + ddwaf::kv_iterator it(object, {}, exclude); for (unsigned i = 0; i < limits.max_container_size; i++) { auto index_str = std::to_string(i); EXPECT_TRUE(it); - EXPECT_STREQ((*it).as_unchecked(), index_str.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), index_str.c_str()); auto path = it.get_current_path(); EXPECT_EQ(path.size(), 1); @@ -218,11 +218,11 @@ TEST(TestKVIterator, TestDeepArray) std::unordered_set persistent; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::kv_iterator it(&object, {}, exclude); + ddwaf::kv_iterator it(object, {}, exclude); for (unsigned i = 0; i < 10; i++) { auto index = std::to_string(i); - EXPECT_STREQ((*it).as_unchecked(), ("val" + index).c_str()); + EXPECT_STREQ((*it)->as_unchecked(), ("val" + index).c_str()); auto path = it.get_current_path(); EXPECT_EQ(path.size(), i + 1); @@ -259,11 +259,11 @@ TEST(TestKVIterator, TestDeepArrayPastLimit) std::unordered_set persistent; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::kv_iterator it(&object, {}, exclude); + ddwaf::kv_iterator it(object, {}, exclude); for (unsigned i = 0; i < limits.max_container_depth; i++) { auto index = std::to_string(i); - EXPECT_STREQ((*it).as_unchecked(), ("val" + index).c_str()); + EXPECT_STREQ((*it)->as_unchecked(), ("val" + index).c_str()); auto path = it.get_current_path(); EXPECT_EQ(path.size(), i + 1); @@ -285,7 +285,7 @@ TEST(TestKVIterator, TestArrayNoScalars) for (unsigned i = 0; i < 50; i++) { ddwaf_object_array_add(&object, ddwaf_object_array(&tmp)); } exclusion::object_set_ref exclude; - ddwaf::kv_iterator it(&object, {}, exclude); + ddwaf::kv_iterator it(object, {}, exclude); EXPECT_EQ(*it, nullptr); EXPECT_FALSE((bool)it); @@ -302,11 +302,11 @@ TEST(TestKVIterator, TestMapSingleItem) ddwaf_object_map_add(&object, "key", ddwaf_object_string(&tmp, "value")); exclusion::object_set_ref exclude; - ddwaf::kv_iterator it(&object, {}, exclude); + ddwaf::kv_iterator it(object, {}, exclude); { EXPECT_TRUE((bool)it); EXPECT_EQ((*it).ptr()->parameterName, nullptr); - EXPECT_STREQ((*it).as_unchecked(), "key"); + EXPECT_STREQ((*it)->as_unchecked(), "key"); auto path = it.get_current_path(); EXPECT_EQ(path.size(), 1); @@ -315,7 +315,7 @@ TEST(TestKVIterator, TestMapSingleItem) { EXPECT_TRUE(++it); - EXPECT_STREQ((*it).as_unchecked(), "value"); + EXPECT_STREQ((*it)->as_unchecked(), "value"); auto path = it.get_current_path(); EXPECT_EQ(path.size(), 1); @@ -341,7 +341,7 @@ TEST(TestKVIterator, TestMapMultipleItems) } exclusion::object_set_ref exclude; - ddwaf::kv_iterator it(&object, {}, exclude); + ddwaf::kv_iterator it(object, {}, exclude); for (unsigned i = 0; i < 50; i++) { auto index = std::to_string(i); @@ -349,14 +349,14 @@ TEST(TestKVIterator, TestMapMultipleItems) std::string value = "value" + index; EXPECT_TRUE((bool)it); - EXPECT_STREQ((*it).as_unchecked(), key.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), key.c_str()); auto path = it.get_current_path(); EXPECT_EQ(path.size(), 1); EXPECT_STREQ(path[0].c_str(), key.c_str()); EXPECT_TRUE(++it); - EXPECT_STREQ((*it).as_unchecked(), value.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), value.c_str()); EXPECT_STREQ((*it).ptr()->parameterName, key.c_str()); path = it.get_current_path(); @@ -399,7 +399,7 @@ TEST(TestKVIterator, TestMapMultipleNullAndInvalid) } exclusion::object_set_ref exclude; - ddwaf::kv_iterator it(&object, {}, exclude); + ddwaf::kv_iterator it(object, {}, exclude); for (unsigned i = 0; i < 25; i++) { { @@ -408,14 +408,14 @@ TEST(TestKVIterator, TestMapMultipleNullAndInvalid) std::string value = "value" + index; EXPECT_TRUE((bool)it); - EXPECT_STREQ((*it).as_unchecked(), key.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), key.c_str()); auto path = it.get_current_path(); EXPECT_EQ(path.size(), 1); EXPECT_STREQ(path[0].c_str(), key.c_str()); EXPECT_TRUE(++it); - EXPECT_STREQ((*it).as_unchecked(), value.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), value.c_str()); path = it.get_current_path(); EXPECT_EQ(path.size(), 1); @@ -470,7 +470,7 @@ TEST(TestKVIterator, TestMapPastSizeLimit) } exclusion::object_set_ref exclude; - ddwaf::kv_iterator it(&object, {}, exclude); + ddwaf::kv_iterator it(object, {}, exclude); for (unsigned i = 0; i < limits.max_container_size; i++) { auto index = std::to_string(i); @@ -478,14 +478,14 @@ TEST(TestKVIterator, TestMapPastSizeLimit) std::string value = "value" + index; EXPECT_TRUE((bool)it); - EXPECT_STREQ((*it).as_unchecked(), key.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), key.c_str()); auto path = it.get_current_path(); EXPECT_EQ(path.size(), 1); EXPECT_STREQ(path[0].c_str(), key.c_str()); EXPECT_TRUE(++it); - EXPECT_STREQ((*it).as_unchecked(), value.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), value.c_str()); EXPECT_STREQ((*it).ptr()->parameterName, key.c_str()); path = it.get_current_path(); @@ -521,12 +521,12 @@ TEST(TestKVIterator, TestDeepMap) } exclusion::object_set_ref exclude; - ddwaf::kv_iterator it(&object, {}, exclude); + ddwaf::kv_iterator it(object, {}, exclude); for (unsigned i = 0; i < 10; i++) { auto index = std::to_string(i); - EXPECT_STREQ((*it).as_unchecked(), ("str" + index).c_str()); + EXPECT_STREQ((*it)->as_unchecked(), ("str" + index).c_str()); { auto path = it.get_current_path(); @@ -539,7 +539,7 @@ TEST(TestKVIterator, TestDeepMap) } EXPECT_TRUE(++it); - EXPECT_STREQ((*it).as_unchecked(), ("val" + index).c_str()); + EXPECT_STREQ((*it)->as_unchecked(), ("val" + index).c_str()); { auto path = it.get_current_path(); EXPECT_EQ(path.size(), i + 1); @@ -550,7 +550,7 @@ TEST(TestKVIterator, TestDeepMap) } EXPECT_TRUE(++it); - EXPECT_STREQ((*it).as_unchecked(), ("map" + index).c_str()); + EXPECT_STREQ((*it)->as_unchecked(), ("map" + index).c_str()); { auto path = it.get_current_path(); EXPECT_EQ(path.size(), i + 1); @@ -590,12 +590,12 @@ TEST(TestKVIterator, TestMapPastDepthLimit) } exclusion::object_set_ref exclude; - ddwaf::kv_iterator it(&object, {}, exclude); + ddwaf::kv_iterator it(object, {}, exclude); for (unsigned i = 0; i < limits.max_container_depth; i++) { auto index = std::to_string(i); - EXPECT_STREQ((*it).as_unchecked(), ("str" + index).c_str()); + EXPECT_STREQ((*it)->as_unchecked(), ("str" + index).c_str()); { auto path = it.get_current_path(); @@ -608,7 +608,7 @@ TEST(TestKVIterator, TestMapPastDepthLimit) } EXPECT_TRUE(++it); - EXPECT_STREQ((*it).as_unchecked(), ("val" + index).c_str()); + EXPECT_STREQ((*it)->as_unchecked(), ("val" + index).c_str()); { auto path = it.get_current_path(); @@ -621,7 +621,7 @@ TEST(TestKVIterator, TestMapPastDepthLimit) } EXPECT_TRUE(++it); - EXPECT_STREQ((*it).as_unchecked(), ("map" + index).c_str()); + EXPECT_STREQ((*it)->as_unchecked(), ("map" + index).c_str()); { auto path = it.get_current_path(); @@ -655,16 +655,16 @@ TEST(TestKVIterator, TestNoRootKey) ddwaf_object_map_add(&root, "root", &object); exclusion::object_set_ref exclude; - ddwaf::kv_iterator it(&root.array[0], {}, exclude); + ddwaf::kv_iterator it(root.array[0], {}, exclude); EXPECT_TRUE((bool)it); - EXPECT_STREQ((*it).as_unchecked(), "key"); + EXPECT_STREQ((*it)->as_unchecked(), "key"); auto path = it.get_current_path(); EXPECT_EQ(path.size(), 1); EXPECT_STREQ(path[0].c_str(), "key"); EXPECT_TRUE(++it); - EXPECT_STREQ((*it).as_unchecked(), "value"); + EXPECT_STREQ((*it)->as_unchecked(), "value"); path = it.get_current_path(); EXPECT_EQ(path.size(), 1); @@ -695,7 +695,7 @@ TEST(TestKVIterator, TestContainerMix) { exclusion::object_set_ref exclude; - ddwaf::kv_iterator it(&object, {}, exclude); + ddwaf::kv_iterator it(object, {}, exclude); std::vector>> values = { {"root", {"root"}}, @@ -718,7 +718,7 @@ TEST(TestKVIterator, TestContainerMix) }; for (auto &[value, path] : values) { - EXPECT_STREQ((*it).as_unchecked(), value.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), value.c_str()); auto it_path = it.get_current_path(); EXPECT_EQ(path, it_path); @@ -741,11 +741,11 @@ TEST(TestKVIterator, TestMapNoScalars) } exclusion::object_set_ref exclude; - ddwaf::kv_iterator it(&object, {}, exclude); + ddwaf::kv_iterator it(object, {}, exclude); for (unsigned i = 0; i < 50; i++) { EXPECT_TRUE((bool)it); - EXPECT_STREQ((*it).as_unchecked(), "key"); + EXPECT_STREQ((*it)->as_unchecked(), "key"); auto path = it.get_current_path(); EXPECT_EQ(path.size(), 1); @@ -765,7 +765,7 @@ TEST(TestKVIterator, TestInvalidObjectPath) exclusion::object_set_ref exclude; std::vector key_path{"key", "0", "value"}; - ddwaf::kv_iterator it(&object, key_path, exclude); + ddwaf::kv_iterator it(object, key_path, exclude); EXPECT_FALSE((bool)it); auto path = it.get_current_path(); @@ -781,14 +781,14 @@ TEST(TestKVIterator, TestSimplePath) { std::vector key_path{"key"}; - ddwaf::kv_iterator it(&object, key_path, {}); + ddwaf::kv_iterator it(object, key_path, {}); EXPECT_FALSE((bool)it); EXPECT_FALSE(++it); } { std::vector key_path{"key", "0"}; - ddwaf::kv_iterator it(&object, key_path, {}); + ddwaf::kv_iterator it(object, key_path, {}); EXPECT_FALSE((bool)it); auto path = it.get_current_path(); @@ -799,7 +799,7 @@ TEST(TestKVIterator, TestSimplePath) { std::vector key_path{"key", "0", "value"}; - ddwaf::kv_iterator it(&object, key_path, {}); + ddwaf::kv_iterator it(object, key_path, {}); EXPECT_FALSE((bool)it); auto path = it.get_current_path(); @@ -839,10 +839,10 @@ TEST(TestKVIterator, TestMultiPath) }; std::vector key_path{"first"}; - ddwaf::kv_iterator it(&object, key_path, exclude); + ddwaf::kv_iterator it(object, key_path, exclude); for (auto &[value, path] : values) { - EXPECT_STREQ((*it).as_unchecked(), value.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), value.c_str()); auto it_path = it.get_current_path(); EXPECT_EQ(path, it_path); @@ -861,10 +861,10 @@ TEST(TestKVIterator, TestMultiPath) }; std::vector key_path{"first", "second"}; - ddwaf::kv_iterator it(&object, key_path, exclude); + ddwaf::kv_iterator it(object, key_path, exclude); for (auto &[value, path] : values) { - EXPECT_STREQ((*it).as_unchecked(), value.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), value.c_str()); auto it_path = it.get_current_path(); EXPECT_EQ(path, it_path); @@ -880,10 +880,10 @@ TEST(TestKVIterator, TestMultiPath) }; std::vector key_path{"first", "second", "third"}; - ddwaf::kv_iterator it(&object, key_path, exclude); + ddwaf::kv_iterator it(object, key_path, exclude); for (auto &[value, path] : values) { - EXPECT_STREQ((*it).as_unchecked(), value.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), value.c_str()); auto it_path = it.get_current_path(); EXPECT_EQ(path, it_path); @@ -917,7 +917,7 @@ TEST(TestKVIterator, TestContainerMixPath) exclusion::object_set_ref exclude; { std::vector key_path{"root", "key0"}; - ddwaf::kv_iterator it(&object, key_path, exclude); + ddwaf::kv_iterator it(object, key_path, exclude); std::vector>> values = { {"value0_0", {"root", "key0", "0"}}, @@ -928,7 +928,7 @@ TEST(TestKVIterator, TestContainerMixPath) }; for (auto &[value, path] : values) { - EXPECT_STREQ((*it).as_unchecked(), value.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), value.c_str()); auto it_path = it.get_current_path(); EXPECT_EQ(path, it_path); @@ -940,10 +940,10 @@ TEST(TestKVIterator, TestContainerMixPath) { std::vector key_path{"root", "key1"}; - ddwaf::kv_iterator it(&object, key_path, exclude); + ddwaf::kv_iterator it(object, key_path, exclude); EXPECT_TRUE((bool)it); - EXPECT_STREQ((*it).as_unchecked(), "value1_0"); + EXPECT_STREQ((*it)->as_unchecked(), "value1_0"); auto path = it.get_current_path(); EXPECT_EQ(path, key_path); @@ -963,10 +963,10 @@ TEST(TestKVIterator, TestContainerMixPath) }; std::vector key_path{"root", "key2"}; - ddwaf::kv_iterator it(&object, key_path, exclude); + ddwaf::kv_iterator it(object, key_path, exclude); for (auto &[value, path] : values) { - EXPECT_STREQ((*it).as_unchecked(), value.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), value.c_str()); auto it_path = it.get_current_path(); EXPECT_EQ(path, it_path); @@ -1000,19 +1000,19 @@ TEST(TestKVIterator, TestContainerMixInvalidPath) exclusion::object_set_ref exclude; { std::vector key_path{"rat"}; - ddwaf::kv_iterator it(&object, key_path, exclude); + ddwaf::kv_iterator it(object, key_path, exclude); EXPECT_FALSE((bool)it); } { std::vector key_path{"root", "cat"}; - ddwaf::kv_iterator it(&object, key_path, exclude); + ddwaf::kv_iterator it(object, key_path, exclude); EXPECT_FALSE((bool)it); } { std::vector key_path{"root", "key2", "key2_2", "0", "1", "2", "3"}; - ddwaf::kv_iterator it(&object, key_path, exclude); + ddwaf::kv_iterator it(object, key_path, exclude); EXPECT_FALSE((bool)it); } @@ -1042,7 +1042,7 @@ TEST(TestKVIterator, TestMapDepthLimitPath) { limits.max_container_depth = 3; std::vector key_path{"root", "child", "grandchild"}; - ddwaf::kv_iterator it(&object, key_path, exclude, limits); + ddwaf::kv_iterator it(object, key_path, exclude, limits); EXPECT_FALSE(it); } @@ -1050,7 +1050,7 @@ TEST(TestKVIterator, TestMapDepthLimitPath) { limits.max_container_depth = 4; std::vector key_path{"root", "child", "grandchild"}; - ddwaf::kv_iterator it(&object, key_path, exclude, limits); + ddwaf::kv_iterator it(object, key_path, exclude, limits); EXPECT_TRUE(it); { @@ -1071,7 +1071,7 @@ TEST(TestKVIterator, TestMapDepthLimitPath) auto it_path = it.get_current_path(); std::vector path = {"root", "child", "grandchild", "another"}; EXPECT_EQ(it_path, path); - EXPECT_STREQ((*it).as_unchecked(), "value"); + EXPECT_STREQ((*it)->as_unchecked(), "value"); } EXPECT_FALSE(++it); @@ -1087,7 +1087,7 @@ TEST(TestKVIterator, TestMapDepthLimitPath) /*exclusion::object_set_ref exclude;*/ /*root.nbEntries = 30;*/ /*{*/ -/*ddwaf::kv_iterator it(&root, {}, exclude);*/ +/*ddwaf::kv_iterator it(root, {}, exclude);*/ /*EXPECT_FALSE(it);*/ /*}*/ @@ -1096,7 +1096,7 @@ TEST(TestKVIterator, TestMapDepthLimitPath) /*root.nbEntries = 0;*/ /*{*/ -/*ddwaf::kv_iterator it(&root, {}, exclude);*/ +/*ddwaf::kv_iterator it(root, {}, exclude);*/ /*EXPECT_FALSE(it);*/ /*}*/ /*root.nbEntries = 1;*/ @@ -1104,7 +1104,7 @@ TEST(TestKVIterator, TestMapDepthLimitPath) /*ddwaf_object_map_add(&root, "other", ddwaf_object_map(&tmp));*/ /*root.array[1].nbEntries = 30;*/ /*{*/ -/*ddwaf::kv_iterator it(&root, {}, exclude);*/ +/*ddwaf::kv_iterator it(root, {}, exclude);*/ /*EXPECT_TRUE(it);*/ /*EXPECT_TRUE(++it);*/ /*EXPECT_TRUE(++it);*/ @@ -1124,14 +1124,14 @@ TEST(TestKVIterator, TestMapDepthLimitPath) /*root.array[0].parameterName = nullptr;*/ /*{*/ -/*ddwaf::kv_iterator it(&root, {}, exclude);*/ +/*ddwaf::kv_iterator it(root, {}, exclude);*/ /*EXPECT_TRUE(it);*/ /*EXPECT_FALSE(++it);*/ /*}*/ /*ddwaf_object_map_add(&root, "other", ddwaf_object_string(&tmp, "value"));*/ /*{*/ -/*ddwaf::kv_iterator it(&root, {}, exclude);*/ +/*ddwaf::kv_iterator it(root, {}, exclude);*/ /*EXPECT_TRUE(it);*/ /*EXPECT_TRUE(++it);*/ /*EXPECT_TRUE(++it);*/ @@ -1152,7 +1152,7 @@ TEST(TestKVIterator, TestMapDepthLimitPath) /*exclusion::object_set_ref exclude;*/ /*{*/ /*std::vector key_path{"key"};*/ -/*ddwaf::kv_iterator it(&root, key_path, exclude);*/ +/*ddwaf::kv_iterator it(root, key_path, exclude);*/ /*EXPECT_FALSE(it);*/ /*}*/ @@ -1162,7 +1162,7 @@ TEST(TestKVIterator, TestMapDepthLimitPath) /*{*/ /*std::vector key_path{"other"};*/ -/*ddwaf::kv_iterator it(&root, key_path, exclude);*/ +/*ddwaf::kv_iterator it(root, key_path, exclude);*/ /*EXPECT_TRUE(it);*/ /*EXPECT_TRUE(++it);*/ /*EXPECT_FALSE(++it);*/ @@ -1181,7 +1181,7 @@ TEST(TestKVIterator, TestRecursiveMap) root.array = &root; exclusion::object_set_ref exclude; - ddwaf::kv_iterator it(&root, {}, exclude); + ddwaf::kv_iterator it(root, {}, exclude); EXPECT_TRUE(it); EXPECT_FALSE(++it); } @@ -1195,7 +1195,7 @@ TEST(TestKVIterator, TestExcludeSingleObject) std::unordered_set persistent{&object.array[0]}; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::kv_iterator it(&object, {}, exclude); + ddwaf::kv_iterator it(object, {}, exclude); EXPECT_FALSE(it); @@ -1215,19 +1215,19 @@ TEST(TestKVIterator, TestExcludeMultipleObjects) std::unordered_set persistent{&root.array[0], &map.array[1]}; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::kv_iterator it(&root, {}, exclude); + ddwaf::kv_iterator it(root, {}, exclude); EXPECT_TRUE(it); - EXPECT_STREQ((*it).as_unchecked(), "other"); + EXPECT_STREQ((*it)->as_unchecked(), "other"); auto path = it.get_current_path(); EXPECT_EQ(path.size(), 1); EXPECT_STREQ(path[0].c_str(), "other"); - EXPECT_STREQ((*it).as_unchecked(), "other"); + EXPECT_STREQ((*it)->as_unchecked(), "other"); EXPECT_TRUE(++it); - EXPECT_STREQ((*it).as_unchecked(), "hello_key"); + EXPECT_STREQ((*it)->as_unchecked(), "hello_key"); path = it.get_current_path(); EXPECT_EQ(path.size(), 2); @@ -1235,7 +1235,7 @@ TEST(TestKVIterator, TestExcludeMultipleObjects) EXPECT_STREQ(path[1].c_str(), "hello_key"); EXPECT_TRUE(++it); - EXPECT_STREQ((*it).as_unchecked(), "hello"); + EXPECT_STREQ((*it)->as_unchecked(), "hello"); path = it.get_current_path(); EXPECT_EQ(path.size(), 2); EXPECT_STREQ(path[0].c_str(), "other"); @@ -1258,7 +1258,7 @@ TEST(TestKVIterator, TestExcludeObjectInKeyPath) std::unordered_set persistent{&child.array[0]}; exclusion::object_set_ref exclude{persistent, {}}; std::vector key_path{"parent", "child"}; - ddwaf::kv_iterator it(&root, key_path, exclude); + ddwaf::kv_iterator it(root, key_path, exclude); EXPECT_FALSE(it); @@ -1277,7 +1277,7 @@ TEST(TestKVIterator, TestExcludeRootOfKeyPath) std::unordered_set persistent{&root.array[0]}; exclusion::object_set_ref exclude{persistent, {}}; std::vector key_path{"parent", "child"}; - ddwaf::kv_iterator it(&root, key_path, exclude); + ddwaf::kv_iterator it(root, key_path, exclude); EXPECT_FALSE(it); diff --git a/tests/object_view_test.cpp b/tests/object_view_test.cpp index be6683fe..75487ef2 100644 --- a/tests/object_view_test.cpp +++ b/tests/object_view_test.cpp @@ -16,11 +16,9 @@ TEST(TestObjectView, InvalidObject) detail::object original; ddwaf_object_invalid(&original); - object_view view(&original); - EXPECT_TRUE(view.has_value()); + object_view view(original); EXPECT_EQ(view.type(), object_type::invalid); - EXPECT_EQ(view.type_unchecked(), object_type::invalid); EXPECT_EQ(view.size(), 0); EXPECT_TRUE(view.empty()); @@ -40,11 +38,9 @@ TEST(TestObjectView, NullObject) detail::object original; ddwaf_object_invalid(&original); - object_view view(&original); - EXPECT_TRUE(view.has_value()); + object_view view(original); EXPECT_EQ(view.type(), object_type::invalid); - EXPECT_EQ(view.type_unchecked(), object_type::invalid); EXPECT_EQ(view.size(), 0); EXPECT_TRUE(view.empty()); @@ -65,11 +61,9 @@ TEST(TestObjectView, BooleanObject) detail::object original; ddwaf_object_bool(&original, true); - object_view view(&original); - EXPECT_TRUE(view.has_value()); + object_view view(original); EXPECT_EQ(view.type(), object_type::boolean); - EXPECT_EQ(view.type_unchecked(), object_type::boolean); EXPECT_EQ(view.size(), 0); EXPECT_TRUE(view.empty()); @@ -93,11 +87,9 @@ TEST(TestObjectView, SignedObject) detail::object original; ddwaf_object_signed(&original, -20); - object_view view(&original); - EXPECT_TRUE(view.has_value()); + object_view view(original); EXPECT_EQ(view.type(), object_type::int64); - EXPECT_EQ(view.type_unchecked(), object_type::int64); EXPECT_EQ(view.size(), 0); EXPECT_TRUE(view.empty()); @@ -121,11 +113,9 @@ TEST(TestObjectView, UnsignedObject) detail::object original; ddwaf_object_unsigned(&original, 20); - object_view view(&original); - EXPECT_TRUE(view.has_value()); + object_view view(original); EXPECT_EQ(view.type(), object_type::uint64); - EXPECT_EQ(view.type_unchecked(), object_type::uint64); EXPECT_EQ(view.size(), 0); EXPECT_TRUE(view.empty()); @@ -149,11 +139,9 @@ TEST(TestObjectView, FloatObject) detail::object original; ddwaf_object_float(&original, 20.1); - object_view view(&original); - EXPECT_TRUE(view.has_value()); + object_view view(original); EXPECT_EQ(view.type(), object_type::float64); - EXPECT_EQ(view.type_unchecked(), object_type::float64); EXPECT_EQ(view.size(), 0); EXPECT_TRUE(view.empty()); @@ -183,19 +171,19 @@ TEST(TestObjectView, ArrayObject) ddwaf_object_string(&tmp, std::to_string(i + 100).c_str())); } - object_view view(&root); + object_view view(root); EXPECT_EQ(view.size(), 20); for (unsigned i = 0; i < 20; i++) { auto [key, value] = view.at_unchecked(i); - EXPECT_STREQ(value.as_unchecked(), std::to_string(100 + i).c_str()); + EXPECT_STREQ(value->as_unchecked(), std::to_string(100 + i).c_str()); } - auto array_view = view.as_unchecked(); - unsigned i = 0; - for (auto value : array_view) { - EXPECT_STREQ(value.as_unchecked(), std::to_string(100 + i++).c_str()); - } +/* auto array_view = view.as_unchecked();*/ + /*unsigned i = 0;*/ + /*for (auto value : array_view) {*/ + /*EXPECT_STREQ(value.as_unchecked(), std::to_string(100 + i++).c_str());*/ + /*}*/ ddwaf_object_free(&root); } diff --git a/tests/value_iterator_test.cpp b/tests/value_iterator_test.cpp index d4accbfe..c0415987 100644 --- a/tests/value_iterator_test.cpp +++ b/tests/value_iterator_test.cpp @@ -19,7 +19,7 @@ TEST(TestValueIterator, TestInvalidIterator) std::unordered_set persistent; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::value_iterator it(&object, {}, exclude); + ddwaf::value_iterator it(object, {}, exclude); EXPECT_FALSE(it); auto path = it.get_current_path(); @@ -35,7 +35,7 @@ TEST(TestValueIterator, TestStringScalar) std::unordered_set persistent; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::value_iterator it(&object, {}, exclude); + ddwaf::value_iterator it(object, {}, exclude); EXPECT_TRUE(it); EXPECT_EQ(*it, &object); @@ -54,7 +54,7 @@ TEST(TestValueIterator, TestUnsignedScalar) std::unordered_set persistent; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::value_iterator it(&object, {}, exclude); + ddwaf::value_iterator it(object, {}, exclude); EXPECT_TRUE(it); EXPECT_EQ(*it, &object); @@ -71,7 +71,7 @@ TEST(TestValueIterator, TestSignedScalar) std::unordered_set persistent; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::value_iterator it(&object, {}, exclude); + ddwaf::value_iterator it(object, {}, exclude); EXPECT_TRUE(it); EXPECT_EQ(*it, &object); @@ -89,9 +89,9 @@ TEST(TestValueIterator, TestArraySingleItem) std::unordered_set persistent; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::value_iterator it(&object, {}, exclude); + ddwaf::value_iterator it(object, {}, exclude); EXPECT_TRUE(it); - EXPECT_STREQ((*it).as_unchecked(), "string"); + EXPECT_STREQ((*it)->as_unchecked(), "string"); auto path = it.get_current_path(); EXPECT_EQ(path.size(), 1); @@ -112,13 +112,13 @@ TEST(TestValueIterator, TestArrayMultipleItems) std::unordered_set persistent; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::value_iterator it(&object, {}, exclude); + ddwaf::value_iterator it(object, {}, exclude); unsigned index = 0; do { auto index_str = std::to_string(index); EXPECT_TRUE(it); - EXPECT_STREQ((*it).as_unchecked(), index_str.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), index_str.c_str()); auto path = it.get_current_path(); EXPECT_EQ(path.size(), 1); @@ -146,13 +146,13 @@ TEST(TestValueIterator, TestArrayMultipleNullAndInvalid) std::unordered_set persistent; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::value_iterator it(&object, {}, exclude); + ddwaf::value_iterator it(object, {}, exclude); // Null and invalid objects should be skipped unsigned index = 0; do { EXPECT_TRUE(it); - EXPECT_STREQ((*it).as_unchecked(), std::to_string(index).c_str()); + EXPECT_STREQ((*it)->as_unchecked(), std::to_string(index).c_str()); auto path = it.get_current_path(); EXPECT_EQ(path.size(), 1); @@ -177,12 +177,12 @@ TEST(TestValueIterator, TestArrayPastSizeLimit) std::unordered_set persistent; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::value_iterator it(&object, {}, exclude); + ddwaf::value_iterator it(object, {}, exclude); for (unsigned i = 0; i < limits.max_container_size; i++) { auto index_str = std::to_string(i); EXPECT_TRUE(it); - EXPECT_STREQ((*it).as_unchecked(), index_str.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), index_str.c_str()); auto path = it.get_current_path(); EXPECT_EQ(path.size(), 1); @@ -217,11 +217,11 @@ TEST(TestValueIterator, TestDeepArray) std::unordered_set persistent; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::value_iterator it(&object, {}, exclude); + ddwaf::value_iterator it(object, {}, exclude); for (unsigned i = 0; i < 10; i++) { auto index = std::to_string(i); - EXPECT_STREQ((*it).as_unchecked(), ("val" + index).c_str()); + EXPECT_STREQ((*it)->as_unchecked(), ("val" + index).c_str()); auto path = it.get_current_path(); EXPECT_EQ(path.size(), i + 1); @@ -257,11 +257,11 @@ TEST(TestValueIterator, TestDeepArrayPastLimit) std::unordered_set persistent; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::value_iterator it(&object, {}, exclude); + ddwaf::value_iterator it(object, {}, exclude); for (unsigned i = 0; i < limits.max_container_depth; i++) { auto index = std::to_string(i); - EXPECT_STREQ((*it).as_unchecked(), ("val" + index).c_str()); + EXPECT_STREQ((*it)->as_unchecked(), ("val" + index).c_str()); auto path = it.get_current_path(); EXPECT_EQ(path.size(), i + 1); @@ -283,7 +283,7 @@ TEST(TestValueIterator, TestArrayNoScalars) std::unordered_set persistent; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::value_iterator it(&object, {}, exclude); + ddwaf::value_iterator it(object, {}, exclude); EXPECT_FALSE(it); EXPECT_FALSE(++it); @@ -299,10 +299,10 @@ TEST(TestValueIterator, TestMapSingleItem) std::unordered_set persistent; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::value_iterator it(&object, {}, exclude); + ddwaf::value_iterator it(object, {}, exclude); EXPECT_TRUE(it); - EXPECT_STREQ((*it).as_unchecked(), "value"); + EXPECT_STREQ((*it)->as_unchecked(), "value"); EXPECT_STREQ((*it).ptr()->parameterName, "key"); auto path = it.get_current_path(); @@ -328,7 +328,7 @@ TEST(TestValueIterator, TestMapMultipleItems) std::unordered_set persistent{}; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::value_iterator it(&object, {}, exclude); + ddwaf::value_iterator it(object, {}, exclude); for (unsigned i = 0; i < 50; i++) { auto index = std::to_string(i); @@ -336,7 +336,7 @@ TEST(TestValueIterator, TestMapMultipleItems) std::string value = "value" + index; EXPECT_TRUE(it); - EXPECT_STREQ((*it).as_unchecked(), value.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), value.c_str()); EXPECT_STREQ((*it).ptr()->parameterName, key.c_str()); auto path = it.get_current_path(); @@ -379,7 +379,7 @@ TEST(TestValueIterator, TestMapMultipleMultipleNullAndInvalid) std::unordered_set persistent; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::value_iterator it(&object, {}, exclude); + ddwaf::value_iterator it(object, {}, exclude); for (unsigned i = 0; i < 25; i++) { auto index = std::to_string(i * 3); @@ -387,7 +387,7 @@ TEST(TestValueIterator, TestMapMultipleMultipleNullAndInvalid) std::string value = "value" + index; EXPECT_TRUE(it); - EXPECT_STREQ((*it).as_unchecked(), value.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), value.c_str()); EXPECT_STREQ((*it).ptr()->parameterName, key.c_str()); auto path = it.get_current_path(); @@ -416,7 +416,7 @@ TEST(TestValueIterator, TestMapPastSizeLimit) std::unordered_set persistent; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::value_iterator it(&object, {}, exclude); + ddwaf::value_iterator it(object, {}, exclude); for (unsigned i = 0; i < limits.max_container_size; i++) { auto index = std::to_string(i); @@ -424,7 +424,7 @@ TEST(TestValueIterator, TestMapPastSizeLimit) std::string value = "value" + index; EXPECT_TRUE(it); - EXPECT_STREQ((*it).as_unchecked(), value.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), value.c_str()); EXPECT_STREQ((*it).ptr()->parameterName, key.c_str()); auto path = it.get_current_path(); @@ -460,12 +460,12 @@ TEST(TestValueIterator, TestDeepMap) std::unordered_set persistent; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::value_iterator it(&object, {}, exclude); + ddwaf::value_iterator it(object, {}, exclude); for (unsigned i = 0; i < 10; i++) { auto index = std::to_string(i); EXPECT_STREQ((*it).ptr()->parameterName, ("str" + index).c_str()); - EXPECT_STREQ((*it).as_unchecked(), ("val" + index).c_str()); + EXPECT_STREQ((*it)->as_unchecked(), ("val" + index).c_str()); auto path = it.get_current_path(); EXPECT_EQ(path.size(), i + 1); @@ -505,12 +505,12 @@ TEST(TestValueIterator, TestMapPastDepthLimit) std::unordered_set persistent; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::value_iterator it(&object, {}, exclude); + ddwaf::value_iterator it(object, {}, exclude); for (unsigned i = 0; i < limits.max_container_depth; i++) { auto index = std::to_string(i); EXPECT_STREQ((*it).ptr()->parameterName, ("str" + index).c_str()); - EXPECT_STREQ((*it).as_unchecked(), ("val" + index).c_str()); + EXPECT_STREQ((*it)->as_unchecked(), ("val" + index).c_str()); auto path = it.get_current_path(); EXPECT_EQ(path.size(), i + 1); @@ -537,7 +537,7 @@ TEST(TestValueIterator, TestMapNoScalars) std::unordered_set persistent; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::value_iterator it(&object, {}, exclude); + ddwaf::value_iterator it(object, {}, exclude); EXPECT_FALSE(it); EXPECT_FALSE(++it); @@ -566,7 +566,7 @@ TEST(TestValueIterator, TestContainerMix) std::unordered_set persistent; exclusion::object_set_ref exclude{persistent, {}}; { - ddwaf::value_iterator it(&object, {}, exclude); + ddwaf::value_iterator it(object, {}, exclude); std::vector>> values = { {"value0_0", {"root", "key0", "0"}}, {"value0_1", {"root", "key0", "1"}}, @@ -576,7 +576,7 @@ TEST(TestValueIterator, TestContainerMix) {"value2_3", {"root", "key2", "key2_2", "1"}}}; for (auto &[value, path] : values) { - EXPECT_STREQ((*it).as_unchecked(), value.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), value.c_str()); auto it_path = it.get_current_path(); EXPECT_EQ(path, it_path); @@ -598,7 +598,7 @@ TEST(TestValueIterator, TestInvalidObjectPath) exclusion::object_set_ref exclude{persistent, {}}; { std::vector key_path{"key"}; - ddwaf::value_iterator it(&object, key_path, exclude); + ddwaf::value_iterator it(object, key_path, exclude); EXPECT_FALSE(it); auto path = it.get_current_path(); @@ -609,7 +609,7 @@ TEST(TestValueIterator, TestInvalidObjectPath) { std::vector key_path{"key", "0"}; - ddwaf::value_iterator it(&object, key_path, exclude); + ddwaf::value_iterator it(object, key_path, exclude); EXPECT_FALSE(it); auto path = it.get_current_path(); @@ -620,7 +620,7 @@ TEST(TestValueIterator, TestInvalidObjectPath) { std::vector key_path{"key", "0", "value"}; - ddwaf::value_iterator it(&object, key_path, exclude); + ddwaf::value_iterator it(object, key_path, exclude); EXPECT_FALSE(it); auto path = it.get_current_path(); @@ -643,7 +643,7 @@ TEST(TestValueIterator, TestSimplePath) exclusion::object_set_ref exclude{persistent, {}}; { std::vector key_path{"key"}; - ddwaf::value_iterator it(&object, key_path, exclude); + ddwaf::value_iterator it(object, key_path, exclude); EXPECT_TRUE(it); std::vector expected_path = {"key"}; @@ -656,7 +656,7 @@ TEST(TestValueIterator, TestSimplePath) { std::vector key_path{"key", "0"}; - ddwaf::value_iterator it(&object, key_path, exclude); + ddwaf::value_iterator it(object, key_path, exclude); EXPECT_FALSE(it); auto path = it.get_current_path(); @@ -667,7 +667,7 @@ TEST(TestValueIterator, TestSimplePath) { std::vector key_path{"key", "0", "value"}; - ddwaf::value_iterator it(&object, key_path, exclude); + ddwaf::value_iterator it(object, key_path, exclude); EXPECT_FALSE(it); auto path = it.get_current_path(); @@ -698,10 +698,10 @@ TEST(TestValueIterator, TestMultiPath) exclusion::object_set_ref exclude{persistent, {}}; { std::vector key_path{"first"}; - ddwaf::value_iterator it(&object, key_path, exclude); + ddwaf::value_iterator it(object, key_path, exclude); EXPECT_TRUE(it); - EXPECT_STREQ((*it).as_unchecked(), "final"); + EXPECT_STREQ((*it)->as_unchecked(), "final"); std::vector expected_path = {"first", "second", "third"}; auto path = it.get_current_path(); @@ -711,7 +711,7 @@ TEST(TestValueIterator, TestMultiPath) EXPECT_TRUE(++it); EXPECT_TRUE(it); - EXPECT_STREQ((*it).as_unchecked(), "value_third"); + EXPECT_STREQ((*it)->as_unchecked(), "value_third"); expected_path = decltype(expected_path){"first", "second", "value"}; path = it.get_current_path(); @@ -721,7 +721,7 @@ TEST(TestValueIterator, TestMultiPath) EXPECT_TRUE(++it); EXPECT_TRUE(it); - EXPECT_STREQ((*it).as_unchecked(), "value_second"); + EXPECT_STREQ((*it)->as_unchecked(), "value_second"); expected_path = decltype(expected_path){"first", "value"}; path = it.get_current_path(); @@ -733,10 +733,10 @@ TEST(TestValueIterator, TestMultiPath) { std::vector key_path{"first", "second"}; - ddwaf::value_iterator it(&object, key_path, exclude); + ddwaf::value_iterator it(object, key_path, exclude); EXPECT_TRUE(it); - EXPECT_STREQ((*it).as_unchecked(), "final"); + EXPECT_STREQ((*it)->as_unchecked(), "final"); std::vector expected_path = {"first", "second", "third"}; auto path = it.get_current_path(); @@ -746,7 +746,7 @@ TEST(TestValueIterator, TestMultiPath) EXPECT_TRUE(++it); EXPECT_TRUE(it); - EXPECT_STREQ((*it).as_unchecked(), "value_third"); + EXPECT_STREQ((*it)->as_unchecked(), "value_third"); expected_path = decltype(expected_path){"first", "second", "value"}; path = it.get_current_path(); @@ -758,10 +758,10 @@ TEST(TestValueIterator, TestMultiPath) { std::vector key_path{"first", "second", "third"}; - ddwaf::value_iterator it(&object, key_path, exclude); + ddwaf::value_iterator it(object, key_path, exclude); EXPECT_TRUE(it); - EXPECT_STREQ((*it).as_unchecked(), "final"); + EXPECT_STREQ((*it)->as_unchecked(), "final"); std::vector expected_path = {"first", "second", "third"}; auto path = it.get_current_path(); @@ -803,10 +803,10 @@ TEST(TestValueIterator, TestContainerMixPath) }; std::vector key_path{"root", "key0"}; - ddwaf::value_iterator it(&object, key_path, exclude); + ddwaf::value_iterator it(object, key_path, exclude); for (auto &[value, path] : values) { - EXPECT_STREQ((*it).as_unchecked(), value.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), value.c_str()); auto it_path = it.get_current_path(); EXPECT_EQ(path, it_path); @@ -818,8 +818,8 @@ TEST(TestValueIterator, TestContainerMixPath) { std::vector key_path{"root", "key1"}; - ddwaf::value_iterator it(&object, key_path, exclude); - EXPECT_STREQ((*it).as_unchecked(), "value1_0"); + ddwaf::value_iterator it(object, key_path, exclude); + EXPECT_STREQ((*it)->as_unchecked(), "value1_0"); auto it_path = it.get_current_path(); std::vector path = {"root", "key1"}; @@ -834,10 +834,10 @@ TEST(TestValueIterator, TestContainerMixPath) {"value2_3", {"root", "key2", "key2_2", "1"}}}; std::vector key_path{"root", "key2"}; - ddwaf::value_iterator it(&object, key_path, exclude); + ddwaf::value_iterator it(object, key_path, exclude); for (auto &[value, path] : values) { - EXPECT_STREQ((*it).as_unchecked(), value.c_str()); + EXPECT_STREQ((*it)->as_unchecked(), value.c_str()); auto it_path = it.get_current_path(); EXPECT_EQ(path, it_path); @@ -872,19 +872,19 @@ TEST(TestValueIterator, TestContainerMixInvalidPath) exclusion::object_set_ref exclude{persistent, {}}; { std::vector key_path{"rat"}; - ddwaf::value_iterator it(&object, key_path, exclude); + ddwaf::value_iterator it(object, key_path, exclude); EXPECT_FALSE(it); } { std::vector key_path{"root", "cat"}; - ddwaf::value_iterator it(&object, key_path, exclude); + ddwaf::value_iterator it(object, key_path, exclude); EXPECT_FALSE(it); } { std::vector key_path{"root", "key2", "key2_2", "0", "1", "2", "3"}; - ddwaf::value_iterator it(&object, key_path, exclude); + ddwaf::value_iterator it(object, key_path, exclude); EXPECT_FALSE(it); } @@ -912,7 +912,7 @@ TEST(TestValueIterator, TestMapDepthLimitPath) { limits.max_container_depth = 3; std::vector key_path{"root", "child", "grandchild"}; - ddwaf::value_iterator it(&object, key_path, exclude, limits); + ddwaf::value_iterator it(object, key_path, exclude, limits); EXPECT_FALSE(it); } @@ -920,7 +920,7 @@ TEST(TestValueIterator, TestMapDepthLimitPath) { limits.max_container_depth = 4; std::vector key_path{"root", "child", "grandchild"}; - ddwaf::value_iterator it(&object, key_path, exclude, limits); + ddwaf::value_iterator it(object, key_path, exclude, limits); auto it_path = it.get_current_path(); std::vector path = {"root", "child", "grandchild", "key"}; @@ -940,7 +940,7 @@ TEST(TestValueIterator, TestMapDepthLimitPath) /*exclusion::object_set_ref exclude{persistent, {}};*/ /*root.nbEntries = 30;*/ /*{*/ -/*ddwaf::value_iterator it(&root, {}, exclude);*/ +/*ddwaf::value_iterator it(root, {}, exclude);*/ /*EXPECT_FALSE(it);*/ /*}*/ @@ -949,7 +949,7 @@ TEST(TestValueIterator, TestMapDepthLimitPath) /*root.nbEntries = 0;*/ /*{*/ -/*ddwaf::value_iterator it(&root, {}, exclude);*/ +/*ddwaf::value_iterator it(root, {}, exclude);*/ /*EXPECT_FALSE(it);*/ /*}*/ /*root.nbEntries = 1;*/ @@ -957,7 +957,7 @@ TEST(TestValueIterator, TestMapDepthLimitPath) /*ddwaf_object_map_add(&root, "other", ddwaf_object_map(&tmp));*/ /*root.array[1].nbEntries = 30;*/ /*{*/ -/*ddwaf::value_iterator it(&root, {}, exclude);*/ +/*ddwaf::value_iterator it(root, {}, exclude);*/ /*EXPECT_TRUE(it);*/ /*EXPECT_FALSE(++it);*/ /*}*/ @@ -977,14 +977,14 @@ TEST(TestValueIterator, TestMapDepthLimitPath) /*exclusion::object_set_ref exclude{persistent, {}};*/ /*{*/ /*// The invalid key should have no impact*/ -/*ddwaf::value_iterator it(&root, {}, exclude);*/ +/*ddwaf::value_iterator it(root, {}, exclude);*/ /*EXPECT_TRUE(it);*/ /*}*/ /*ddwaf_object_map_add(&root, "other", ddwaf_object_string(&tmp, "value"));*/ /*{*/ /*// The invalid key should have no impact*/ -/*ddwaf::value_iterator it(&root, {}, exclude);*/ +/*ddwaf::value_iterator it(root, {}, exclude);*/ /*EXPECT_TRUE(it);*/ /*}*/ @@ -1004,7 +1004,7 @@ TEST(TestValueIterator, TestMapDepthLimitPath) /*{*/ /*// The invalid key should have no impact*/ /*std::vector key_path{"key"};*/ -/*ddwaf::value_iterator it(&root, key_path, exclude);*/ +/*ddwaf::value_iterator it(root, key_path, exclude);*/ /*EXPECT_FALSE(it);*/ /*}*/ @@ -1012,7 +1012,7 @@ TEST(TestValueIterator, TestMapDepthLimitPath) /*{*/ /*// The invalid key should have no impact*/ /*std::vector key_path{"other"};*/ -/*ddwaf::value_iterator it(&root, key_path, exclude);*/ +/*ddwaf::value_iterator it(root, key_path, exclude);*/ /*EXPECT_TRUE(it);*/ /*}*/ @@ -1030,7 +1030,7 @@ TEST(TestValueIterator, TestRecursiveMap) std::unordered_set persistent; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::value_iterator it(&root, {}, exclude); + ddwaf::value_iterator it(root, {}, exclude); EXPECT_FALSE(it); } @@ -1042,7 +1042,7 @@ TEST(TestValueIterator, TestExcludeSingleObject) std::unordered_set persistent = {&object.array[0]}; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::value_iterator it(&object, {}, exclude); + ddwaf::value_iterator it(object, {}, exclude); EXPECT_FALSE(it); @@ -1062,10 +1062,10 @@ TEST(TestValueIterator, TestExcludeMultipleObjects) std::unordered_set persistent = {&root.array[0], &array.array[1]}; exclusion::object_set_ref exclude{persistent, {}}; - ddwaf::value_iterator it(&root, {}, exclude); + ddwaf::value_iterator it(root, {}, exclude); EXPECT_TRUE(it); - EXPECT_STREQ((*it).as_unchecked(), "hello"); + EXPECT_STREQ((*it)->as_unchecked(), "hello"); auto path = it.get_current_path(); EXPECT_EQ(path.size(), 2); @@ -1089,7 +1089,7 @@ TEST(TestValueIterator, TestExcludeObjectInKeyPath) std::unordered_set persistent = {&child.array[0]}; exclusion::object_set_ref exclude{persistent, {}}; std::vector key_path{"parent", "child"}; - ddwaf::value_iterator it(&root, key_path, exclude); + ddwaf::value_iterator it(root, key_path, exclude); EXPECT_FALSE(it); @@ -1108,7 +1108,7 @@ TEST(TestValueIterator, TestExcludeRootOfKeyPath) std::unordered_set persistent = {&root.array[0]}; exclusion::object_set_ref exclude{persistent, {}}; std::vector key_path{"parent", "child"}; - ddwaf::value_iterator it(&root, key_path, exclude); + ddwaf::value_iterator it(root, key_path, exclude); EXPECT_FALSE(it);