Skip to content

Commit

Permalink
Support multiple types per matcher
Browse files Browse the repository at this point in the history
  • Loading branch information
Anilm3 committed Sep 11, 2024
1 parent d37459d commit 04a5820
Show file tree
Hide file tree
Showing 11 changed files with 73 additions and 52 deletions.
2 changes: 1 addition & 1 deletion src/condition/scalar_condition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ ResultType eval_target(Iterator &it, std::string_view address, bool ephemeral,
throw ddwaf::timeout_exception();
}

if (it.type() != matcher.supported_type()) {
if (!matcher.is_supported_type(it.type())) {
continue;
}

Expand Down
16 changes: 8 additions & 8 deletions src/matcher/base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class base {
[[nodiscard]] virtual std::string_view to_string() const = 0;

// Scalar matcher methods
[[nodiscard]] virtual DDWAF_OBJ_TYPE supported_type() const = 0;
[[nodiscard]] virtual bool is_supported_type(DDWAF_OBJ_TYPE type) const = 0;

[[nodiscard]] virtual std::pair<bool, std::string> match(const ddwaf_object &obj) const = 0;
};
Expand All @@ -54,9 +54,9 @@ template <typename T> class base_impl : public base {
return static_cast<const T *>(this)->to_string_impl();
}

[[nodiscard]] DDWAF_OBJ_TYPE supported_type() const override
[[nodiscard]] bool is_supported_type(DDWAF_OBJ_TYPE type) const override
{
return T::supported_type_impl();
return T::is_supported_type_impl(type);
}

// Helper used for testing purposes
Expand All @@ -68,31 +68,31 @@ template <typename T> class base_impl : public base {
[[nodiscard]] std::pair<bool, std::string> match(const ddwaf_object &obj) const override
{
const auto *ptr = static_cast<const T *>(this);
if constexpr (T::supported_type_impl() == DDWAF_OBJ_STRING) {
if constexpr (T::is_supported_type_impl(DDWAF_OBJ_STRING)) {
if (obj.type == DDWAF_OBJ_STRING && obj.stringValue != nullptr) {
return ptr->match_impl({obj.stringValue, static_cast<std::size_t>(obj.nbEntries)});
}
}

if constexpr (T::supported_type_impl() == DDWAF_OBJ_SIGNED) {
if constexpr (T::is_supported_type_impl(DDWAF_OBJ_SIGNED)) {
if (obj.type == DDWAF_OBJ_SIGNED) {
return ptr->match_impl(obj.intValue);
}
}

if constexpr (T::supported_type_impl() == DDWAF_OBJ_UNSIGNED) {
if constexpr (T::is_supported_type_impl(DDWAF_OBJ_UNSIGNED)) {
if (obj.type == DDWAF_OBJ_UNSIGNED) {
return ptr->match_impl(obj.uintValue);
}
}

if constexpr (T::supported_type_impl() == DDWAF_OBJ_BOOL) {
if constexpr (T::is_supported_type_impl(DDWAF_OBJ_BOOL)) {
if (obj.type == DDWAF_OBJ_BOOL) {
return ptr->match_impl(obj.boolean);
}
}

if constexpr (T::supported_type_impl() == DDWAF_OBJ_FLOAT) {
if constexpr (T::is_supported_type_impl(DDWAF_OBJ_FLOAT)) {
if (obj.type == DDWAF_OBJ_FLOAT) {
return ptr->match_impl(obj.f64);
}
Expand Down
29 changes: 17 additions & 12 deletions src/matcher/equals.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <string_view>
#include <type_traits>
#include <unordered_map>
#include <utility>

#include "matcher/base.hpp"
#include "utils.hpp"
Expand All @@ -30,29 +31,30 @@ template <typename T> class equals : public base_impl<equals<T>> {
protected:
static constexpr std::string_view to_string_impl() { return ""; }
static constexpr std::string_view name_impl() { return "equals"; }

static constexpr DDWAF_OBJ_TYPE supported_type_impl()
static constexpr bool is_supported_type_impl(DDWAF_OBJ_TYPE type)
{
if constexpr (std::is_same_v<T, int64_t>) {
return DDWAF_OBJ_SIGNED;
}
if constexpr (std::is_same_v<T, uint64_t>) {
return DDWAF_OBJ_UNSIGNED;
if constexpr (std::is_same_v<T, int64_t> || std::is_same_v<T, uint64_t>) {
return type == DDWAF_OBJ_SIGNED || type == DDWAF_OBJ_UNSIGNED;
}

if constexpr (std::is_same_v<T, bool>) {
return DDWAF_OBJ_BOOL;
return type == DDWAF_OBJ_BOOL;
}

if constexpr (std::is_same_v<T, std::string>) {
return DDWAF_OBJ_STRING;
return type == DDWAF_OBJ_STRING;
}
}

[[nodiscard]] std::pair<bool, std::string> match_impl(const T &obtained) const
template <typename U>
[[nodiscard]] std::pair<bool, std::string> match_impl(const U &obtained) const
requires(!std::is_same_v<T, std::string>)
{
return {expected_ == obtained, {}};
if constexpr (std::is_same_v<T, int64_t> || std::is_same_v<T, uint64_t>) {
return {std::cmp_equal(expected_, obtained), {}};
} else {
return {expected_ == obtained, {}};
}
}

[[nodiscard]] std::pair<bool, std::string> match_impl(std::string_view obtained) const
Expand All @@ -79,7 +81,10 @@ template <> class equals<double> : public base_impl<equals<double>> {
protected:
static constexpr std::string_view to_string_impl() { return ""; }
static constexpr std::string_view name_impl() { return "equals"; }
static constexpr DDWAF_OBJ_TYPE supported_type_impl() { return DDWAF_OBJ_FLOAT; }
static constexpr bool is_supported_type_impl(DDWAF_OBJ_TYPE type)
{
return type == DDWAF_OBJ_FLOAT;
}

[[nodiscard]] std::pair<bool, std::string> match_impl(double obtained) const
{
Expand Down
5 changes: 4 additions & 1 deletion src/matcher/exact_match.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ class exact_match : public base_impl<exact_match> {
protected:
static constexpr std::string_view to_string_impl() { return ""; }
static constexpr std::string_view name_impl() { return "exact_match"; }
static constexpr DDWAF_OBJ_TYPE supported_type_impl() { return DDWAF_OBJ_STRING; }
static constexpr bool is_supported_type_impl(DDWAF_OBJ_TYPE type)
{
return type == DDWAF_OBJ_STRING;
}

[[nodiscard]] std::pair<bool, std::string> match_impl(std::string_view str) const;

Expand Down
24 changes: 11 additions & 13 deletions src/matcher/greater_than.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <string_view>
#include <type_traits>
#include <unordered_map>
#include <utility>

#include "ddwaf.h"
#include "matcher/base.hpp"
Expand All @@ -30,25 +31,22 @@ class greater_than : public base_impl<greater_than<T>> {
protected:
static constexpr std::string_view to_string_impl() { return ""; }
static constexpr std::string_view name_impl() { return "greater_than"; }

static constexpr DDWAF_OBJ_TYPE supported_type_impl()
static constexpr bool is_supported_type_impl(DDWAF_OBJ_TYPE type)
{
if constexpr (std::is_same_v<T, int64_t>) {
return DDWAF_OBJ_SIGNED;
}
if constexpr (std::is_same_v<T, uint64_t>) {
return DDWAF_OBJ_UNSIGNED;
}
if constexpr (std::is_same_v<T, double>) {
return DDWAF_OBJ_FLOAT;
}
return type == DDWAF_OBJ_SIGNED || type == DDWAF_OBJ_UNSIGNED || type == DDWAF_OBJ_FLOAT;
}

[[nodiscard]] std::pair<bool, std::string> match_impl(const T &obtained) const
template <typename U>
[[nodiscard]] std::pair<bool, std::string> match_impl(const U &obtained) const
requires(!std::is_floating_point_v<T>)
{
return {minimum_ < obtained, {}};
return {std::cmp_greater(obtained, minimum_), {}};
}

[[nodiscard]] std::pair<bool, std::string> match_impl(double obtained) const
{
return {obtained > minimum_, {}};
}
T minimum_;

friend class base_impl<greater_than<T>>;
Expand Down
5 changes: 4 additions & 1 deletion src/matcher/ip_match.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ class ip_match : public base_impl<ip_match> {
protected:
static constexpr std::string_view to_string_impl() { return ""; }
static constexpr std::string_view name_impl() { return "ip_match"; }
static constexpr DDWAF_OBJ_TYPE supported_type_impl() { return DDWAF_OBJ_STRING; }
static constexpr bool is_supported_type_impl(DDWAF_OBJ_TYPE type)
{
return type == DDWAF_OBJ_STRING;
}

[[nodiscard]] std::pair<bool, std::string> match_impl(std::string_view str) const;

Expand Down
5 changes: 4 additions & 1 deletion src/matcher/is_sqli.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ class is_sqli : public base_impl<is_sqli> {

static constexpr std::string_view to_string_impl() { return ""; }
static constexpr std::string_view name_impl() { return "is_sqli"; }
static constexpr DDWAF_OBJ_TYPE supported_type_impl() { return DDWAF_OBJ_STRING; }
static constexpr bool is_supported_type_impl(DDWAF_OBJ_TYPE type)
{
return type == DDWAF_OBJ_STRING;
}

static std::pair<bool, std::string> match_impl(std::string_view pattern);

Expand Down
5 changes: 4 additions & 1 deletion src/matcher/is_xss.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ class is_xss : public base_impl<is_xss> {
protected:
static constexpr std::string_view to_string_impl() { return ""; }
static constexpr std::string_view name_impl() { return "is_xss"; }
static constexpr DDWAF_OBJ_TYPE supported_type_impl() { return DDWAF_OBJ_STRING; }
static constexpr bool is_supported_type_impl(DDWAF_OBJ_TYPE type)
{
return type == DDWAF_OBJ_STRING;
}

static std::pair<bool, std::string> match_impl(std::string_view pattern);

Expand Down
23 changes: 11 additions & 12 deletions src/matcher/lower_than.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <string_view>
#include <type_traits>
#include <unordered_map>
#include <utility>

#include "ddwaf.h"
#include "matcher/base.hpp"
Expand All @@ -30,23 +31,21 @@ class lower_than : public base_impl<lower_than<T>> {
protected:
static constexpr std::string_view to_string_impl() { return ""; }
static constexpr std::string_view name_impl() { return "lower_than"; }
static constexpr bool is_supported_type_impl(DDWAF_OBJ_TYPE type)
{
return type == DDWAF_OBJ_SIGNED || type == DDWAF_OBJ_UNSIGNED || type == DDWAF_OBJ_FLOAT;
}

static constexpr DDWAF_OBJ_TYPE supported_type_impl()
template <typename U>
[[nodiscard]] std::pair<bool, std::string> match_impl(const U &obtained) const
requires(!std::is_floating_point_v<T>)
{
if constexpr (std::is_same_v<T, int64_t>) {
return DDWAF_OBJ_SIGNED;
}
if constexpr (std::is_same_v<T, uint64_t>) {
return DDWAF_OBJ_UNSIGNED;
}
if constexpr (std::is_same_v<T, double>) {
return DDWAF_OBJ_FLOAT;
}
return {std::cmp_less(obtained, maximum_), {}};
}

[[nodiscard]] std::pair<bool, std::string> match_impl(const T &obtained) const
[[nodiscard]] std::pair<bool, std::string> match_impl(double obtained) const
{
return {maximum_ > obtained, {}};
return {obtained < maximum_, {}};
}

T maximum_;
Expand Down
6 changes: 5 additions & 1 deletion src/matcher/phrase_match.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <ac.h>
#include <memory>
#include <vector>

#include "matcher/base.hpp"

Expand All @@ -26,7 +27,10 @@ class phrase_match : public base_impl<phrase_match> {
protected:
static constexpr std::string_view to_string_impl() { return ""; }
static constexpr std::string_view name_impl() { return "phrase_match"; }
static constexpr DDWAF_OBJ_TYPE supported_type_impl() { return DDWAF_OBJ_STRING; }
static constexpr bool is_supported_type_impl(DDWAF_OBJ_TYPE type)
{
return type == DDWAF_OBJ_STRING;
}

[[nodiscard]] std::pair<bool, std::string> match_impl(std::string_view pattern) const;

Expand Down
5 changes: 4 additions & 1 deletion src/matcher/regex_match.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ class regex_match : public base_impl<regex_match> {
protected:
[[nodiscard]] std::string_view to_string_impl() const { return regex->pattern(); }
static constexpr std::string_view name_impl() { return "match_regex"; }
static constexpr DDWAF_OBJ_TYPE supported_type_impl() { return DDWAF_OBJ_STRING; }
static constexpr bool is_supported_type_impl(DDWAF_OBJ_TYPE type)
{
return type == DDWAF_OBJ_STRING;
}

[[nodiscard]] std::pair<bool, std::string> match_impl(std::string_view pattern) const;

Expand Down

0 comments on commit 04a5820

Please sign in to comment.