From 5d39890783223f70548bab4359efc850ef2ead63 Mon Sep 17 00:00:00 2001 From: Eduardo Arias Date: Tue, 14 May 2024 01:47:59 +0000 Subject: [PATCH 01/24] Updated Transformation::evaluate signature to allow for in-place updates, removing unnecessary heap allocated copies. - Renamed Transformation::evaluate to Transformation::transform to avoid confusion with Action's overload methods. - Updated Transformation::transform signature to receive the value by reference and perform the transformation inline, if possible. - Some transformations still need to use a temporary std::string to perform their work, and then copy the result back. - Made Transformation::transform methods const and updated Transaction parameter to be const. - Transaction parameter could not be removed because it's used by just a single transformation, UrlDecodeUni. - Removed std::string Action::evaluate(const std::string &exp, Transaction *transaction); which was only implemented by Transformation but was not used from the base class, but only after downcasting to Transformation, so it can just be declared there (and not pollute other actions with a default member implementation -that does nothing- which is never called). --- headers/modsecurity/actions/action.h | 23 ++--- headers/modsecurity/rule.h | 2 +- headers/modsecurity/rule_with_actions.h | 19 ++-- src/actions/accuracy.cc | 13 +-- src/actions/action.cc | 6 -- src/actions/chain.cc | 12 +-- src/actions/maturity.cc | 13 +-- src/actions/phase.cc | 17 ++-- src/actions/rev.cc | 13 +-- src/actions/rule_id.cc | 11 +-- src/actions/transformations/base64_decode.cc | 28 ++---- src/actions/transformations/base64_decode.h | 24 ++--- .../transformations/base64_decode_ext.cc | 28 ++---- .../transformations/base64_decode_ext.h | 24 ++--- src/actions/transformations/base64_encode.cc | 28 ++---- src/actions/transformations/base64_encode.h | 24 ++--- src/actions/transformations/cmd_line.cc | 27 ++---- src/actions/transformations/cmd_line.h | 21 +---- .../transformations/compress_whitespace.cc | 27 ++---- .../transformations/compress_whitespace.h | 24 ++--- src/actions/transformations/css_decode.cc | 29 ++---- src/actions/transformations/css_decode.h | 24 ++--- .../transformations/escape_seq_decode.cc | 31 +++---- .../transformations/escape_seq_decode.h | 26 ++---- src/actions/transformations/hex_decode.cc | 30 ++----- src/actions/transformations/hex_decode.h | 24 ++--- src/actions/transformations/hex_encode.cc | 32 +++---- src/actions/transformations/hex_encode.h | 22 +---- .../transformations/html_entity_decode.cc | 30 +++---- .../transformations/html_entity_decode.h | 25 +----- src/actions/transformations/js_decode.cc | 29 ++---- src/actions/transformations/js_decode.h | 21 +---- src/actions/transformations/length.cc | 27 ++---- src/actions/transformations/length.h | 22 +---- src/actions/transformations/lower_case.cc | 24 ++--- src/actions/transformations/lower_case.h | 24 ++--- src/actions/transformations/md5.cc | 27 ++---- src/actions/transformations/md5.h | 24 ++--- src/actions/transformations/none.cc | 25 ++---- src/actions/transformations/none.h | 21 +---- src/actions/transformations/normalise_path.cc | 32 ++----- src/actions/transformations/normalise_path.h | 22 +---- .../transformations/normalise_path_win.cc | 34 +++---- .../transformations/normalise_path_win.h | 20 +---- .../transformations/parity_even_7bit.cc | 30 ++----- .../transformations/parity_even_7bit.h | 23 ++--- .../transformations/parity_odd_7bit.cc | 29 ++---- src/actions/transformations/parity_odd_7bit.h | 23 ++--- .../transformations/parity_zero_7bit.cc | 29 ++---- .../transformations/parity_zero_7bit.h | 23 ++--- .../transformations/remove_comments.cc | 28 ++---- src/actions/transformations/remove_comments.h | 26 ++---- .../transformations/remove_comments_char.cc | 23 ++--- .../transformations/remove_comments_char.h | 21 +---- src/actions/transformations/remove_nulls.cc | 24 ++--- src/actions/transformations/remove_nulls.h | 21 +---- .../transformations/remove_whitespace.cc | 23 ++--- .../transformations/remove_whitespace.h | 21 +---- .../transformations/replace_comments.cc | 29 ++---- .../transformations/replace_comments.h | 24 ++--- src/actions/transformations/replace_nulls.cc | 22 ++--- src/actions/transformations/replace_nulls.h | 24 ++--- src/actions/transformations/sha1.cc | 26 ++---- src/actions/transformations/sha1.h | 24 ++--- src/actions/transformations/sql_hex_decode.cc | 29 ++---- src/actions/transformations/sql_hex_decode.h | 24 ++--- src/actions/transformations/transformation.cc | 90 +++++++++---------- src/actions/transformations/transformation.h | 21 ++--- src/actions/transformations/trim.cc | 31 ++----- src/actions/transformations/trim.h | 30 ++----- src/actions/transformations/trim_left.cc | 32 +++---- src/actions/transformations/trim_left.h | 25 ++---- src/actions/transformations/trim_right.cc | 31 +++---- src/actions/transformations/trim_right.h | 25 ++---- src/actions/transformations/upper_case.cc | 25 ++---- src/actions/transformations/upper_case.h | 25 ++---- src/actions/transformations/url_decode.cc | 32 +++---- src/actions/transformations/url_decode.h | 26 ++---- src/actions/transformations/url_decode_uni.cc | 33 ++----- src/actions/transformations/url_decode_uni.h | 26 ++---- src/actions/transformations/url_encode.cc | 30 ++----- src/actions/transformations/url_encode.h | 26 ++---- .../transformations/utf8_to_unicode.cc | 31 +++---- src/actions/transformations/utf8_to_unicode.h | 24 ++--- src/actions/ver.cc | 13 +-- src/engine/lua.cc | 24 +++-- src/engine/lua.h | 4 +- src/modsecurity.cc | 4 +- src/operators/validate_utf8_encoding.cc | 8 ++ src/operators/validate_utf8_encoding.h | 7 -- src/rule_with_actions.cc | 61 ++++++------- src/rule_with_operator.cc | 5 +- src/utils/string.h | 22 ++--- test/coding_style_suppressions.txt | 1 - test/unit/unit.cc | 6 +- test/unit/unit_test.cc | 14 --- 96 files changed, 644 insertions(+), 1643 deletions(-) diff --git a/headers/modsecurity/actions/action.h b/headers/modsecurity/actions/action.h index 374b77d6c6..b1839fe70f 100644 --- a/headers/modsecurity/actions/action.h +++ b/headers/modsecurity/actions/action.h @@ -13,26 +13,19 @@ * */ -#ifdef __cplusplus - -#include -#include -#include - -#endif - -#include "modsecurity/intervention.h" -#include "modsecurity/rule.h" -#include "modsecurity/rule_with_actions.h" - #ifndef HEADERS_MODSECURITY_ACTIONS_ACTION_H_ #define HEADERS_MODSECURITY_ACTIONS_ACTION_H_ #ifdef __cplusplus +#include +#include + namespace modsecurity { class Transaction; class RuleWithOperator; +class RuleWithActions; +class RuleMessage; namespace actions { @@ -74,8 +67,6 @@ class Action { virtual ~Action() { } - virtual std::string evaluate(const std::string &exp, - Transaction *transaction); virtual bool evaluate(RuleWithActions *rule, Transaction *transaction); virtual bool evaluate(RuleWithActions *rule, Transaction *transaction, std::shared_ptr ruleMessage) { @@ -87,9 +78,9 @@ class Action { void set_name_and_payload(const std::string& data) { size_t pos = data.find(":"); - std::string t = "t:"; + const char t[] = "t:"; - if (data.compare(0, t.length(), t) == 0) { + if (data.compare(0, std::size(t) - 1, t) == 0) { pos = data.find(":", 2); } diff --git a/headers/modsecurity/rule.h b/headers/modsecurity/rule.h index 1d5570a8df..18e64c0a93 100644 --- a/headers/modsecurity/rule.h +++ b/headers/modsecurity/rule.h @@ -52,7 +52,7 @@ namespace operators { class Operator; } -using TransformationResult = std::pair, +using TransformationResult = std::pair>; using TransformationResults = std::list; diff --git a/headers/modsecurity/rule_with_actions.h b/headers/modsecurity/rule_with_actions.h index 4b7db43f73..bb63f499bd 100644 --- a/headers/modsecurity/rule_with_actions.h +++ b/headers/modsecurity/rule_with_actions.h @@ -119,16 +119,7 @@ class RuleWithActions : public Rule { void executeTransformations( - Transaction *trasn, const std::string &value, TransformationResults &ret); - - inline void executeTransformation( - actions::transformations::Transformation *a, - std::shared_ptr *value, - Transaction *trans, - TransformationResults *ret, - std::string *path, - int *nth) const; - + const Transaction *trasn, const std::string &value, TransformationResults &ret); void performLogging(Transaction *trans, std::shared_ptr ruleMessage, @@ -166,6 +157,14 @@ class RuleWithActions : public Rule { RuleWithActions *m_chainedRuleParent; private: + inline void executeTransformation( + const actions::transformations::Transformation &a, + std::string &value, + const Transaction *trans, + TransformationResults *ret, + std::string *path, + int *nth) const; + /* actions */ actions::Action *m_disruptiveAction; actions::LogData *m_logData; diff --git a/src/actions/accuracy.cc b/src/actions/accuracy.cc index c8cfca72aa..ace9f1c5c4 100644 --- a/src/actions/accuracy.cc +++ b/src/actions/accuracy.cc @@ -15,16 +15,10 @@ #include "src/actions/accuracy.h" -#include -#include +#include "modsecurity/rule_with_actions.h" -#include "modsecurity/actions/action.h" -#include "modsecurity/transaction.h" -#include "modsecurity/rule.h" - -namespace modsecurity { -namespace actions { +namespace modsecurity::actions { bool Accuracy::init(std::string *error) { @@ -45,5 +39,4 @@ bool Accuracy::evaluate(RuleWithActions *rule, Transaction *transaction) { } -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions diff --git a/src/actions/action.cc b/src/actions/action.cc index e58e2067e7..dd329a509f 100644 --- a/src/actions/action.cc +++ b/src/actions/action.cc @@ -45,12 +45,6 @@ namespace modsecurity { namespace actions { -std::string Action::evaluate(const std::string &value, - Transaction *transaction) { - return value; -} - - bool Action::evaluate(RuleWithActions *rule, Transaction *transaction) { return true; } diff --git a/src/actions/chain.cc b/src/actions/chain.cc index 197f861ff2..62f0409c74 100644 --- a/src/actions/chain.cc +++ b/src/actions/chain.cc @@ -15,14 +15,9 @@ #include "src/actions/chain.h" -#include -#include +#include "modsecurity/rule_with_actions.h" -#include "modsecurity/transaction.h" -#include "modsecurity/rule.h" - -namespace modsecurity { -namespace actions { +namespace modsecurity::actions { bool Chain::evaluate(RuleWithActions *rule, Transaction *transaction) { @@ -31,5 +26,4 @@ bool Chain::evaluate(RuleWithActions *rule, Transaction *transaction) { } -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions diff --git a/src/actions/maturity.cc b/src/actions/maturity.cc index 131d2148bd..fca6aaa4aa 100644 --- a/src/actions/maturity.cc +++ b/src/actions/maturity.cc @@ -15,16 +15,10 @@ #include "src/actions/maturity.h" -#include -#include +#include "modsecurity/rule_with_actions.h" -#include "modsecurity/actions/action.h" -#include "modsecurity/transaction.h" -#include "modsecurity/rule.h" - -namespace modsecurity { -namespace actions { +namespace modsecurity::actions { bool Maturity::init(std::string *error) { @@ -45,5 +39,4 @@ bool Maturity::evaluate(RuleWithActions *rule, Transaction *transaction) { } -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions diff --git a/src/actions/phase.cc b/src/actions/phase.cc index 2e9e727786..1d17ec33c8 100644 --- a/src/actions/phase.cc +++ b/src/actions/phase.cc @@ -15,20 +15,15 @@ #include "src/actions/phase.h" -#include -#include - -#include "modsecurity/transaction.h" -#include "modsecurity/rule.h" -#include "modsecurity/modsecurity.h" +#include "modsecurity/rule_with_actions.h" #include "src/utils/string.h" -namespace modsecurity { -namespace actions { +namespace modsecurity::actions { + bool Phase::init(std::string *error) { - std::string a = utils::string::tolower(m_parser_payload); + const auto a = utils::string::tolower(m_parser_payload); m_phase = -1; try { @@ -77,5 +72,5 @@ bool Phase::evaluate(RuleWithActions *rule, Transaction *transaction) { return true; } -} // namespace actions -} // namespace modsecurity + +} // namespace modsecurity::actions diff --git a/src/actions/rev.cc b/src/actions/rev.cc index 43d8d1be46..6543a5dab1 100644 --- a/src/actions/rev.cc +++ b/src/actions/rev.cc @@ -15,16 +15,10 @@ #include "src/actions/rev.h" -#include -#include +#include "modsecurity/rule_with_actions.h" -#include "modsecurity/actions/action.h" -#include "modsecurity/transaction.h" -#include "modsecurity/rule.h" - -namespace modsecurity { -namespace actions { +namespace modsecurity::actions { bool Rev::init(std::string *error) { @@ -39,5 +33,4 @@ bool Rev::evaluate(RuleWithActions *rule, Transaction *transaction) { } -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions diff --git a/src/actions/rule_id.cc b/src/actions/rule_id.cc index d16bf63bec..c7864707b7 100644 --- a/src/actions/rule_id.cc +++ b/src/actions/rule_id.cc @@ -15,14 +15,10 @@ #include "src/actions/rule_id.h" -#include -#include +#include "modsecurity/rule_with_actions.h" -#include "modsecurity/transaction.h" -#include "modsecurity/rule.h" -namespace modsecurity { -namespace actions { +namespace modsecurity::actions { bool RuleId::init(std::string *error) { @@ -54,5 +50,4 @@ bool RuleId::evaluate(RuleWithActions *rule, Transaction *transaction) { } -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions diff --git a/src/actions/transformations/base64_decode.cc b/src/actions/transformations/base64_decode.cc index 8ddfe23525..fe910e5012 100644 --- a/src/actions/transformations/base64_decode.cc +++ b/src/actions/transformations/base64_decode.cc @@ -13,33 +13,19 @@ * */ -#include "src/actions/transformations/base64_decode.h" +#include "base64_decode.h" -#include -#include -#include -#include -#include -#include - -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/base64.h" -namespace modsecurity { -namespace actions { -namespace transformations { - +namespace modsecurity::actions::transformations { -std::string Base64Decode::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret = Utils::Base64::decode(value); - return ret; +bool Base64Decode::transform(std::string &value, const Transaction *trans) const { + if (value.empty()) return false; + value = Utils::Base64::decode(value); + return true; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/base64_decode.h b/src/actions/transformations/base64_decode.h index a82276990b..3527bd5e76 100644 --- a/src/actions/transformations/base64_decode.h +++ b/src/actions/transformations/base64_decode.h @@ -13,33 +13,21 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class Base64Decode : public Transformation { public: - explicit Base64Decode(const std::string &action) : Transformation(action) { } + explicit Base64Decode(const std::string &action) + : Transformation(action) { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_H_ diff --git a/src/actions/transformations/base64_decode_ext.cc b/src/actions/transformations/base64_decode_ext.cc index ee8e4b5b2c..e6c13987f6 100644 --- a/src/actions/transformations/base64_decode_ext.cc +++ b/src/actions/transformations/base64_decode_ext.cc @@ -13,33 +13,19 @@ * */ -#include "src/actions/transformations/base64_decode_ext.h" +#include "base64_decode_ext.h" -#include -#include -#include -#include -#include -#include - -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/base64.h" -namespace modsecurity { -namespace actions { -namespace transformations { - +namespace modsecurity::actions::transformations { -std::string Base64DecodeExt::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret = Utils::Base64::decode_forgiven(value); - return ret; +bool Base64DecodeExt::transform(std::string &value, const Transaction *trans) const { + if (value.empty()) return false; + value = Utils::Base64::decode_forgiven(value); + return true; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/base64_decode_ext.h b/src/actions/transformations/base64_decode_ext.h index ad0efbdc0e..8f1f069edb 100644 --- a/src/actions/transformations/base64_decode_ext.h +++ b/src/actions/transformations/base64_decode_ext.h @@ -13,33 +13,21 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_EXT_H_ #define SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_EXT_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class Base64DecodeExt : public Transformation { public: - explicit Base64DecodeExt(const std::string &action) : Transformation(action) { } + explicit Base64DecodeExt(const std::string &action) + : Transformation(action) { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_EXT_H_ diff --git a/src/actions/transformations/base64_encode.cc b/src/actions/transformations/base64_encode.cc index 8be748033c..bf802a1e8d 100644 --- a/src/actions/transformations/base64_encode.cc +++ b/src/actions/transformations/base64_encode.cc @@ -13,33 +13,19 @@ * */ -#include "src/actions/transformations/base64_encode.h" +#include "base64_encode.h" -#include -#include -#include -#include -#include -#include - -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/base64.h" -namespace modsecurity { -namespace actions { -namespace transformations { - +namespace modsecurity::actions::transformations { -std::string Base64Encode::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret = Utils::Base64::encode(value); - return ret; +bool Base64Encode::transform(std::string &value, const Transaction *trans) const { + if (value.empty()) return false; + value = Utils::Base64::encode(value); + return true; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/base64_encode.h b/src/actions/transformations/base64_encode.h index 0f7fd1fe53..7b3ac25ef3 100644 --- a/src/actions/transformations/base64_encode.h +++ b/src/actions/transformations/base64_encode.h @@ -13,33 +13,21 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_BASE64_ENCODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_BASE64_ENCODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class Base64Encode : public Transformation { public: - explicit Base64Encode(const std::string &action) : Transformation(action) { } + explicit Base64Encode(const std::string &action) + : Transformation(action) { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_BASE64_ENCODE_H_ diff --git a/src/actions/transformations/cmd_line.cc b/src/actions/transformations/cmd_line.cc index 72087e36b9..cac1d2df6b 100644 --- a/src/actions/transformations/cmd_line.cc +++ b/src/actions/transformations/cmd_line.cc @@ -13,26 +13,13 @@ * */ -#include "src/actions/transformations/cmd_line.h" +#include "cmd_line.h" -#include -#include -#include -#include -#include -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { - - -std::string CmdLine::evaluate(const std::string &value, - Transaction *transaction) { +bool CmdLine::transform(std::string &value, const Transaction *trans) const { std::string ret; int space = 0; @@ -77,11 +64,11 @@ std::string CmdLine::evaluate(const std::string &value, } } - return ret; + const auto changed = ret != value; + value = ret; + return changed; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/cmd_line.h b/src/actions/transformations/cmd_line.h index 851f29385f..9ba5c6b2a3 100644 --- a/src/actions/transformations/cmd_line.h +++ b/src/actions/transformations/cmd_line.h @@ -13,35 +13,22 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_CMD_LINE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_CMD_LINE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class CmdLine : public Transformation { public: explicit CmdLine(const std::string &action) : Transformation(action) { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // modsecurity::namespace actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_CMD_LINE_H_ diff --git a/src/actions/transformations/compress_whitespace.cc b/src/actions/transformations/compress_whitespace.cc index 506de2483d..32c22a258f 100644 --- a/src/actions/transformations/compress_whitespace.cc +++ b/src/actions/transformations/compress_whitespace.cc @@ -13,30 +13,18 @@ * */ -#include "src/actions/transformations/compress_whitespace.h" +#include "compress_whitespace.h" -#include -#include -#include -#include -#include -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { - CompressWhitespace::CompressWhitespace(const std::string &action) : Transformation(action) { this->action_kind = 1; } -std::string CompressWhitespace::evaluate(const std::string &value, - Transaction *transaction) { +bool CompressWhitespace::transform(std::string &value, const Transaction *trans) const { std::string a; int inWhiteSpace = 0; @@ -58,9 +46,10 @@ std::string CompressWhitespace::evaluate(const std::string &value, i++; } - return a; + const auto changed = a != value; + value = a; + return changed; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity + +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/compress_whitespace.h b/src/actions/transformations/compress_whitespace.h index 184ddcfab1..bf90b0ba20 100644 --- a/src/actions/transformations/compress_whitespace.h +++ b/src/actions/transformations/compress_whitespace.h @@ -13,34 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_COMPRESS_WHITESPACE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_COMPRESS_WHITESPACE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class CompressWhitespace : public Transformation { public: + explicit CompressWhitespace(const std::string &action); - explicit CompressWhitespace(const std::string &action) ; - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_COMPRESS_WHITESPACE_H_ diff --git a/src/actions/transformations/css_decode.cc b/src/actions/transformations/css_decode.cc index f808512385..7f6938acf4 100644 --- a/src/actions/transformations/css_decode.cc +++ b/src/actions/transformations/css_decode.cc @@ -13,29 +13,15 @@ * */ -#include "src/actions/transformations/css_decode.h" +#include "css_decode.h" -#include - -#include -#include -#include -#include -#include -#include - -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/string.h" -namespace modsecurity { -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { -std::string CssDecode::evaluate(const std::string &value, - Transaction *transaction) { +bool CssDecode::transform(std::string &value, const Transaction *trans) const { char *tmp = reinterpret_cast( malloc(sizeof(char) * value.size() + 1)); @@ -47,7 +33,10 @@ std::string CssDecode::evaluate(const std::string &value, std::string ret(tmp, 0, value.size()); free(tmp); - return ret; + + const auto changed = ret != value; + value = ret; + return changed; } @@ -191,6 +180,4 @@ int CssDecode::css_decode_inplace(unsigned char *input, int64_t input_len) { } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/css_decode.h b/src/actions/transformations/css_decode.h index a6769bad39..0441814952 100644 --- a/src/actions/transformations/css_decode.h +++ b/src/actions/transformations/css_decode.h @@ -13,37 +13,23 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_CSS_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_CSS_DECODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; - -namespace actions { -namespace transformations { +#include "transformation.h" +namespace modsecurity::actions::transformations { class CssDecode : public Transformation { public: explicit CssDecode(const std::string &action) : Transformation(action) { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + + bool transform(std::string &value, const Transaction *trans) const override; static int css_decode_inplace(unsigned char *input, int64_t input_len); }; - -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_CSS_DECODE_H_ diff --git a/src/actions/transformations/escape_seq_decode.cc b/src/actions/transformations/escape_seq_decode.cc index 03303272ef..a0dccb5393 100644 --- a/src/actions/transformations/escape_seq_decode.cc +++ b/src/actions/transformations/escape_seq_decode.cc @@ -13,23 +13,12 @@ * */ -#include "src/actions/transformations/escape_seq_decode.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +#include "escape_seq_decode.h" + #include "src/utils/string.h" -namespace modsecurity { -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { + EscapeSeqDecode::EscapeSeqDecode(const std::string &action) : Transformation(action) { @@ -140,8 +129,7 @@ int EscapeSeqDecode::ansi_c_sequences_decode_inplace(unsigned char *input, } -std::string EscapeSeqDecode::evaluate(const std::string &value, - Transaction *transaction) { +bool EscapeSeqDecode::transform(std::string &value, const Transaction *trans) const { unsigned char *tmp = (unsigned char *) malloc(sizeof(char) * value.size() + 1); @@ -154,9 +142,10 @@ std::string EscapeSeqDecode::evaluate(const std::string &value, ret.assign(reinterpret_cast(tmp), size); free(tmp); - return ret; + const auto changed = ret != value; + value = ret; + return changed; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity + +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/escape_seq_decode.h b/src/actions/transformations/escape_seq_decode.h index d68f33b56f..ab66464d6b 100644 --- a/src/actions/transformations/escape_seq_decode.h +++ b/src/actions/transformations/escape_seq_decode.h @@ -13,35 +13,21 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_ESCAPE_SEQ_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_ESCAPE_SEQ_DECODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class EscapeSeqDecode : public Transformation { public: + explicit EscapeSeqDecode(const std::string &action); - explicit EscapeSeqDecode(const std::string &action) ; - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; - int ansi_c_sequences_decode_inplace(unsigned char *input, int input_len); + bool transform(std::string &value, const Transaction *trans) const override; + static int ansi_c_sequences_decode_inplace(unsigned char *input, int input_len); }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_ESCAPE_SEQ_DECODE_H_ diff --git a/src/actions/transformations/hex_decode.cc b/src/actions/transformations/hex_decode.cc index 1525377cbe..5866079bd6 100644 --- a/src/actions/transformations/hex_decode.cc +++ b/src/actions/transformations/hex_decode.cc @@ -13,27 +13,15 @@ * */ -#include "src/actions/transformations/hex_decode.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +#include "hex_decode.h" + #include "src/utils/string.h" -namespace modsecurity { -namespace actions { -namespace transformations { + +namespace modsecurity::actions::transformations { -std::string HexDecode::evaluate(const std::string &value, - Transaction *transaction) { +bool HexDecode::transform(std::string &value, const Transaction *trans) const { std::string ret; unsigned char *input; int size = 0; @@ -52,7 +40,9 @@ std::string HexDecode::evaluate(const std::string &value, ret.assign(reinterpret_cast(input), size); free(input); - return ret; + const auto changed = ret != value; + value = ret; + return changed; } @@ -74,6 +64,4 @@ int HexDecode::inplace(unsigned char *data, int len) { } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/hex_decode.h b/src/actions/transformations/hex_decode.h index a2f48c6d8f..4239c86d09 100644 --- a/src/actions/transformations/hex_decode.h +++ b/src/actions/transformations/hex_decode.h @@ -13,35 +13,23 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_HEX_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_HEX_DECODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class HexDecode : public Transformation { public: - explicit HexDecode(const std::string &action) : Transformation(action) { } + explicit HexDecode(const std::string &action) + : Transformation(action) { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; static int inplace(unsigned char *data, int len); }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_HEX_DECODE_H_ diff --git a/src/actions/transformations/hex_encode.cc b/src/actions/transformations/hex_encode.cc index 4e6121df60..a07197263f 100644 --- a/src/actions/transformations/hex_encode.cc +++ b/src/actions/transformations/hex_encode.cc @@ -13,41 +13,29 @@ * */ -#include "src/actions/transformations/hex_encode.h" +#include "hex_encode.h" -#include -#include -#include -#include -#include -#include -#include +#include "modsecurity/rule_with_actions.h" -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" - -namespace modsecurity { -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { HexEncode::HexEncode(const std::string &action) : Transformation(action) { this->action_kind = 1; } -std::string HexEncode::evaluate(const std::string &value, - Transaction *transaction) { +bool HexEncode::transform(std::string &value, const Transaction *trans) const { + if (value.empty()) return false; std::stringstream result; - for (std::size_t i=0; i < value.length(); i++) { - unsigned int ii = (unsigned char)(value[i]); + for (const auto c : value) { + unsigned int ii = (unsigned char)c; result << std::setw(2) << std::setfill('0') << std::hex << ii; } - return result.str(); + value = result.str(); + return true; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/hex_encode.h b/src/actions/transformations/hex_encode.h index 1ba39c56a1..3bb744b5cb 100644 --- a/src/actions/transformations/hex_encode.h +++ b/src/actions/transformations/hex_encode.h @@ -13,34 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_HEX_ENCODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_HEX_ENCODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class HexEncode : public Transformation { public: - explicit HexEncode(const std::string &action); - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_HEX_ENCODE_H_ diff --git a/src/actions/transformations/html_entity_decode.cc b/src/actions/transformations/html_entity_decode.cc index 6a68324564..a730f1604f 100644 --- a/src/actions/transformations/html_entity_decode.cc +++ b/src/actions/transformations/html_entity_decode.cc @@ -13,32 +13,21 @@ * */ -#include "src/actions/transformations/html_entity_decode.h" +#include "html_entity_decode.h" -#include +#include -#include -#include -#include -#include -#include -#include - -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +#include "src/utils/string.h" #ifdef WIN32 #include "src/compat/msvc.h" #endif -namespace modsecurity { -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { -std::string HtmlEntityDecode::evaluate(const std::string &value, - Transaction *transaction) { +bool HtmlEntityDecode::transform(std::string &value, const Transaction *trans) const { std::string ret; unsigned char *input; @@ -56,7 +45,9 @@ std::string HtmlEntityDecode::evaluate(const std::string &value, ret.assign(reinterpret_cast(input), i); free(input); - return ret; + const auto changed = ret != value; + value = ret; + return changed; } @@ -207,6 +198,5 @@ int HtmlEntityDecode::inplace(unsigned char *input, uint64_t input_len) { return count; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity + +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/html_entity_decode.h b/src/actions/transformations/html_entity_decode.h index 44fcc32319..558da5b975 100644 --- a/src/actions/transformations/html_entity_decode.h +++ b/src/actions/transformations/html_entity_decode.h @@ -13,40 +13,23 @@ * */ -#include -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" -#include "src/utils/string.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_HTML_ENTITY_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_HTML_ENTITY_DECODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; - -namespace actions { -namespace transformations { +#include "transformation.h" +namespace modsecurity::actions::transformations { class HtmlEntityDecode : public Transformation { public: explicit HtmlEntityDecode(const std::string &action) : Transformation(action) { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; static int inplace(unsigned char *input, uint64_t input_len); }; - -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_HTML_ENTITY_DECODE_H_ diff --git a/src/actions/transformations/js_decode.cc b/src/actions/transformations/js_decode.cc index 2f4cf8bb57..5ed5715768 100644 --- a/src/actions/transformations/js_decode.cc +++ b/src/actions/transformations/js_decode.cc @@ -13,29 +13,15 @@ * */ -#include "src/actions/transformations/js_decode.h" +#include "js_decode.h" -#include - -#include -#include -#include -#include -#include -#include - -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/string.h" -namespace modsecurity { -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { -std::string JsDecode::evaluate(const std::string &value, - Transaction *transaction) { +bool JsDecode::transform(std::string &value, const Transaction *trans) const { std::string ret; unsigned char *input; @@ -53,7 +39,9 @@ std::string JsDecode::evaluate(const std::string &value, ret.assign(reinterpret_cast(input), i); free(input); - return ret; + const auto changed = ret != value; + value = ret; + return changed; } @@ -163,6 +151,5 @@ int JsDecode::inplace(unsigned char *input, uint64_t input_len) { return count; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity + +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/js_decode.h b/src/actions/transformations/js_decode.h index 60d6617b35..b91ab9b83f 100644 --- a/src/actions/transformations/js_decode.h +++ b/src/actions/transformations/js_decode.h @@ -13,35 +13,22 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_JS_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_JS_DECODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class JsDecode : public Transformation { public: explicit JsDecode(const std::string &action) : Transformation(action) { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; static int inplace(unsigned char *input, uint64_t input_len); }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_JS_DECODE_H_ diff --git a/src/actions/transformations/length.cc b/src/actions/transformations/length.cc index 61015b82bf..10aadfe8ce 100644 --- a/src/actions/transformations/length.cc +++ b/src/actions/transformations/length.cc @@ -13,34 +13,21 @@ * */ -#include "src/actions/transformations/length.h" +#include "length.h" -#include -#include -#include -#include -#include -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { - Length::Length(const std::string &action) : Transformation(action) { this->action_kind = 1; } -std::string Length::evaluate(const std::string &value, - Transaction *transaction) { - - return std::to_string(value.size()); +bool Length::transform(std::string &value, const Transaction *trans) const { + value = std::to_string(value.size()); + return true; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity + +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/length.h b/src/actions/transformations/length.h index 8892a9dcd2..e7b6b0816d 100644 --- a/src/actions/transformations/length.h +++ b/src/actions/transformations/length.h @@ -13,34 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_LENGTH_H_ #define SRC_ACTIONS_TRANSFORMATIONS_LENGTH_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class Length : public Transformation { public: - explicit Length(const std::string &action); - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_LENGTH_H_ diff --git a/src/actions/transformations/lower_case.cc b/src/actions/transformations/lower_case.cc index 7bca947972..0ea1864c2c 100644 --- a/src/actions/transformations/lower_case.cc +++ b/src/actions/transformations/lower_case.cc @@ -13,27 +13,20 @@ * */ -#include "src/actions/transformations/lower_case.h" -#include -#include +#include "lower_case.h" + #include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" -#include "modsecurity/actions/action.h" -namespace modsecurity { -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { LowerCase::LowerCase(const std::string &a) : Transformation(a) { } -std::string LowerCase::evaluate(const std::string &val, - Transaction *transaction) { +bool LowerCase::transform(std::string &val, const Transaction *trans) const { std::locale loc; std::string value(val); @@ -41,9 +34,10 @@ std::string LowerCase::evaluate(const std::string &val, value[i] = std::tolower(value[i], loc); } - return value; + const auto changed = val != value; + val = value; + return changed; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity + +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/lower_case.h b/src/actions/transformations/lower_case.h index 590498405b..bbb51272f1 100644 --- a/src/actions/transformations/lower_case.h +++ b/src/actions/transformations/lower_case.h @@ -13,34 +13,20 @@ * */ -#include -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_LOWER_CASE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_LOWER_CASE_H_ -#ifdef __cplusplus - -namespace modsecurity { -class Transaction; -namespace actions { -namespace transformations { +#include "transformation.h" +namespace modsecurity::actions::transformations { class LowerCase : public Transformation { public: explicit LowerCase(const std::string &action); - std::string evaluate(const std::string &exp, - Transaction *transaction) override; -}; -} // namespace transformations -} // namespace actions -} // namespace modsecurity + bool transform(std::string &value, const Transaction *trans) const override; +}; -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_LOWER_CASE_H_ diff --git a/src/actions/transformations/md5.cc b/src/actions/transformations/md5.cc index 71c36bc300..b1cdc93ece 100644 --- a/src/actions/transformations/md5.cc +++ b/src/actions/transformations/md5.cc @@ -13,32 +13,17 @@ * */ -#include "src/actions/transformations/md5.h" +#include "md5.h" -#include -#include -#include -#include -#include -#include - -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/md5.h" -namespace modsecurity { -namespace actions { -namespace transformations { - +namespace modsecurity::actions::transformations { -std::string Md5::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret = Utils::Md5::digest(value); - return ret; +bool Md5::transform(std::string &value, const Transaction *trans) const { + value = Utils::Md5::digest(value); + return true; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/md5.h b/src/actions/transformations/md5.h index 37f22473fa..9d5a15f881 100644 --- a/src/actions/transformations/md5.h +++ b/src/actions/transformations/md5.h @@ -13,33 +13,21 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_MD5_H_ #define SRC_ACTIONS_TRANSFORMATIONS_MD5_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class Md5 : public Transformation { public: - explicit Md5(const std::string &action) : Transformation(action) { } + explicit Md5(const std::string &action) + : Transformation(action) { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_MD5_H_ diff --git a/src/actions/transformations/none.cc b/src/actions/transformations/none.cc index f122bf035c..adbf32a606 100644 --- a/src/actions/transformations/none.cc +++ b/src/actions/transformations/none.cc @@ -13,30 +13,15 @@ * */ -#include "src/actions/transformations/none.h" +#include "none.h" -#include -#include -#include -#include -#include -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { - - -std::string None::evaluate(const std::string &value, - Transaction *transaction) { - return value; +bool None::transform(std::string &value, const Transaction *trans) const { + return false; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/none.h b/src/actions/transformations/none.h index e8a0e9d956..2fe428bb00 100644 --- a/src/actions/transformations/none.h +++ b/src/actions/transformations/none.h @@ -13,20 +13,12 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_NONE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_NONE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class None : public Transformation { public: @@ -34,14 +26,9 @@ class None : public Transformation { : Transformation(action) { m_isNone = true; } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_NONE_H_ diff --git a/src/actions/transformations/normalise_path.cc b/src/actions/transformations/normalise_path.cc index e75b984986..c663b98a6f 100644 --- a/src/actions/transformations/normalise_path.cc +++ b/src/actions/transformations/normalise_path.cc @@ -13,33 +13,19 @@ * */ -#include "src/actions/transformations/normalise_path.h" +#include "normalise_path.h" -#include -#include -#include -#include -#include -#include -#include +namespace modsecurity::actions::transformations { -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" - - -namespace modsecurity { -namespace actions { -namespace transformations { NormalisePath::NormalisePath(const std::string &action) : Transformation(action) { this->action_kind = 1; } -std::string NormalisePath::evaluate(const std::string &value, - Transaction *transaction) { - int changed = 0; +bool NormalisePath::transform(std::string &value, const Transaction *trans) const { + int _changed = 0; char *tmp = reinterpret_cast( malloc(sizeof(char) * value.size() + 1)); @@ -47,13 +33,15 @@ std::string NormalisePath::evaluate(const std::string &value, tmp[value.size()] = '\0'; int i = normalize_path_inplace((unsigned char *)tmp, - value.size(), 0, &changed); + value.size(), 0, &_changed); std::string ret(""); ret.assign(tmp, i); free(tmp); - return ret; + const auto changed = ret != value; + value = ret; + return changed; } @@ -223,6 +211,4 @@ int NormalisePath::normalize_path_inplace(unsigned char *input, int input_len, } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/normalise_path.h b/src/actions/transformations/normalise_path.h index b3869bea04..d5b84085d6 100644 --- a/src/actions/transformations/normalise_path.h +++ b/src/actions/transformations/normalise_path.h @@ -13,37 +13,23 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_H_ #define SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class NormalisePath : public Transformation { public: - explicit NormalisePath(const std::string &action); - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; static int normalize_path_inplace(unsigned char *input, int input_len, int win, int *changed); }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_H_ diff --git a/src/actions/transformations/normalise_path_win.cc b/src/actions/transformations/normalise_path_win.cc index 6c171a59c4..49f6989fc0 100644 --- a/src/actions/transformations/normalise_path_win.cc +++ b/src/actions/transformations/normalise_path_win.cc @@ -13,30 +13,16 @@ * */ -#include "src/actions/transformations/normalise_path_win.h" +#include "normalise_path_win.h" -#include +#include "normalise_path.h" -#include -#include -#include -#include -#include -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" -#include "src/actions/transformations/normalise_path.h" +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { - - -std::string NormalisePathWin::evaluate(const std::string &value, - Transaction *transaction) { - int changed; +bool NormalisePathWin::transform(std::string &value, const Transaction *trans) const { + int _changed; char *tmp = reinterpret_cast( malloc(sizeof(char) * value.size() + 1)); @@ -45,16 +31,16 @@ std::string NormalisePathWin::evaluate(const std::string &value, int i = NormalisePath::normalize_path_inplace( reinterpret_cast(tmp), - value.size(), 1, &changed); + value.size(), 1, &_changed); std::string ret(""); ret.assign(tmp, i); free(tmp); - return ret; + const auto changed = ret != value; + value = ret; + return changed; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/normalise_path_win.h b/src/actions/transformations/normalise_path_win.h index a1f8c5f746..af312693e6 100644 --- a/src/actions/transformations/normalise_path_win.h +++ b/src/actions/transformations/normalise_path_win.h @@ -13,33 +13,21 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_WIN_H_ #define SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_WIN_H_ +#include "transformation.h" -namespace modsecurity { -class Transaction; - -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class NormalisePathWin : public Transformation { public: explicit NormalisePathWin(const std::string &action) : Transformation(action) { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_WIN_H_ diff --git a/src/actions/transformations/parity_even_7bit.cc b/src/actions/transformations/parity_even_7bit.cc index 2c0be31cd4..f299224094 100644 --- a/src/actions/transformations/parity_even_7bit.cc +++ b/src/actions/transformations/parity_even_7bit.cc @@ -13,28 +13,17 @@ * */ -#include "src/actions/transformations/parity_even_7bit.h" - -#include -#include -#include -#include -#include -#include +#include "parity_even_7bit.h" + #include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { +bool ParityEven7bit::transform(std::string &value, const Transaction *trans) const { + if (value.empty()) return false; -std::string ParityEven7bit::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; unsigned char *input; input = reinterpret_cast @@ -46,9 +35,9 @@ std::string ParityEven7bit::evaluate(const std::string &value, std::memcpy(input, value.c_str(), value.length()+1); - inplace(input, value.length()); + const auto ret = inplace(input, value.length()); - ret.assign(reinterpret_cast(input), value.length()); + value.assign(reinterpret_cast(input), value.length()); free(input); return ret; @@ -76,7 +65,4 @@ bool ParityEven7bit::inplace(unsigned char *input, uint64_t input_len) { } - -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/parity_even_7bit.h b/src/actions/transformations/parity_even_7bit.h index 08aa88230a..41010d6255 100644 --- a/src/actions/transformations/parity_even_7bit.h +++ b/src/actions/transformations/parity_even_7bit.h @@ -13,33 +13,22 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_PARITY_EVEN_7BIT_H_ #define SRC_ACTIONS_TRANSFORMATIONS_PARITY_EVEN_7BIT_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class ParityEven7bit : public Transformation { public: - explicit ParityEven7bit(const std::string &action) : Transformation(action) { } + explicit ParityEven7bit(const std::string &action) + : Transformation(action) { } - std::string evaluate(const std::string &exp, Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; static bool inplace(unsigned char *input, uint64_t input_len); }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_PARITY_EVEN_7BIT_H_ diff --git a/src/actions/transformations/parity_odd_7bit.cc b/src/actions/transformations/parity_odd_7bit.cc index 5ac38d20dc..f8192ef306 100644 --- a/src/actions/transformations/parity_odd_7bit.cc +++ b/src/actions/transformations/parity_odd_7bit.cc @@ -13,28 +13,17 @@ * */ -#include "src/actions/transformations/parity_odd_7bit.h" - -#include -#include -#include -#include -#include -#include +#include "parity_odd_7bit.h" + #include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { +bool ParityOdd7bit::transform(std::string &value, const Transaction *trans) const { + if (value.empty()) return false; -std::string ParityOdd7bit::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; unsigned char *input; input = reinterpret_cast @@ -46,9 +35,9 @@ std::string ParityOdd7bit::evaluate(const std::string &value, memcpy(input, value.c_str(), value.length()+1); - inplace(input, value.length()); + const auto ret = inplace(input, value.length()); - ret.assign(reinterpret_cast(input), value.length()); + value.assign(reinterpret_cast(input), value.length()); free(input); return ret; @@ -76,6 +65,4 @@ bool ParityOdd7bit::inplace(unsigned char *input, uint64_t input_len) { } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/parity_odd_7bit.h b/src/actions/transformations/parity_odd_7bit.h index 8b7e34d289..1afa13275e 100644 --- a/src/actions/transformations/parity_odd_7bit.h +++ b/src/actions/transformations/parity_odd_7bit.h @@ -13,33 +13,22 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_PARITY_ODD_7BIT_H_ #define SRC_ACTIONS_TRANSFORMATIONS_PARITY_ODD_7BIT_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class ParityOdd7bit : public Transformation { public: - explicit ParityOdd7bit(const std::string &action) : Transformation(action) { } + explicit ParityOdd7bit(const std::string &action) + : Transformation(action) { } - std::string evaluate(const std::string &exp, Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; static bool inplace(unsigned char *input, uint64_t input_len); }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_PARITY_ODD_7BIT_H_ diff --git a/src/actions/transformations/parity_zero_7bit.cc b/src/actions/transformations/parity_zero_7bit.cc index 7bb846362c..ef80b74d88 100644 --- a/src/actions/transformations/parity_zero_7bit.cc +++ b/src/actions/transformations/parity_zero_7bit.cc @@ -13,28 +13,17 @@ * */ -#include "src/actions/transformations/parity_zero_7bit.h" - -#include -#include -#include -#include -#include -#include +#include "parity_zero_7bit.h" + #include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { +bool ParityZero7bit::transform(std::string &value, const Transaction *trans) const { + if (value.empty()) return false; -std::string ParityZero7bit::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; unsigned char *input; input = reinterpret_cast @@ -46,9 +35,9 @@ std::string ParityZero7bit::evaluate(const std::string &value, memcpy(input, value.c_str(), value.length()+1); - inplace(input, value.length()); + const auto ret = inplace(input, value.length()); - ret.assign(reinterpret_cast(input), value.length()); + value.assign(reinterpret_cast(input), value.length()); free(input); return ret; @@ -68,6 +57,4 @@ bool ParityZero7bit::inplace(unsigned char *input, uint64_t input_len) { } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/parity_zero_7bit.h b/src/actions/transformations/parity_zero_7bit.h index 4b4ccd23e1..af47f7c5f3 100644 --- a/src/actions/transformations/parity_zero_7bit.h +++ b/src/actions/transformations/parity_zero_7bit.h @@ -13,33 +13,22 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_PARITY_ZERO_7BIT_H_ #define SRC_ACTIONS_TRANSFORMATIONS_PARITY_ZERO_7BIT_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class ParityZero7bit : public Transformation { public: - explicit ParityZero7bit(const std::string &action) : Transformation(action) { } + explicit ParityZero7bit(const std::string &action) + : Transformation(action) { } - std::string evaluate(const std::string &exp, Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; static bool inplace(unsigned char *input, uint64_t input_len); }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_PARITY_ZERO_7BIT_H_ diff --git a/src/actions/transformations/remove_comments.cc b/src/actions/transformations/remove_comments.cc index 043dd9505a..1515675c52 100644 --- a/src/actions/transformations/remove_comments.cc +++ b/src/actions/transformations/remove_comments.cc @@ -13,27 +13,13 @@ * */ -#include "src/actions/transformations/remove_comments.h" +#include "remove_comments.h" -#include -#include -#include -#include -#include -#include -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { - - -std::string RemoveComments::evaluate(const std::string &value, - Transaction *transaction) { +bool RemoveComments::transform(std::string &value, const Transaction *trans) const { std::string ret; unsigned char *input; @@ -103,10 +89,10 @@ std::string RemoveComments::evaluate(const std::string &value, ret.assign(reinterpret_cast(input), j); free(input); - return ret; + const auto changed = ret != value; + value = ret; + return changed; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/remove_comments.h b/src/actions/transformations/remove_comments.h index 78dd213d69..67f0ff5b7c 100644 --- a/src/actions/transformations/remove_comments.h +++ b/src/actions/transformations/remove_comments.h @@ -13,35 +13,21 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_H_ #define SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; - -namespace actions { -namespace transformations { +#include "transformation.h" +namespace modsecurity::actions::transformations { class RemoveComments : public Transformation { public: - explicit RemoveComments(const std::string &action) : Transformation(action) { } + explicit RemoveComments(const std::string &action) + : Transformation(action) { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; - -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_H_ diff --git a/src/actions/transformations/remove_comments_char.cc b/src/actions/transformations/remove_comments_char.cc index 4c54e68aa7..7a4763d332 100644 --- a/src/actions/transformations/remove_comments_char.cc +++ b/src/actions/transformations/remove_comments_char.cc @@ -13,25 +13,17 @@ * */ -#include "src/actions/transformations/remove_comments_char.h" +#include "remove_comments_char.h" -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" - - -namespace modsecurity { -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { RemoveCommentsChar::RemoveCommentsChar(const std::string &action) : Transformation(action) { this->action_kind = 1; } -std::string RemoveCommentsChar::evaluate(const std::string &val, - Transaction *transaction) { +bool RemoveCommentsChar::transform(std::string &val, const Transaction *trans) const { size_t i = 0; std::string transformed_value; transformed_value.reserve(val.size()); @@ -65,10 +57,11 @@ std::string RemoveCommentsChar::evaluate(const std::string &val, i++; } } - return transformed_value; + + const auto changed = transformed_value != val; + val = transformed_value; + return changed; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/remove_comments_char.h b/src/actions/transformations/remove_comments_char.h index 722aba5926..2066fd6535 100644 --- a/src/actions/transformations/remove_comments_char.h +++ b/src/actions/transformations/remove_comments_char.h @@ -13,33 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_CHAR_H_ #define SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_CHAR_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class RemoveCommentsChar : public Transformation { public: explicit RemoveCommentsChar(const std::string &action); - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_CHAR_H_ diff --git a/src/actions/transformations/remove_nulls.cc b/src/actions/transformations/remove_nulls.cc index 2d479c73eb..bda34bbeeb 100644 --- a/src/actions/transformations/remove_nulls.cc +++ b/src/actions/transformations/remove_nulls.cc @@ -13,23 +13,13 @@ * */ -#include "src/actions/transformations/remove_nulls.h" +#include "remove_nulls.h" -#include -#include +namespace modsecurity::actions::transformations { -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" - -namespace modsecurity { -namespace actions { -namespace transformations { - - -std::string RemoveNulls::evaluate(const std::string &val, - Transaction *transaction) { +bool RemoveNulls::transform(std::string &val, const Transaction *trans) const { size_t i = 0; std::string transformed_value; transformed_value.reserve(val.size()); @@ -43,10 +33,10 @@ std::string RemoveNulls::evaluate(const std::string &val, i++; } - return transformed_value; + const auto changed = transformed_value != val; + val = transformed_value; + return changed; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/remove_nulls.h b/src/actions/transformations/remove_nulls.h index eeb33b363f..56df24c831 100644 --- a/src/actions/transformations/remove_nulls.h +++ b/src/actions/transformations/remove_nulls.h @@ -13,34 +13,21 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_REMOVE_NULLS_H_ #define SRC_ACTIONS_TRANSFORMATIONS_REMOVE_NULLS_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class RemoveNulls : public Transformation { public: explicit RemoveNulls(const std::string &action) : Transformation(action) { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_REMOVE_NULLS_H_ diff --git a/src/actions/transformations/remove_whitespace.cc b/src/actions/transformations/remove_whitespace.cc index 3796466385..8cee80c968 100644 --- a/src/actions/transformations/remove_whitespace.cc +++ b/src/actions/transformations/remove_whitespace.cc @@ -13,25 +13,17 @@ * */ -#include "src/actions/transformations/remove_whitespace.h" +#include "remove_whitespace.h" -#include +namespace modsecurity::actions::transformations { -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" - - -namespace modsecurity { -namespace actions { -namespace transformations { RemoveWhitespace::RemoveWhitespace(const std::string &action) : Transformation(action) { this->action_kind = 1; } -std::string RemoveWhitespace::evaluate(const std::string &val, - Transaction *transaction) { +bool RemoveWhitespace::transform(std::string &val, const Transaction *trans) const { std::string transformed_value; transformed_value.reserve(val.size()); @@ -52,10 +44,11 @@ std::string RemoveWhitespace::evaluate(const std::string &val, i++; } - return transformed_value; + const auto changed = transformed_value != val; + val = transformed_value; + return changed; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity + +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/remove_whitespace.h b/src/actions/transformations/remove_whitespace.h index f977914cb0..a9925f8e74 100644 --- a/src/actions/transformations/remove_whitespace.h +++ b/src/actions/transformations/remove_whitespace.h @@ -13,33 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_REMOVE_WHITESPACE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_REMOVE_WHITESPACE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class RemoveWhitespace : public Transformation { public: explicit RemoveWhitespace(const std::string &action); - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_REMOVE_WHITESPACE_H_ diff --git a/src/actions/transformations/replace_comments.cc b/src/actions/transformations/replace_comments.cc index 77e3e3b700..b1aeecf908 100644 --- a/src/actions/transformations/replace_comments.cc +++ b/src/actions/transformations/replace_comments.cc @@ -13,31 +13,19 @@ * */ -#include "src/actions/transformations/replace_comments.h" +#include "replace_comments.h" -#include -#include -#include -#include -#include -#include -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { - ReplaceComments::ReplaceComments(const std::string &action) : Transformation(action) { this->action_kind = 1; } -std::string ReplaceComments::evaluate(const std::string &value, - Transaction *transaction) { + +bool ReplaceComments::transform(std::string &value, const Transaction *trans) const { uint64_t i, j, incomment; char *input = reinterpret_cast( @@ -80,9 +68,10 @@ std::string ReplaceComments::evaluate(const std::string &value, free(input); - return resp; + const auto changed = resp != value; + value = resp; + return changed; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity + +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/replace_comments.h b/src/actions/transformations/replace_comments.h index 6808f426c1..95e5e8540d 100644 --- a/src/actions/transformations/replace_comments.h +++ b/src/actions/transformations/replace_comments.h @@ -13,34 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_REPLACE_COMMENTS_H_ #define SRC_ACTIONS_TRANSFORMATIONS_REPLACE_COMMENTS_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class ReplaceComments : public Transformation { public: + explicit ReplaceComments(const std::string &action); - explicit ReplaceComments(const std::string &action) ; - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_REPLACE_COMMENTS_H_ diff --git a/src/actions/transformations/replace_nulls.cc b/src/actions/transformations/replace_nulls.cc index 1af860f4e8..c59ceb87f3 100644 --- a/src/actions/transformations/replace_nulls.cc +++ b/src/actions/transformations/replace_nulls.cc @@ -13,25 +13,17 @@ * */ -#include "src/actions/transformations/replace_nulls.h" +#include "replace_nulls.h" -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" - - -namespace modsecurity { -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { ReplaceNulls::ReplaceNulls(const std::string &action) : Transformation(action) { this->action_kind = 1; } -std::string ReplaceNulls::evaluate(const std::string &val, - Transaction *transaction) { +bool ReplaceNulls::transform(std::string &val, const Transaction *trans) const { int64_t i; std::string value(val); @@ -44,9 +36,9 @@ std::string ReplaceNulls::evaluate(const std::string &val, } } - return value; + const auto changed = val != value; + val = value; + return changed; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/replace_nulls.h b/src/actions/transformations/replace_nulls.h index 8e2d315fc5..ad206ae40b 100644 --- a/src/actions/transformations/replace_nulls.h +++ b/src/actions/transformations/replace_nulls.h @@ -13,34 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_REPLACE_NULLS_H_ #define SRC_ACTIONS_TRANSFORMATIONS_REPLACE_NULLS_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class ReplaceNulls : public Transformation { public: + explicit ReplaceNulls(const std::string &action); - explicit ReplaceNulls(const std::string &action) ; - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_REPLACE_NULLS_H_ diff --git a/src/actions/transformations/sha1.cc b/src/actions/transformations/sha1.cc index 9e0c7f53e7..af1eda415f 100644 --- a/src/actions/transformations/sha1.cc +++ b/src/actions/transformations/sha1.cc @@ -13,35 +13,21 @@ * */ -#include "src/actions/transformations/sha1.h" +#include "sha1.h" -#include -#include -#include -#include -#include -#include - -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/sha1.h" -namespace modsecurity { -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { Sha1::Sha1(const std::string &action) : Transformation(action) { this->action_kind = 1; } -std::string Sha1::evaluate(const std::string &value, - Transaction *transaction) { - - return Utils::Sha1::digest(value); +bool Sha1::transform(std::string &value, const Transaction *trans) const { + value = Utils::Sha1::digest(value); + return true; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/sha1.h b/src/actions/transformations/sha1.h index eb5fb3f135..263ed97879 100644 --- a/src/actions/transformations/sha1.h +++ b/src/actions/transformations/sha1.h @@ -13,32 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_SHA1_H_ #define SRC_ACTIONS_TRANSFORMATIONS_SHA1_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class Sha1 : public Transformation { public: - explicit Sha1(const std::string &action) ; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; -}; + explicit Sha1(const std::string &action); -} // namespace transformations -} // namespace actions -} // namespace modsecurity + bool transform(std::string &value, const Transaction *trans) const override; +}; -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_SHA1_H_ diff --git a/src/actions/transformations/sql_hex_decode.cc b/src/actions/transformations/sql_hex_decode.cc index 8c8805ff67..41189f9272 100644 --- a/src/actions/transformations/sql_hex_decode.cc +++ b/src/actions/transformations/sql_hex_decode.cc @@ -13,24 +13,15 @@ * */ -#include "src/actions/transformations/sql_hex_decode.h" - -#include -#include -#include -#include -#include -#include +#include "sql_hex_decode.h" + #include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/string.h" -namespace modsecurity { -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { + #ifndef VALID_HEX #define VALID_HEX(X) (((X >= '0') && (X <= '9')) \ @@ -41,8 +32,7 @@ namespace transformations { #define ISODIGIT(X) ((X >= '0') && (X <= '7')) #endif -std::string SqlHexDecode::evaluate(const std::string &value, - Transaction *transaction) { +bool SqlHexDecode::transform(std::string &value, const Transaction *trans) const { std::string ret; unsigned char *input; int size = 0; @@ -61,7 +51,9 @@ std::string SqlHexDecode::evaluate(const std::string &value, ret.assign(reinterpret_cast(input), size); free(input); - return ret; + const auto changed = ret != value; + value = ret; + return changed; } @@ -107,7 +99,4 @@ int SqlHexDecode::inplace(unsigned char *data, int len) { } - -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/sql_hex_decode.h b/src/actions/transformations/sql_hex_decode.h index 9a3afe0f5e..a92a0a2b49 100644 --- a/src/actions/transformations/sql_hex_decode.h +++ b/src/actions/transformations/sql_hex_decode.h @@ -13,27 +13,19 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_SQL_HEX_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_SQL_HEX_DECODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class SqlHexDecode : public Transformation { public: - explicit SqlHexDecode(const std::string &action) : Transformation(action) { } + explicit SqlHexDecode(const std::string &action) + : Transformation(action) { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; static int inplace(unsigned char *data, int len); @@ -45,10 +37,6 @@ class SqlHexDecode : public Transformation { } }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_SQL_HEX_DECODE_H_ diff --git a/src/actions/transformations/transformation.cc b/src/actions/transformations/transformation.cc index 3b38431ad1..b6fbf5a394 100644 --- a/src/actions/transformations/transformation.cc +++ b/src/actions/transformations/transformation.cc @@ -13,65 +13,62 @@ * */ -#include "src/actions/transformations/transformation.h" +#include "transformation.h" #include - #include #include #include "modsecurity/transaction.h" #include "modsecurity/actions/action.h" -#include "src/actions/transformations/base64_decode_ext.h" -#include "src/actions/transformations/base64_decode.h" -#include "src/actions/transformations/base64_encode.h" -#include "src/actions/transformations/cmd_line.h" -#include "src/actions/transformations/compress_whitespace.h" -#include "src/actions/transformations/css_decode.h" -#include "src/actions/transformations/escape_seq_decode.h" -#include "src/actions/transformations/hex_decode.h" -#include "src/actions/transformations/hex_encode.h" -#include "src/actions/transformations/html_entity_decode.h" -#include "src/actions/transformations/js_decode.h" -#include "src/actions/transformations/length.h" -#include "src/actions/transformations/lower_case.h" -#include "src/actions/transformations/md5.h" -#include "src/actions/transformations/none.h" -#include "src/actions/transformations/normalise_path.h" -#include "src/actions/transformations/normalise_path_win.h" -#include "src/actions/transformations/parity_even_7bit.h" -#include "src/actions/transformations/parity_odd_7bit.h" -#include "src/actions/transformations/parity_zero_7bit.h" -#include "src/actions/transformations/remove_comments_char.h" -#include "src/actions/transformations/remove_comments.h" -#include "src/actions/transformations/remove_nulls.h" -#include "src/actions/transformations/remove_whitespace.h" -#include "src/actions/transformations/replace_comments.h" -#include "src/actions/transformations/replace_nulls.h" -#include "src/actions/transformations/sha1.h" -#include "src/actions/transformations/sql_hex_decode.h" -#include "src/actions/transformations/trim.h" -#include "src/actions/transformations/trim_left.h" -#include "src/actions/transformations/trim_right.h" -#include "src/actions/transformations/upper_case.h" -#include "src/actions/transformations/url_decode.h" -#include "src/actions/transformations/url_decode_uni.h" -#include "src/actions/transformations/url_encode.h" -#include "src/actions/transformations/utf8_to_unicode.h" + +#include "base64_decode_ext.h" +#include "base64_decode.h" +#include "base64_encode.h" +#include "cmd_line.h" +#include "compress_whitespace.h" +#include "css_decode.h" +#include "escape_seq_decode.h" +#include "hex_decode.h" +#include "hex_encode.h" +#include "html_entity_decode.h" +#include "js_decode.h" +#include "length.h" +#include "lower_case.h" +#include "md5.h" +#include "none.h" +#include "normalise_path.h" +#include "normalise_path_win.h" +#include "parity_even_7bit.h" +#include "parity_odd_7bit.h" +#include "parity_zero_7bit.h" +#include "remove_comments_char.h" +#include "remove_comments.h" +#include "remove_nulls.h" +#include "remove_whitespace.h" +#include "replace_comments.h" +#include "replace_nulls.h" +#include "sha1.h" +#include "sql_hex_decode.h" +#include "trim.h" +#include "trim_left.h" +#include "trim_right.h" +#include "upper_case.h" +#include "url_decode.h" +#include "url_decode_uni.h" +#include "url_encode.h" +#include "utf8_to_unicode.h" #define IF_MATCH(b) \ if (a.compare(2, std::strlen(#b), #b) == 0) -namespace modsecurity { -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { -std::string Transformation::evaluate(const std::string &value, - Transaction *transaction) { - return value; +bool Transformation::transform(std::string &value, const Transaction *trans) const { + return false; } Transformation* Transformation::instantiate(std::string a) { @@ -119,6 +116,5 @@ Transformation* Transformation::instantiate(std::string a) { return new Transformation(a); } -} // namespace transformations -} // namespace actions -} // namespace modsecurity + +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/transformation.h b/src/actions/transformations/transformation.h index f1d81503ec..3677dcefd8 100644 --- a/src/actions/transformations/transformation.h +++ b/src/actions/transformations/transformation.h @@ -13,19 +13,12 @@ * */ -#include - -#include "modsecurity/actions/action.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_TRANSFORMATION_H_ #define SRC_ACTIONS_TRANSFORMATIONS_TRANSFORMATION_H_ +#include "modsecurity/actions/action.h" -namespace modsecurity { -class Transaction; - -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class Transformation : public Action { public: @@ -35,15 +28,11 @@ class Transformation : public Action { explicit Transformation(const std::string& _action, int kind) : Action(_action, kind) { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; - static Transformation* instantiate(std::string a); -}; -} // namespace transformations -} // namespace actions -} // namespace modsecurity + virtual bool transform(std::string &value, const Transaction *trans) const; +}; +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_TRANSFORMATION_H_ diff --git a/src/actions/transformations/trim.cc b/src/actions/transformations/trim.cc index 5902497f40..a551534676 100644 --- a/src/actions/transformations/trim.cc +++ b/src/actions/transformations/trim.cc @@ -13,22 +13,10 @@ * */ -#include "src/actions/transformations/trim.h" +#include "trim.h" -#include -#include -#include -#include -#include -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" -#include "modsecurity/actions/action.h" - -namespace modsecurity { -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { std::string *Trim::ltrim(std::string *s) { @@ -66,14 +54,13 @@ Trim::Trim(const std::string &action) } -std::string -Trim::evaluate(const std::string &val, - Transaction *transaction) { - std::string value(val); - return *this->trim(&value); +bool Trim::transform(std::string &value, const Transaction *trans) const { + std::string ret(value); + this->trim(&ret); + const auto changed = ret != value; + value = ret; + return changed; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/trim.h b/src/actions/transformations/trim.h index ac16050cfd..3b0e82d94c 100644 --- a/src/actions/transformations/trim.h +++ b/src/actions/transformations/trim.h @@ -13,38 +13,24 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_TRIM_H_ #define SRC_ACTIONS_TRANSFORMATIONS_TRIM_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class Trim : public Transformation { public: + explicit Trim(const std::string &action); - explicit Trim(const std::string &action) ; + bool transform(std::string &value, const Transaction *trans) const override; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; - - std::string *ltrim(std::string *s); - std::string *rtrim(std::string *s); - std::string *trim(std::string *s); + static std::string *ltrim(std::string *s); + static std::string *rtrim(std::string *s); + static std::string *trim(std::string *s); }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_TRIM_H_ diff --git a/src/actions/transformations/trim_left.cc b/src/actions/transformations/trim_left.cc index 50c0cc6aa5..c141727a7b 100644 --- a/src/actions/transformations/trim_left.cc +++ b/src/actions/transformations/trim_left.cc @@ -13,23 +13,10 @@ * */ -#include "src/actions/transformations/trim_left.h" +#include "trim_left.h" -#include -#include -#include -#include -#include -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" -#include "src/actions/transformations/trim.h" -#include "modsecurity/actions/action.h" - -namespace modsecurity { -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { @@ -38,12 +25,13 @@ TrimLeft::TrimLeft(const std::string &action) this->action_kind = 1; } -std::string TrimLeft::evaluate(const std::string &val, - Transaction *transaction) { - std::string value(val); - return *ltrim(&value); +bool TrimLeft::transform(std::string &value, const Transaction *trans) const { + std::string ret(value); + this->ltrim(&ret); + const auto changed = ret != value; + value = ret; + return changed; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity + +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/trim_left.h b/src/actions/transformations/trim_left.h index 54e4885c05..5d5a0a57b3 100644 --- a/src/actions/transformations/trim_left.h +++ b/src/actions/transformations/trim_left.h @@ -13,34 +13,21 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" -#include "src/actions/transformations/trim.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_TRIM_LEFT_H_ #define SRC_ACTIONS_TRANSFORMATIONS_TRIM_LEFT_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" +#include "trim.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class TrimLeft : public Trim { public: - explicit TrimLeft(const std::string &action) ; + explicit TrimLeft(const std::string &action); - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_TRIM_LEFT_H_ diff --git a/src/actions/transformations/trim_right.cc b/src/actions/transformations/trim_right.cc index 92383f7e00..b95b63aad0 100644 --- a/src/actions/transformations/trim_right.cc +++ b/src/actions/transformations/trim_right.cc @@ -13,22 +13,10 @@ * */ -#include "src/actions/transformations/trim_right.h" +#include "trim_right.h" -#include -#include -#include -#include -#include -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" -#include "modsecurity/actions/action.h" - -namespace modsecurity { -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { TrimRight::TrimRight(const std::string &action) @@ -36,12 +24,13 @@ TrimRight::TrimRight(const std::string &action) this->action_kind = 1; } -std::string TrimRight::evaluate(const std::string &val, - Transaction *transaction) { - std::string value(val); - return *this->rtrim(&value); +bool TrimRight::transform(std::string &value, const Transaction *trans) const { + std::string ret(value); + this->rtrim(&ret); + const auto changed = ret != value; + value = ret; + return changed; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity + +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/trim_right.h b/src/actions/transformations/trim_right.h index 9a96b4c5cc..eb13fb20f3 100644 --- a/src/actions/transformations/trim_right.h +++ b/src/actions/transformations/trim_right.h @@ -13,34 +13,21 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" -#include "src/actions/transformations/trim.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_TRIM_RIGHT_H_ #define SRC_ACTIONS_TRANSFORMATIONS_TRIM_RIGHT_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" +#include "trim.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class TrimRight : public Trim { public: - explicit TrimRight(const std::string &action) ; + explicit TrimRight(const std::string &action); - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_TRIM_RIGHT_H_ diff --git a/src/actions/transformations/upper_case.cc b/src/actions/transformations/upper_case.cc index 998ec725ea..2b8ad1d9b1 100644 --- a/src/actions/transformations/upper_case.cc +++ b/src/actions/transformations/upper_case.cc @@ -13,27 +13,19 @@ * */ -#include "src/actions/transformations/upper_case.h" -#include -#include -#include +#include "upper_case.h" -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" -#include "modsecurity/actions/action.h" +#include -namespace modsecurity { -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { UpperCase::UpperCase(const std::string &a) : Transformation(a) { } -std::string UpperCase::evaluate(const std::string &val, - Transaction *transaction) { +bool UpperCase::transform(std::string &val, const Transaction *trans) const { std::string value(val); std::locale loc; @@ -41,9 +33,10 @@ std::string UpperCase::evaluate(const std::string &val, value[i] = std::toupper(value[i], loc); } - return value; + const auto changed = val != value; + val = value; + return changed; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity + +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/upper_case.h b/src/actions/transformations/upper_case.h index f4a77220c6..70c806b0c6 100644 --- a/src/actions/transformations/upper_case.h +++ b/src/actions/transformations/upper_case.h @@ -13,35 +13,20 @@ * */ -#include -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_UPPER_CASE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_UPPER_CASE_H_ -#ifdef __cplusplus - -namespace modsecurity { -class Transaction; -namespace actions { -namespace transformations { +#include "transformation.h" +namespace modsecurity::actions::transformations { class UpperCase : public Transformation { public: - explicit UpperCase(const std::string &action) ; + explicit UpperCase(const std::string &action); - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_UPPER_CASE_H_ diff --git a/src/actions/transformations/url_decode.cc b/src/actions/transformations/url_decode.cc index 845c6a647a..7e5f87676f 100644 --- a/src/actions/transformations/url_decode.cc +++ b/src/actions/transformations/url_decode.cc @@ -13,23 +13,12 @@ * */ -#include "src/actions/transformations/url_decode.h" +#include "url_decode.h" -#include -#include -#include -#include -#include -#include -#include - -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/decode.h" -namespace modsecurity { -namespace actions { -namespace transformations { + +namespace modsecurity::actions::transformations { UrlDecode::UrlDecode(const std::string &action) @@ -37,28 +26,27 @@ UrlDecode::UrlDecode(const std::string &action) this->action_kind = 1; } -std::string UrlDecode::evaluate(const std::string &value, - Transaction *transaction) { +bool UrlDecode::transform(std::string &value, const Transaction *trans) const { unsigned char *val(NULL); int invalid_count = 0; - int changed; + int _changed; val = (unsigned char *) malloc(sizeof(char) * value.size() + 1); memcpy(val, value.c_str(), value.size() + 1); val[value.size()] = '\0'; int size = utils::urldecode_nonstrict_inplace(val, value.size(), - &invalid_count, &changed); + &invalid_count, &_changed); std::string out; out.append((const char *)val, size); free(val); - return out; + const auto changed = out != value; + value = out; + return changed; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/url_decode.h b/src/actions/transformations/url_decode.h index e965dae7fe..5c5c266209 100644 --- a/src/actions/transformations/url_decode.h +++ b/src/actions/transformations/url_decode.h @@ -13,36 +13,20 @@ * */ -#include -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_URL_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_URL_DECODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; - -namespace actions { -namespace transformations { +#include "transformation.h" +namespace modsecurity::actions::transformations { class UrlDecode : public Transformation { public: + explicit UrlDecode(const std::string &action); - explicit UrlDecode(const std::string &action) ; - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_URL_DECODE_H_ diff --git a/src/actions/transformations/url_decode_uni.cc b/src/actions/transformations/url_decode_uni.cc index ad5b8111c6..fdc2e79b56 100644 --- a/src/actions/transformations/url_decode_uni.cc +++ b/src/actions/transformations/url_decode_uni.cc @@ -13,33 +13,16 @@ * */ -#include "src/actions/transformations/url_decode_uni.h" +#include "url_decode_uni.h" -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "modsecurity/rules_set_properties.h" #include "modsecurity/rules_set.h" -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/string.h" -#include "src/utils/system.h" -namespace modsecurity { -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { -std::string UrlDecodeUni::evaluate(const std::string &value, - Transaction *t) { +bool UrlDecodeUni::transform(std::string &value, const Transaction *t) const { std::string ret; unsigned char *input; @@ -57,7 +40,9 @@ std::string UrlDecodeUni::evaluate(const std::string &value, ret.assign(reinterpret_cast(input), i); free(input); - return ret; + const auto changed = ret != value; + value = ret; + return changed; } @@ -66,7 +51,7 @@ std::string UrlDecodeUni::evaluate(const std::string &value, * IMP1 Assumes NUL-terminated */ int UrlDecodeUni::inplace(unsigned char *input, uint64_t input_len, - Transaction *t) { + const Transaction *t) { unsigned char *d = input; int64_t i, count, fact, j, xv; int Code, hmap = -1; @@ -190,6 +175,4 @@ int UrlDecodeUni::inplace(unsigned char *input, uint64_t input_len, } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/url_decode_uni.h b/src/actions/transformations/url_decode_uni.h index d7b0dd2152..3196285127 100644 --- a/src/actions/transformations/url_decode_uni.h +++ b/src/actions/transformations/url_decode_uni.h @@ -13,35 +13,23 @@ * */ -#include - -#include "modsecurity/rules_set_properties.h" -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_URL_DECODE_UNI_H_ #define SRC_ACTIONS_TRANSFORMATIONS_URL_DECODE_UNI_H_ +#include "transformation.h" -#ifdef __cplusplus -namespace modsecurity { -class Transaction; -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class UrlDecodeUni : public Transformation { public: - explicit UrlDecodeUni(const std::string &action) : Transformation(action) { } + explicit UrlDecodeUni(const std::string &action) + : Transformation(action) { } - std::string evaluate(const std::string &exp, Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; static int inplace(unsigned char *input, uint64_t input_len, - Transaction *transaction); + const Transaction *transaction); }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_URL_DECODE_UNI_H_ diff --git a/src/actions/transformations/url_encode.cc b/src/actions/transformations/url_encode.cc index 056755ca2d..e7f59f85af 100644 --- a/src/actions/transformations/url_encode.cc +++ b/src/actions/transformations/url_encode.cc @@ -13,22 +13,11 @@ * */ -#include "src/actions/transformations/url_encode.h" +#include "url_encode.h" -#include -#include -#include -#include -#include -#include - -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/string.h" -namespace modsecurity { -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { UrlEncode::UrlEncode(const std::string &action) @@ -87,16 +76,15 @@ std::string UrlEncode::url_enc(const char *input, } -std::string UrlEncode::evaluate(const std::string &value, - Transaction *transaction) { - int changed; +bool UrlEncode::transform(std::string &value, const Transaction *trans) const { + int _changed; - std::string ret = url_enc(value.c_str(), value.size(), &changed); + std::string ret = url_enc(value.c_str(), value.size(), &_changed); - return ret; + const auto changed = ret != value; + value = ret; + return changed; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/url_encode.h b/src/actions/transformations/url_encode.h index a45be56402..b300c40da0 100644 --- a/src/actions/transformations/url_encode.h +++ b/src/actions/transformations/url_encode.h @@ -13,37 +13,23 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_URL_ENCODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_URL_ENCODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class UrlEncode : public Transformation { public: + explicit UrlEncode(const std::string &action); - explicit UrlEncode(const std::string &action) ; + bool transform(std::string &value, const Transaction *trans) const override; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; - - std::string url_enc(const char *input, + static std::string url_enc(const char *input, unsigned int input_len, int *changed); }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - -#endif +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_URL_ENCODE_H_ diff --git a/src/actions/transformations/utf8_to_unicode.cc b/src/actions/transformations/utf8_to_unicode.cc index 70c1f9c8e1..2f40ce60b4 100644 --- a/src/actions/transformations/utf8_to_unicode.cc +++ b/src/actions/transformations/utf8_to_unicode.cc @@ -13,31 +13,20 @@ * */ -#include "src/actions/transformations/utf8_to_unicode.h" - -#include -#include -#include -#include -#include -#include +#include "utf8_to_unicode.h" + #include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/string.h" -namespace modsecurity { -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { -std::string Utf8ToUnicode::evaluate(const std::string &value, - Transaction *transaction) { +bool Utf8ToUnicode::transform(std::string &value, const Transaction *trans) const { std::string ret; unsigned char *input; - int changed = 0; + int _changed = 0; char *out; input = reinterpret_cast @@ -49,7 +38,7 @@ std::string Utf8ToUnicode::evaluate(const std::string &value, memcpy(input, value.c_str(), value.length()+1); - out = inplace(input, value.size() + 1, &changed); + out = inplace(input, value.size() + 1, &_changed); free(input); if (out != NULL) { ret.assign(reinterpret_cast(out), @@ -57,7 +46,9 @@ std::string Utf8ToUnicode::evaluate(const std::string &value, free(out); } - return ret; + const auto changed = ret != value; + value = ret; + return changed; } @@ -313,6 +304,4 @@ char *Utf8ToUnicode::inplace(unsigned char *input, } -} // namespace transformations -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/utf8_to_unicode.h b/src/actions/transformations/utf8_to_unicode.h index 4d488410e0..83aba8199a 100644 --- a/src/actions/transformations/utf8_to_unicode.h +++ b/src/actions/transformations/utf8_to_unicode.h @@ -13,40 +13,30 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_ACTIONS_TRANSFORMATIONS_UTF8_TO_UNICODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_UTF8_TO_UNICODE_H_ +#include "transformation.h" + #define UNICODE_ERROR_CHARACTERS_MISSING -1 #define UNICODE_ERROR_INVALID_ENCODING -2 #define UNICODE_ERROR_OVERLONG_CHARACTER -3 #define UNICODE_ERROR_RESTRICTED_CHARACTER -4 #define UNICODE_ERROR_DECODING_ERROR -5 -namespace modsecurity { -class Transaction; - -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class Utf8ToUnicode : public Transformation { public: - explicit Utf8ToUnicode(const std::string &action) : Transformation(action) { } + explicit Utf8ToUnicode(const std::string &action) + : Transformation(action) { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + bool transform(std::string &value, const Transaction *trans) const override; static char *inplace(unsigned char *input, uint64_t input_len, int *changed); }; -} // namespace transformations -} // namespace actions -} // namespace modsecurity - +} // namespace modsecurity::actions::transformations #endif // SRC_ACTIONS_TRANSFORMATIONS_UTF8_TO_UNICODE_H_ diff --git a/src/actions/ver.cc b/src/actions/ver.cc index 43b8b832e2..d7b8bdc42d 100644 --- a/src/actions/ver.cc +++ b/src/actions/ver.cc @@ -15,16 +15,10 @@ #include "src/actions/ver.h" -#include -#include +#include "modsecurity/rule_with_actions.h" -#include "modsecurity/actions/action.h" -#include "modsecurity/transaction.h" -#include "modsecurity/rule.h" - -namespace modsecurity { -namespace actions { +namespace modsecurity::actions { bool Ver::evaluate(RuleWithActions *rule, Transaction *transaction) { @@ -33,5 +27,4 @@ bool Ver::evaluate(RuleWithActions *rule, Transaction *transaction) { } -} // namespace actions -} // namespace modsecurity +} // namespace modsecurity::actions diff --git a/src/engine/lua.cc b/src/engine/lua.cc index 0fac4f6477..01a3eaceaf 100644 --- a/src/engine/lua.cc +++ b/src/engine/lua.cc @@ -267,7 +267,7 @@ int Lua::getvar(lua_State *L) { t = reinterpret_cast(z); std::string var = variables::Variable::stringMatchResolve(t, varname); - var = applyTransformations(L, t, 2, var); + applyTransformations(L, t, 2, var); if (var.size() == 0) { lua_pushnil(L); @@ -407,12 +407,10 @@ int Lua::setvar(lua_State *L) { } -std::string Lua::applyTransformations(lua_State *L, Transaction *t, - int idx, std::string var) { - std::string newVar = var; - +void Lua::applyTransformations(lua_State *L, const Transaction *t, + int idx, std::string &var) { if (lua_isuserdata(L, idx) || lua_isnoneornil(L, idx)) { - return var; + return; } if (lua_istable(L, idx)) { @@ -429,16 +427,15 @@ std::string Lua::applyTransformations(lua_State *L, Transaction *t, /* A "none" means start over */ if (strcmp("none", name) == 0) { - newVar = var; continue; } - actions::transformations::Transformation *tfn = \ + auto tfn = \ actions::transformations::Transformation::instantiate( "t:" + std::string(name)); // FIXME: transformation is not yet returning null. if (tfn) { - newVar = tfn->evaluate(newVar, t); + tfn->transform(var, t); } else { ms_dbg_a(t, 1, "SecRuleScript: Invalid transformation function: " \ @@ -447,32 +444,31 @@ std::string Lua::applyTransformations(lua_State *L, Transaction *t, delete tfn; } - return newVar; + return; } if (lua_isstring(L, idx)) { const char *name(NULL); name = reinterpret_cast(luaL_checkstring(L, idx)); - actions::transformations::Transformation *tfn = \ + auto tfn = \ actions::transformations::Transformation::instantiate( "t:" + std::string(name)); // FIXME: transformation is not yet returning null. if (tfn) { - newVar = tfn->evaluate(newVar, t); + tfn->transform(var, t); delete tfn; } else { ms_dbg_a(t, 1, "SecRuleScript: Invalid transformation function: " \ + std::string(name)); } - return newVar; + return; } ms_dbg_a(t, 8, "SecRuleScript: Transformation parameter must be a " \ "transformation name or array of transformation names, but found " \ "" + std::string(lua_typename(L, idx)) + " (type " \ + std::to_string(lua_type(L, idx)) + ")"); - return newVar; } #endif diff --git a/src/engine/lua.h b/src/engine/lua.h index a33f28f812..452c7f4989 100644 --- a/src/engine/lua.h +++ b/src/engine/lua.h @@ -79,8 +79,8 @@ class Lua { static int getvar(lua_State *L); static int getvars(lua_State *L); static int setvar(lua_State *L); - static std::string applyTransformations(lua_State *L, Transaction *t, - int idx, std::string var); + static void applyTransformations(lua_State *L, const Transaction *t, + int idx, std::string &var); LuaScriptBlob m_blob; #endif diff --git a/src/modsecurity.cc b/src/modsecurity.cc index 855facb30d..93caa95242 100644 --- a/src/modsecurity.cc +++ b/src/modsecurity.cc @@ -300,7 +300,6 @@ int ModSecurity::processContentOffset(const char *content, size_t len, while (!trans.empty()) { modsecurity::actions::transformations::Transformation *t; - std::string varValueRes; yajl_gen_map_open(g); yajl_gen_string(g, reinterpret_cast("transformation"), @@ -312,8 +311,7 @@ int ModSecurity::processContentOffset(const char *content, size_t len, t = modsecurity::actions::transformations::Transformation::instantiate( trans.back().str().c_str()); - varValueRes = t->evaluate(varValue, NULL); - varValue.assign(varValueRes); + t->transform(varValue, nullptr); trans.pop_back(); yajl_gen_string(g, reinterpret_cast("value"), diff --git a/src/operators/validate_utf8_encoding.cc b/src/operators/validate_utf8_encoding.cc index 3e17686fcc..cd2f064c8c 100644 --- a/src/operators/validate_utf8_encoding.cc +++ b/src/operators/validate_utf8_encoding.cc @@ -19,6 +19,14 @@ #include "src/operators/operator.h" + +constexpr int UNICODE_ERROR_CHARACTERS_MISSING = -1; +constexpr int UNICODE_ERROR_INVALID_ENCODING = -2; +constexpr int UNICODE_ERROR_OVERLONG_CHARACTER = -3; +constexpr int UNICODE_ERROR_RESTRICTED_CHARACTER = -4; +constexpr int UNICODE_ERROR_DECODING_ERROR = -5; + + namespace modsecurity { namespace operators { diff --git a/src/operators/validate_utf8_encoding.h b/src/operators/validate_utf8_encoding.h index e59eef5897..2bd75dc8e7 100644 --- a/src/operators/validate_utf8_encoding.h +++ b/src/operators/validate_utf8_encoding.h @@ -22,13 +22,6 @@ #include "src/operators/operator.h" -#define UNICODE_ERROR_CHARACTERS_MISSING -1 -#define UNICODE_ERROR_INVALID_ENCODING -2 -#define UNICODE_ERROR_OVERLONG_CHARACTER -3 -#define UNICODE_ERROR_RESTRICTED_CHARACTER -4 -#define UNICODE_ERROR_DECODING_ERROR -5 - - namespace modsecurity { namespace operators { diff --git a/src/rule_with_actions.cc b/src/rule_with_actions.cc index e5d8183f67..1b76005c70 100644 --- a/src/rule_with_actions.cc +++ b/src/rule_with_actions.cc @@ -25,6 +25,7 @@ #include #include #include +#include #include "modsecurity/rules_set.h" #include "src/operators/operator.h" @@ -323,49 +324,42 @@ void RuleWithActions::executeAction(Transaction *trans, inline void RuleWithActions::executeTransformation( - actions::transformations::Transformation *a, - std::shared_ptr *value, - Transaction *trans, + const actions::transformations::Transformation &a, + std::string &value, + const Transaction *trans, TransformationResults *ret, std::string *path, int *nth) const { - std::string *oldValue = (*value).get(); - std::string newValue = a->evaluate(*oldValue, trans); - - if (newValue != *oldValue) { - auto u = std::make_shared(newValue); - if (m_containsMultiMatchAction) { - ret->push_back(std::make_pair(u, a->m_name)); - (*nth)++; - } - *value = u; + if (a.transform(value, trans) && + m_containsMultiMatchAction) { + ret.emplace_back(value, a.m_name); + (*nth)++; } if (path->empty()) { - path->append(*a->m_name.get()); + path->append(*a.m_name.get()); } else { - path->append("," + *a->m_name.get()); + path->append("," + *a.m_name.get()); } ms_dbg_a(trans, 9, " T (" + \ std::to_string(*nth) + ") " + \ - *a->m_name.get() + ": \"" + \ - utils::string::limitTo(80, newValue) +"\""); + *a.m_name.get() + ": \"" + \ + utils::string::limitTo(80, value) +"\""); } void RuleWithActions::executeTransformations( - Transaction *trans, const std::string &in, TransformationResults &ret) { + const Transaction *trans, const std::string &in, TransformationResults &ret) { int none = 0; int transformations = 0; std::string path(""); - auto value = std::make_shared(in); + auto value = in; if (m_containsMultiMatchAction == true) { /* keep the original value */ - ret.push_back(std::make_pair( - std::make_shared(*value), - std::make_shared(path))); + ret.emplace_back(value, + std::make_shared(path)); } for (Action *a : m_transformations) { @@ -385,15 +379,17 @@ void RuleWithActions::executeTransformations( } // FIXME: here the object needs to be a transformation already. - Transformation *t = dynamic_cast(a.get()); - executeTransformation(t, &value, trans, &ret, &path, + auto t = dynamic_cast(a.get()); + assert(t != nullptr); + executeTransformation(*t, value, trans, &ret, &path, &transformations); } } - for (Transformation *a : m_transformations) { + for (const Transformation *a : m_transformations) { + assert(a != nullptr); if (none == 0) { - executeTransformation(a, &value, trans, &ret, &path, + executeTransformation(*a, value, trans, &ret, &path, &transformations); } if (a->m_isNone) { @@ -408,7 +404,8 @@ void RuleWithActions::executeTransformations( if (m_ruleId != b.first) { continue; } - Transformation *a = dynamic_cast(b.second.get()); + auto a = dynamic_cast(b.second.get()); + assert(a != nullptr); if (a->m_isNone) { none++; } @@ -419,9 +416,10 @@ void RuleWithActions::executeTransformations( if (m_ruleId != b.first) { continue; } - Transformation *a = dynamic_cast(b.second.get()); + auto a = dynamic_cast(b.second.get()); + assert(a != nullptr); if (none == 0) { - executeTransformation(a, &value, trans, &ret, &path, + executeTransformation(*a, value, trans, &ret, &path, &transformations); } if (a->m_isNone) { @@ -436,9 +434,8 @@ void RuleWithActions::executeTransformations( } if (!m_containsMultiMatchAction) { - ret.push_back(std::make_pair( - std::make_shared(*value), - std::make_shared(path))); + ret.emplace_back(value, + std::make_shared(path)); } } diff --git a/src/rule_with_operator.cc b/src/rule_with_operator.cc index f54ffb5c1d..b043af5c17 100644 --- a/src/rule_with_operator.cc +++ b/src/rule_with_operator.cc @@ -296,10 +296,9 @@ bool RuleWithOperator::evaluate(Transaction *trans, executeTransformations(trans, value, values); for (const auto &valueTemp : values) { - bool ret; - std::string valueAfterTrans = std::move(*valueTemp.first); + const auto &valueAfterTrans = valueTemp.first; - ret = executeOperatorAt(trans, key, valueAfterTrans, ruleMessage); + const bool ret = executeOperatorAt(trans, key, valueAfterTrans, ruleMessage); if (ret == true) { ruleMessage->m_match = m_operator->resolveMatchMessage(trans, diff --git a/src/utils/string.h b/src/utils/string.h index b0c3c17d97..dbfb9b4795 100644 --- a/src/utils/string.h +++ b/src/utils/string.h @@ -235,18 +235,18 @@ inline unsigned char *c2x(unsigned what, unsigned char *where) { } -inline std::string string_to_hex(const std::string& input) { - static const char* const lut = "0123456789ABCDEF"; - size_t len = input.length(); - - std::string output; - output.reserve(2 * len); - for (size_t i = 0; i < len; ++i) { - const unsigned char c = input[i]; - output.push_back(lut[c >> 4]); - output.push_back(lut[c & 15]); +inline std::string string_to_hex(std::string_view input) { + static const char* const lut = "0123456789abcdef"; + + std::string a(input.size()*2, 0); + char *d = a.data(); + + for (const unsigned char c : input) { + *d++ = lut[c >> 4]; + *d++ = lut[c & 15]; } - return output; + + return a; } diff --git a/test/coding_style_suppressions.txt b/test/coding_style_suppressions.txt index c2b1ea52d9..bba5a62c99 100644 --- a/test/coding_style_suppressions.txt +++ b/test/coding_style_suppressions.txt @@ -13,7 +13,6 @@ ./src/utils/acmp.cc ./src/utils/acmp.h ./src/utils/mbedtls/ -./src/utils/md5.cc ./src/utils/md5.h ./src/utils/msc_tree.cc ./src/utils/msc_tree.h diff --git a/test/unit/unit.cc b/test/unit/unit.cc index 75fec13726..5ebc9d3fe4 100644 --- a/test/unit/unit.cc +++ b/test/unit/unit.cc @@ -89,8 +89,10 @@ struct TransformationTest { return tfn; } - static UnitTestResult eval(ItemType &tfn, const UnitTest &t) { - return {1, tfn.evaluate(t.input, nullptr)}; + static UnitTestResult eval(const ItemType &tfn, const UnitTest &t) { + std::string ret = t.input; + tfn.transform(ret, nullptr); + return {1, ret}; } static bool check(const UnitTestResult &result, const UnitTest &t) { diff --git a/test/unit/unit_test.cc b/test/unit/unit_test.cc index dee4f1ae12..b00607325c 100644 --- a/test/unit/unit_test.cc +++ b/test/unit/unit_test.cc @@ -30,20 +30,6 @@ namespace modsecurity_test { -std::string string_to_hex(const std::string& input) { - static const char* const lut = "0123456789ABCDEF"; - size_t len = input.length(); - - std::string output; - output.reserve(2 * len); - for (size_t i = 0; i < len; ++i) { - const unsigned char c = input[i]; - output.push_back(lut[c >> 4]); - output.push_back(lut[c & 15]); - } - return output; -} - void replaceAll(std::string *s, const std::string &search, const char replace) { for (size_t pos = 0; ; pos += 0) { From 3ff72fbbc526b0c1dd17e63f61791c126d125831 Mon Sep 17 00:00:00 2001 From: Eduardo Arias Date: Mon, 19 Aug 2024 01:48:38 +0000 Subject: [PATCH 02/24] Perform ParityEven7bit, ParityOdd7bit & ParityZero7bit transformations in-place - Refactored to share implementations of ParityEven7bit & ParityOdd7bit. --- .../transformations/parity_even_7bit.cc | 43 +----------------- .../transformations/parity_even_7bit.h | 23 +++++++++- .../transformations/parity_odd_7bit.cc | 44 +------------------ src/actions/transformations/parity_odd_7bit.h | 1 - .../transformations/parity_zero_7bit.cc | 34 +++----------- .../transformations/parity_zero_7bit.h | 1 - 6 files changed, 31 insertions(+), 115 deletions(-) diff --git a/src/actions/transformations/parity_even_7bit.cc b/src/actions/transformations/parity_even_7bit.cc index f299224094..d9327b9eb2 100644 --- a/src/actions/transformations/parity_even_7bit.cc +++ b/src/actions/transformations/parity_even_7bit.cc @@ -15,53 +15,12 @@ #include "parity_even_7bit.h" -#include - namespace modsecurity::actions::transformations { bool ParityEven7bit::transform(std::string &value, const Transaction *trans) const { - if (value.empty()) return false; - - unsigned char *input; - - input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); - - if (input == NULL) { - return ""; - } - - std::memcpy(input, value.c_str(), value.length()+1); - - const auto ret = inplace(input, value.length()); - - value.assign(reinterpret_cast(input), value.length()); - free(input); - - return ret; -} - -bool ParityEven7bit::inplace(unsigned char *input, uint64_t input_len) { - uint64_t i; - - i = 0; - while (i < input_len) { - unsigned int x = input[i]; - - input[i] ^= input[i] >> 4; - input[i] &= 0xf; - - if ((0x6996 >> input[i]) & 1) { - input[i] = x | 0x80; - } else { - input[i] = x & 0x7f; - } - i++; - } - - return true; + return ParityEven7bit::inplace(value); } diff --git a/src/actions/transformations/parity_even_7bit.h b/src/actions/transformations/parity_even_7bit.h index 41010d6255..786f72e419 100644 --- a/src/actions/transformations/parity_even_7bit.h +++ b/src/actions/transformations/parity_even_7bit.h @@ -26,7 +26,28 @@ class ParityEven7bit : public Transformation { : Transformation(action) { } bool transform(std::string &value, const Transaction *trans) const override; - static bool inplace(unsigned char *input, uint64_t input_len); + + template + static bool inplace(std::string &value) { + if (value.empty()) return false; + + for(auto &c : value) { + auto &uc = reinterpret_cast(c); + unsigned int x = uc; + + uc ^= uc >> 4; + uc &= 0xf; + + const bool condition = (0x6996 >> uc) & 1; + if (even ? condition : !condition) { + uc = x | 0x80; + } else { + uc = x & 0x7f; + } + } + + return true; + } }; } // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/parity_odd_7bit.cc b/src/actions/transformations/parity_odd_7bit.cc index f8192ef306..865a2754ed 100644 --- a/src/actions/transformations/parity_odd_7bit.cc +++ b/src/actions/transformations/parity_odd_7bit.cc @@ -14,54 +14,14 @@ */ #include "parity_odd_7bit.h" - -#include +#include "parity_even_7bit.h" namespace modsecurity::actions::transformations { bool ParityOdd7bit::transform(std::string &value, const Transaction *trans) const { - if (value.empty()) return false; - - unsigned char *input; - - input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); - - if (input == NULL) { - return ""; - } - - memcpy(input, value.c_str(), value.length()+1); - - const auto ret = inplace(input, value.length()); - - value.assign(reinterpret_cast(input), value.length()); - free(input); - - return ret; -} - -bool ParityOdd7bit::inplace(unsigned char *input, uint64_t input_len) { - uint64_t i; - - i = 0; - while (i < input_len) { - unsigned int x = input[i]; - - input[i] ^= input[i] >> 4; - input[i] &= 0xf; - - if ((0x6996 >> input[i]) & 1) { - input[i] = x & 0x7f; - } else { - input[i] = x | 0x80; - } - i++; - } - - return true; + return ParityEven7bit::inplace(value); } diff --git a/src/actions/transformations/parity_odd_7bit.h b/src/actions/transformations/parity_odd_7bit.h index 1afa13275e..d0a1583c55 100644 --- a/src/actions/transformations/parity_odd_7bit.h +++ b/src/actions/transformations/parity_odd_7bit.h @@ -26,7 +26,6 @@ class ParityOdd7bit : public Transformation { : Transformation(action) { } bool transform(std::string &value, const Transaction *trans) const override; - static bool inplace(unsigned char *input, uint64_t input_len); }; } // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/parity_zero_7bit.cc b/src/actions/transformations/parity_zero_7bit.cc index ef80b74d88..77ad05145b 100644 --- a/src/actions/transformations/parity_zero_7bit.cc +++ b/src/actions/transformations/parity_zero_7bit.cc @@ -15,45 +15,23 @@ #include "parity_zero_7bit.h" -#include - namespace modsecurity::actions::transformations { -bool ParityZero7bit::transform(std::string &value, const Transaction *trans) const { +static inline bool inplace(std::string &value) { if (value.empty()) return false; - unsigned char *input; - - input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); - - if (input == NULL) { - return ""; + for(auto &c : value) { + ((unsigned char&)c) &= 0x7f; } - memcpy(input, value.c_str(), value.length()+1); - - const auto ret = inplace(input, value.length()); - - value.assign(reinterpret_cast(input), value.length()); - free(input); - - return ret; + return true; } -bool ParityZero7bit::inplace(unsigned char *input, uint64_t input_len) { - uint64_t i; - - i = 0; - while (i < input_len) { - input[i] &= 0x7f; - i++; - } - - return true; +bool ParityZero7bit::transform(std::string &value, const Transaction *trans) const { + return inplace(value); } diff --git a/src/actions/transformations/parity_zero_7bit.h b/src/actions/transformations/parity_zero_7bit.h index af47f7c5f3..c7f27d7484 100644 --- a/src/actions/transformations/parity_zero_7bit.h +++ b/src/actions/transformations/parity_zero_7bit.h @@ -26,7 +26,6 @@ class ParityZero7bit : public Transformation { : Transformation(action) { } bool transform(std::string &value, const Transaction *trans) const override; - static bool inplace(unsigned char *input, uint64_t input_len); }; } // namespace modsecurity::actions::transformations From 13203ae5e7dba5ce8e80fd720573ca6e1e3155e6 Mon Sep 17 00:00:00 2001 From: Eduardo Arias Date: Mon, 19 Aug 2024 07:09:26 -0700 Subject: [PATCH 03/24] Perform CmdLine transformation in-place --- src/actions/transformations/cmd_line.cc | 27 +++++++++++++------------ 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/actions/transformations/cmd_line.cc b/src/actions/transformations/cmd_line.cc index cac1d2df6b..8db1529dfb 100644 --- a/src/actions/transformations/cmd_line.cc +++ b/src/actions/transformations/cmd_line.cc @@ -20,10 +20,10 @@ namespace modsecurity::actions::transformations { bool CmdLine::transform(std::string &value, const Transaction *trans) const { - std::string ret; - int space = 0; + char *d = value.data(); + bool space = false; - for (auto& a : value) { + for (const auto& a : value) { switch (a) { /* remove some characters */ case '"': @@ -39,9 +39,9 @@ bool CmdLine::transform(std::string &value, const Transaction *trans) const { case '\t': case '\r': case '\n': - if (space == 0) { - ret.append(" "); - space++; + if (space == false) { + *d++ = ' '; + space = true; } break; @@ -49,23 +49,24 @@ bool CmdLine::transform(std::string &value, const Transaction *trans) const { case '/': case '(': if (space) { - ret.pop_back(); + d--; } - space = 0; - ret.append(&a, 1); + space = false; + *d++ = a; break; /* copy normal characters */ default : char b = std::tolower(a); - ret.append(&b, 1); - space = 0; + *d++ = b; + space = false; break; } } - const auto changed = ret != value; - value = ret; + const auto new_len = d - value.c_str(); + const auto changed = new_len != value.length(); + value.resize(new_len); return changed; } From 1236d9a7cda62c58e10dba8d22ad801b2d7f353b Mon Sep 17 00:00:00 2001 From: Eduardo Arias Date: Mon, 19 Aug 2024 07:14:11 -0700 Subject: [PATCH 04/24] Perform CompressWhitespace transformation in-place --- .../transformations/compress_whitespace.cc | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/actions/transformations/compress_whitespace.cc b/src/actions/transformations/compress_whitespace.cc index 32c22a258f..065b4ee094 100644 --- a/src/actions/transformations/compress_whitespace.cc +++ b/src/actions/transformations/compress_whitespace.cc @@ -25,29 +25,27 @@ CompressWhitespace::CompressWhitespace(const std::string &action) } bool CompressWhitespace::transform(std::string &value, const Transaction *trans) const { + bool inWhiteSpace = false; - std::string a; - int inWhiteSpace = 0; - int i = 0; + auto d = value.data(); - while (i < value.size()) { - if (isspace(value[i])) { + for(const auto c : value) { + if (isspace(c)) { if (inWhiteSpace) { - i++; continue; } else { - inWhiteSpace = 1; - a.append(" ", 1); + inWhiteSpace = true; + *d++ = ' '; } } else { - inWhiteSpace = 0; - a.append(&value.at(i), 1); + inWhiteSpace = false; + *d++ = c; } - i++; } - const auto changed = a != value; - value = a; + const auto new_len = d - value.c_str(); + const auto changed = new_len != value.length(); + value.resize(new_len); return changed; } From 150502599068b721c7be6e8db5c8da39adff3b0e Mon Sep 17 00:00:00 2001 From: Eduardo Arias Date: Mon, 19 Aug 2024 07:21:22 -0700 Subject: [PATCH 05/24] Perform RemoveNulls & RemoveWhitespace transformations in-place - Refactored to share implementation. --- src/actions/transformations/remove_nulls.cc | 19 ++---------- src/actions/transformations/remove_nulls.h | 14 +++++++++ .../transformations/remove_whitespace.cc | 30 +++++++------------ 3 files changed, 26 insertions(+), 37 deletions(-) diff --git a/src/actions/transformations/remove_nulls.cc b/src/actions/transformations/remove_nulls.cc index bda34bbeeb..1d3cc552e6 100644 --- a/src/actions/transformations/remove_nulls.cc +++ b/src/actions/transformations/remove_nulls.cc @@ -19,23 +19,8 @@ namespace modsecurity::actions::transformations { -bool RemoveNulls::transform(std::string &val, const Transaction *trans) const { - size_t i = 0; - std::string transformed_value; - transformed_value.reserve(val.size()); - - while (i < val.size()) { - if (val.at(i) == '\0') { - // do nothing; continue on to next char in original val - } else { - transformed_value += val.at(i); - } - i++; - } - - const auto changed = transformed_value != val; - val = transformed_value; - return changed; +bool RemoveNulls::transform(std::string &value, const Transaction *trans) const { + return remove_if(value, [](const auto c) { return c == '\0'; }); } diff --git a/src/actions/transformations/remove_nulls.h b/src/actions/transformations/remove_nulls.h index 56df24c831..163f9ddfc7 100644 --- a/src/actions/transformations/remove_nulls.h +++ b/src/actions/transformations/remove_nulls.h @@ -18,6 +18,8 @@ #include "transformation.h" +#include + namespace modsecurity::actions::transformations { class RemoveNulls : public Transformation { @@ -26,6 +28,18 @@ class RemoveNulls : public Transformation { : Transformation(action) { } bool transform(std::string &value, const Transaction *trans) const override; + + template + static bool remove_if(std::string &val, Pred pred) { + const auto old_size = val.size(); + + val.erase( + std::remove_if( + val.begin(), val.end(), pred), + val.end()); + + return val.size() != old_size; + } }; } // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/remove_whitespace.cc b/src/actions/transformations/remove_whitespace.cc index 8cee80c968..934f1d29fe 100644 --- a/src/actions/transformations/remove_whitespace.cc +++ b/src/actions/transformations/remove_whitespace.cc @@ -15,6 +15,8 @@ #include "remove_whitespace.h" +#include "remove_nulls.h" + namespace modsecurity::actions::transformations { @@ -23,30 +25,18 @@ RemoveWhitespace::RemoveWhitespace(const std::string &action) this->action_kind = 1; } -bool RemoveWhitespace::transform(std::string &val, const Transaction *trans) const { - std::string transformed_value; - transformed_value.reserve(val.size()); - - size_t i = 0; +bool RemoveWhitespace::transform(std::string &value, const Transaction *trans) const { const char nonBreakingSpaces = 0xa0; const char nonBreakingSpaces2 = 0xc2; - // loop through all the chars - while (i < val.size()) { + auto pred = [](const auto c) { // remove whitespaces and non breaking spaces (NBSP) - if (std::isspace(static_cast(val[i])) - || (val[i] == nonBreakingSpaces) - || val[i] == nonBreakingSpaces2) { - // don't copy; continue on to next char in original val - } else { - transformed_value += val.at(i); - } - i++; - } - - const auto changed = transformed_value != val; - val = transformed_value; - return changed; + return std::isspace(static_cast(c)) + || c == nonBreakingSpaces + || c == nonBreakingSpaces2; + }; + + return RemoveNulls::remove_if(value, pred); } From da775eca81e2b4c7b74cf5287e4fa016d5a73b12 Mon Sep 17 00:00:00 2001 From: Eduardo Arias Date: Mon, 19 Aug 2024 08:41:18 -0700 Subject: [PATCH 06/24] Perform ReplaceNulls transformation in-place --- src/actions/transformations/replace_nulls.cc | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/actions/transformations/replace_nulls.cc b/src/actions/transformations/replace_nulls.cc index c59ceb87f3..479f2f5ac8 100644 --- a/src/actions/transformations/replace_nulls.cc +++ b/src/actions/transformations/replace_nulls.cc @@ -23,21 +23,16 @@ ReplaceNulls::ReplaceNulls(const std::string &action) this->action_kind = 1; } -bool ReplaceNulls::transform(std::string &val, const Transaction *trans) const { - int64_t i; - std::string value(val); - - i = 0; - while (i < value.size()) { - if (value.at(i) == '\0') { - value[i] = ' '; - } else { - i++; +bool ReplaceNulls::transform(std::string &value, const Transaction *trans) const { + bool changed = false; + + for(auto &c : value) { + if (c == '\0') { + c = ' '; + changed = true; } } - const auto changed = val != value; - val = value; return changed; } From 74d150c068cceaca76300f0003be6e2d152d975f Mon Sep 17 00:00:00 2001 From: Eduardo Arias Date: Mon, 19 Aug 2024 07:30:11 -0700 Subject: [PATCH 07/24] Perform RemoveCommentsChar, RemoveComments & ReplaceComments transformations in-place --- .../transformations/remove_comments.cc | 46 ++++++------- .../transformations/remove_comments_char.cc | 64 +++++++++---------- .../transformations/replace_comments.cc | 50 +++++++-------- 3 files changed, 75 insertions(+), 85 deletions(-) diff --git a/src/actions/transformations/remove_comments.cc b/src/actions/transformations/remove_comments.cc index 1515675c52..5f3edaef58 100644 --- a/src/actions/transformations/remove_comments.cc +++ b/src/actions/transformations/remove_comments.cc @@ -19,41 +19,34 @@ namespace modsecurity::actions::transformations { -bool RemoveComments::transform(std::string &value, const Transaction *trans) const { - std::string ret; - unsigned char *input; - - input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); - - if (input == NULL) { - return ""; - } - - memcpy(input, value.c_str(), value.length()+1); - - uint64_t input_len = value.size(); - uint64_t i, j, incomment; +static inline int inplace(std::string &value) { + auto input = reinterpret_cast(value.data()); + const auto input_len = value.length(); + bool changed = false, incomment = false; + std::string::size_type i = 0, j = 0; - i = j = incomment = 0; while (i < input_len) { - if (incomment == 0) { + if (!incomment) { if ((input[i] == '/') && (i + 1 < input_len) && (input[i + 1] == '*')) { - incomment = 1; + incomment = true; + changed = true; i += 2; } else if ((input[i] == '<') && (i + 1 < input_len) && (input[i + 1] == '!') && (i + 2 < input_len) && (input[i+2] == '-') && (i + 3 < input_len) && (input[i + 3] == '-')) { - incomment = 1; + incomment = true; + changed = true; i += 4; } else if ((input[i] == '-') && (i + 1 < input_len) && (input[i + 1] == '-')) { input[i] = ' '; + changed = true; break; } else if (input[i] == '#') { input[i] = ' '; + changed = true; break; } else { input[j] = input[i]; @@ -63,7 +56,7 @@ bool RemoveComments::transform(std::string &value, const Transaction *trans) con } else { if ((input[i] == '*') && (i + 1 < input_len) && (input[i + 1] == '/')) { - incomment = 0; + incomment = false; i += 2; input[j] = input[i]; i++; @@ -71,7 +64,7 @@ bool RemoveComments::transform(std::string &value, const Transaction *trans) con } else if ((input[i] == '-') && (i + 1 < input_len) && (input[i + 1] == '-') && (i + 2 < input_len) && (input[i+2] == '>')) { - incomment = 0; + incomment = false; i += 3; input[j] = input[i]; i++; @@ -86,13 +79,14 @@ bool RemoveComments::transform(std::string &value, const Transaction *trans) con input[j++] = ' '; } - ret.assign(reinterpret_cast(input), j); - free(input); - - const auto changed = ret != value; - value = ret; + value.resize(j); return changed; } +bool RemoveComments::transform(std::string &value, const Transaction *trans) const { + return inplace(value); +} + + } // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/remove_comments_char.cc b/src/actions/transformations/remove_comments_char.cc index 7a4763d332..2eeb86f65e 100644 --- a/src/actions/transformations/remove_comments_char.cc +++ b/src/actions/transformations/remove_comments_char.cc @@ -23,43 +23,43 @@ RemoveCommentsChar::RemoveCommentsChar(const std::string &action) this->action_kind = 1; } -bool RemoveCommentsChar::transform(std::string &val, const Transaction *trans) const { - size_t i = 0; - std::string transformed_value; - transformed_value.reserve(val.size()); +bool RemoveCommentsChar::transform(std::string &value, const Transaction *trans) const { + char *d = value.data(); + const char *s = d; + const char *e = s + value.size(); - while (i < val.size()) { - if (val.at(i) == '/' - && (i+1 < val.size()) && val.at(i+1) == '*') { - i += 2; - } else if (val.at(i) == '*' - && (i+1 < val.size()) && val.at(i+1) == '/') { - i += 2; - } else if (val.at(i) == '<' - && (i+1 < val.size()) - && val.at(i+1) == '!' - && (i+2 < val.size()) - && val.at(i+2) == '-' - && (i+3 < val.size()) - && val.at(i+3) == '-') { - i += 4; - } else if (val.at(i) == '-' - && (i+1 < val.size()) && val.at(i+1) == '-' - && (i+2 < val.size()) && val.at(i+2) == '>') { - i += 3; - } else if (val.at(i) == '-' - && (i+1 < val.size()) && val.at(i+1) == '-') { - i += 2; - } else if (val.at(i) == '#') { - i += 1; + while (s < e) { + if (*s == '/' + && (s+1 < e) && *(s+1) == '*') { + s += 2; + } else if (*s == '*' + && (s+1 < e) && *(s+1) == '/') { + s += 2; + } else if (*s == '<' + && (s+1 < e) + && *(s+1) == '!' + && (s+2 < e) + && *(s+2) == '-' + && (s+3 < e) + && *(s+3) == '-') { + s += 4; + } else if (*s == '-' + && (s+1 < e) && *(s+1) == '-' + && (s+2 < e) && *(s+2) == '>') { + s += 3; + } else if (*s == '-' + && (s+1 < e) && *(s+1) == '-') { + s += 2; + } else if (*s == '#') { + s += 1; } else { - transformed_value += val.at(i); - i++; + *d++ = *s++; } } - const auto changed = transformed_value != val; - val = transformed_value; + const auto changed = d != s; + const auto new_len = d - value.c_str(); + value.resize(new_len); return changed; } diff --git a/src/actions/transformations/replace_comments.cc b/src/actions/transformations/replace_comments.cc index b1aeecf908..a6bab9727c 100644 --- a/src/actions/transformations/replace_comments.cc +++ b/src/actions/transformations/replace_comments.cc @@ -19,36 +19,28 @@ namespace modsecurity::actions::transformations { -ReplaceComments::ReplaceComments(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - - -bool ReplaceComments::transform(std::string &value, const Transaction *trans) const { - uint64_t i, j, incomment; - - char *input = reinterpret_cast( - malloc(sizeof(char) * value.size() + 1)); - memcpy(input, value.c_str(), value.size() + 1); - input[value.size()] = '\0'; - - i = j = incomment = 0; - while (i < value.size()) { - if (incomment == 0) { - if ((input[i] == '/') && (i + 1 < value.size()) +static inline bool inplace(std::string &value) { + auto input = reinterpret_cast(value.data()); + const auto input_len = value.length(); + bool changed = false, incomment = false; + std::string::size_type i = 0, j = 0; + + while (i < input_len) { + if (!incomment) { + if ((input[i] == '/') && (i + 1 < input_len) && (input[i + 1] == '*')) { - incomment = 1; + incomment = true; i += 2; + changed = true; } else { input[j] = input[i]; i++; j++; } } else { - if ((input[i] == '*') && (i + 1 < value.size()) + if ((input[i] == '*') && (i + 1 < input_len) && (input[i + 1] == '/')) { - incomment = 0; + incomment = false; i += 2; input[j] = ' '; j++; @@ -62,15 +54,19 @@ bool ReplaceComments::transform(std::string &value, const Transaction *trans) co input[j++] = ' '; } + value.resize(j); + return changed; +} - std::string resp; - resp.append(reinterpret_cast(input), j); - free(input); +ReplaceComments::ReplaceComments(const std::string &action) + : Transformation(action) { + this->action_kind = 1; +} - const auto changed = resp != value; - value = resp; - return changed; + +bool ReplaceComments::transform(std::string &value, const Transaction *trans) const { + return inplace(value); } From 2915ee60e23587e9e0ad4d1c1f13a43b9a208a63 Mon Sep 17 00:00:00 2001 From: Eduardo Arias Date: Mon, 19 Aug 2024 07:45:16 -0700 Subject: [PATCH 08/24] Perform Trim, TrimLeft & TrimRight transformations in-place --- src/actions/transformations/trim.cc | 45 ++++++++++++----------- src/actions/transformations/trim.h | 8 ++-- src/actions/transformations/trim_left.cc | 6 +-- src/actions/transformations/trim_right.cc | 6 +-- 4 files changed, 31 insertions(+), 34 deletions(-) diff --git a/src/actions/transformations/trim.cc b/src/actions/transformations/trim.cc index a551534676..bc90b4ecb6 100644 --- a/src/actions/transformations/trim.cc +++ b/src/actions/transformations/trim.cc @@ -15,36 +15,43 @@ #include "trim.h" +#include + namespace modsecurity::actions::transformations { -std::string *Trim::ltrim(std::string *s) { - s->erase( - s->begin(), - std::find_if(s->begin(), s->end(), [](unsigned char c) { +bool Trim::ltrim(std::string &s) { + auto it = std::find_if(s.begin(), s.end(), [](unsigned char c) { return !std::isspace(c); - }) - ); + }); + + const bool changed = it != s.begin(); + + s.erase(s.begin(), it); - return s; + return changed; } -std::string *Trim::rtrim(std::string *s) { - s->erase( - std::find_if(s->rbegin(), s->rend(), [](unsigned char c) { +bool Trim::rtrim(std::string &s) { + auto it = std::find_if(s.rbegin(), s.rend(), [](unsigned char c) { return !std::isspace(c); - }).base(), - s->end() - ); + }).base(); + + const bool changed = it != s.end(); - return s; + s.erase(it, s.end()); + + return changed; } -std::string *Trim::trim(std::string *s) { - return ltrim(rtrim(s)); +bool Trim::trim(std::string &s) { + bool changed = false; + changed |= rtrim(s); + changed |= ltrim(s); + return changed; } @@ -55,11 +62,7 @@ Trim::Trim(const std::string &action) bool Trim::transform(std::string &value, const Transaction *trans) const { - std::string ret(value); - this->trim(&ret); - const auto changed = ret != value; - value = ret; - return changed; + return trim(value); } diff --git a/src/actions/transformations/trim.h b/src/actions/transformations/trim.h index 3b0e82d94c..0e3d26f676 100644 --- a/src/actions/transformations/trim.h +++ b/src/actions/transformations/trim.h @@ -26,9 +26,11 @@ class Trim : public Transformation { bool transform(std::string &value, const Transaction *trans) const override; - static std::string *ltrim(std::string *s); - static std::string *rtrim(std::string *s); - static std::string *trim(std::string *s); + protected: + + static bool ltrim(std::string &s); + static bool rtrim(std::string &s); + static bool trim(std::string &s); }; } // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/trim_left.cc b/src/actions/transformations/trim_left.cc index c141727a7b..10276acff6 100644 --- a/src/actions/transformations/trim_left.cc +++ b/src/actions/transformations/trim_left.cc @@ -26,11 +26,7 @@ TrimLeft::TrimLeft(const std::string &action) } bool TrimLeft::transform(std::string &value, const Transaction *trans) const { - std::string ret(value); - this->ltrim(&ret); - const auto changed = ret != value; - value = ret; - return changed; + return ltrim(value); } diff --git a/src/actions/transformations/trim_right.cc b/src/actions/transformations/trim_right.cc index b95b63aad0..aa38c3488f 100644 --- a/src/actions/transformations/trim_right.cc +++ b/src/actions/transformations/trim_right.cc @@ -25,11 +25,7 @@ TrimRight::TrimRight(const std::string &action) } bool TrimRight::transform(std::string &value, const Transaction *trans) const { - std::string ret(value); - this->rtrim(&ret); - const auto changed = ret != value; - value = ret; - return changed; + return rtrim(value); } From fd8a979463c06a50ecd45687949a7a8a3e1cac90 Mon Sep 17 00:00:00 2001 From: Eduardo Arias Date: Mon, 19 Aug 2024 07:55:41 -0700 Subject: [PATCH 09/24] Perform SqlHexDecode transformation in-place - Validate buffer size before accessing data. The previous implementation would only check that there was a character available in the buffer but could continue processing/reading characters from an hex representation without checking bounds. - Removed inplace & mytolower helper functions from the class, as they're only referenced by the implementation. - Removed duplicate VALID_HEX & ISODIGIT macros, already in src/utils/string.h. --- src/actions/transformations/sql_hex_decode.cc | 97 +++++++------------ src/actions/transformations/sql_hex_decode.h | 9 -- 2 files changed, 34 insertions(+), 72 deletions(-) diff --git a/src/actions/transformations/sql_hex_decode.cc b/src/actions/transformations/sql_hex_decode.cc index 41189f9272..8f19e6197d 100644 --- a/src/actions/transformations/sql_hex_decode.cc +++ b/src/actions/transformations/sql_hex_decode.cc @@ -23,79 +23,50 @@ namespace modsecurity::actions::transformations { -#ifndef VALID_HEX -#define VALID_HEX(X) (((X >= '0') && (X <= '9')) \ - || ((X >= 'a') && (X <= 'f')) \ - || ((X >= 'A') && (X <= 'F'))) -#endif -#ifndef ISODIGIT -#define ISODIGIT(X) ((X >= '0') && (X <= '7')) -#endif - -bool SqlHexDecode::transform(std::string &value, const Transaction *trans) const { - std::string ret; - unsigned char *input; - int size = 0; - - input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); - - if (input == NULL) { - return ""; - } - - memcpy(input, value.c_str(), value.length()+1); - - size = inplace(input, value.length()); - - ret.assign(reinterpret_cast(input), size); - free(input); - - const auto changed = ret != value; - value = ret; - return changed; +static inline int mytolower(int ch) { + if (ch >= 'A' && ch <= 'Z') + return ('a' + ch - 'A'); + else + return ch; } - -int SqlHexDecode::inplace(unsigned char *data, int len) { - unsigned char *d, *begin = data; - int count = 0; - - if ((data == NULL) || (len == 0)) { - return 0; +static inline bool inplace(std::string &value) { + if (value.empty()) { + return false; } - for (d = data; (++count < len) && *data; *d++ = *data++) { - if (*data != '0') { - continue; + auto d = reinterpret_cast(value.data()); + const unsigned char *data = d; + const auto end = data + value.size(); + + bool changed = false; + + while (data < end) { + if (data + 3 < end + && *data == '0' + && mytolower(*(data + 1)) == 'x' + && VALID_HEX(*(data + 2)) && VALID_HEX(*(data + 3))) { + data += 2; // skip '0x' + do { + *d++ = utils::string::x2c(data); + data += 2; + } while ((data + 1 < end) && VALID_HEX(*data) && VALID_HEX(*(data + 1))); + changed = true; } - ++data; - ++count; - if (mytolower(*data) != 'x') { - data--; - count--; - continue; + else { + *d++ = *data++; } + } - data++; - ++count; + *d = '\0'; - // Do we need to keep "0x" if no hexa after? - if (!VALID_HEX(data[0]) || !VALID_HEX(data[1])) { - data -= 2; - count -= 2; - continue; - } + value.resize(d - reinterpret_cast(value.c_str())); + return changed; +} - while (VALID_HEX(data[0]) && VALID_HEX(data[1])) { - *d++ = utils::string::x2c(data); - data += 2; - count += 2; - } - } - *d = '\0'; - return strlen(reinterpret_cast(begin)); +bool SqlHexDecode::transform(std::string &value, const Transaction *trans) const { + return inplace(value); } diff --git a/src/actions/transformations/sql_hex_decode.h b/src/actions/transformations/sql_hex_decode.h index a92a0a2b49..44f45d172d 100644 --- a/src/actions/transformations/sql_hex_decode.h +++ b/src/actions/transformations/sql_hex_decode.h @@ -26,15 +26,6 @@ class SqlHexDecode : public Transformation { : Transformation(action) { } bool transform(std::string &value, const Transaction *trans) const override; - - static int inplace(unsigned char *data, int len); - - static int mytolower(int ch) { - if (ch >= 'A' && ch <= 'Z') - return ('a' + ch - 'A'); - else - return ch; - } }; } // namespace modsecurity::actions::transformations From 4670710376e9b80f2d1a151f627c08d3c086d0b7 Mon Sep 17 00:00:00 2001 From: Eduardo Arias Date: Mon, 19 Aug 2024 08:06:00 -0700 Subject: [PATCH 10/24] Perform LowerCase & UpperCase transformations in-place - Refactored to share implementation and reduce code duplication. --- src/actions/transformations/lower_case.cc | 16 ++++------------ src/actions/transformations/lower_case.h | 15 +++++++++++++++ src/actions/transformations/upper_case.cc | 19 +++++++------------ 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/actions/transformations/lower_case.cc b/src/actions/transformations/lower_case.cc index 0ea1864c2c..080429d952 100644 --- a/src/actions/transformations/lower_case.cc +++ b/src/actions/transformations/lower_case.cc @@ -16,7 +16,7 @@ #include "lower_case.h" -#include +#include namespace modsecurity::actions::transformations { @@ -26,17 +26,9 @@ LowerCase::LowerCase(const std::string &a) : Transformation(a) { } -bool LowerCase::transform(std::string &val, const Transaction *trans) const { - std::locale loc; - std::string value(val); - - for (std::string::size_type i=0; i < value.length(); ++i) { - value[i] = std::tolower(value[i], loc); - } - - const auto changed = val != value; - val = value; - return changed; +bool LowerCase::transform(std::string &value, const Transaction *trans) const { + return convert(value, [](auto c) { + return std::tolower(c); }); } diff --git a/src/actions/transformations/lower_case.h b/src/actions/transformations/lower_case.h index bbb51272f1..7bdf2d8443 100644 --- a/src/actions/transformations/lower_case.h +++ b/src/actions/transformations/lower_case.h @@ -18,6 +18,8 @@ #include "transformation.h" +#include + namespace modsecurity::actions::transformations { class LowerCase : public Transformation { @@ -25,6 +27,19 @@ class LowerCase : public Transformation { explicit LowerCase(const std::string &action); bool transform(std::string &value, const Transaction *trans) const override; + + template + static bool convert(std::string &val, Operation op) { + bool changed = false; + + std::transform(val.begin(), val.end(), val.data(), + [&](auto c) { + const auto nc = op(c); + if(nc != c) changed = true; + return nc; }); + + return changed; + } }; } // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/upper_case.cc b/src/actions/transformations/upper_case.cc index 2b8ad1d9b1..f811bcbbdb 100644 --- a/src/actions/transformations/upper_case.cc +++ b/src/actions/transformations/upper_case.cc @@ -16,7 +16,10 @@ #include "upper_case.h" -#include +#include + +#include "lower_case.h" + namespace modsecurity::actions::transformations { @@ -25,17 +28,9 @@ UpperCase::UpperCase(const std::string &a) : Transformation(a) { } -bool UpperCase::transform(std::string &val, const Transaction *trans) const { - std::string value(val); - std::locale loc; - - for (std::string::size_type i=0; i < value.length(); ++i) { - value[i] = std::toupper(value[i], loc); - } - - const auto changed = val != value; - val = value; - return changed; +bool UpperCase::transform(std::string &value, const Transaction *trans) const { + return LowerCase::convert(value, [](auto c) + { return std::toupper(c); }); } From e687140d0583ae5e85e248bdb364eec8b952a921 Mon Sep 17 00:00:00 2001 From: Eduardo Arias Date: Mon, 19 Aug 2024 08:12:00 -0700 Subject: [PATCH 11/24] Perform HexDecode transformation in-place - Removed inplace helper function from the class, as it's only referenced by the implementation. --- src/actions/transformations/hex_decode.cc | 44 +++++++---------------- src/actions/transformations/hex_decode.h | 2 -- 2 files changed, 12 insertions(+), 34 deletions(-) diff --git a/src/actions/transformations/hex_decode.cc b/src/actions/transformations/hex_decode.cc index 5866079bd6..1b43b6cdf2 100644 --- a/src/actions/transformations/hex_decode.cc +++ b/src/actions/transformations/hex_decode.cc @@ -21,46 +21,26 @@ namespace modsecurity::actions::transformations { -bool HexDecode::transform(std::string &value, const Transaction *trans) const { - std::string ret; - unsigned char *input; - int size = 0; +static inline int inplace(std::string &value) { + if (value.empty()) return false; - input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); + const auto len = value.length(); + auto d = reinterpret_cast(value.data()); + const auto data = d; - if (input == NULL) { - return ""; + for (int i = 0; i <= len - 2; i += 2) { + *d++ = utils::string::x2c(&data[i]); } - memcpy(input, value.c_str(), value.length()+1); - - size = inplace(input, value.length()); - - ret.assign(reinterpret_cast(input), size); - free(input); + *d = '\0'; - const auto changed = ret != value; - value = ret; - return changed; + value.resize(d - data); + return true; } -int HexDecode::inplace(unsigned char *data, int len) { - unsigned char *d = data; - int count = 0; - - if ((data == NULL) || (len == 0)) { - return 0; - } - - for (int i = 0;i <= len - 2;i += 2) { - *d++ = utils::string::x2c(&data[i]); - count++; - } - *d = '\0'; - - return count; +bool HexDecode::transform(std::string &value, const Transaction *trans) const { + return inplace(value); } diff --git a/src/actions/transformations/hex_decode.h b/src/actions/transformations/hex_decode.h index 4239c86d09..158f91aa15 100644 --- a/src/actions/transformations/hex_decode.h +++ b/src/actions/transformations/hex_decode.h @@ -26,8 +26,6 @@ class HexDecode : public Transformation { : Transformation(action) { } bool transform(std::string &value, const Transaction *trans) const override; - - static int inplace(unsigned char *data, int len); }; } // namespace modsecurity::actions::transformations From 727f2bf840dff972bd6ab41316884645171fedef Mon Sep 17 00:00:00 2001 From: Eduardo Arias Date: Mon, 19 Aug 2024 08:24:31 -0700 Subject: [PATCH 12/24] Perform CssDecode transformation in-place - Removed inplace helper function from the class, as it's only referenced by the implementation. --- src/actions/transformations/css_decode.cc | 50 ++++++++--------------- src/actions/transformations/css_decode.h | 2 - 2 files changed, 18 insertions(+), 34 deletions(-) diff --git a/src/actions/transformations/css_decode.cc b/src/actions/transformations/css_decode.cc index 7f6938acf4..c5de63f73a 100644 --- a/src/actions/transformations/css_decode.cc +++ b/src/actions/transformations/css_decode.cc @@ -21,25 +21,6 @@ namespace modsecurity::actions::transformations { -bool CssDecode::transform(std::string &value, const Transaction *trans) const { - - char *tmp = reinterpret_cast( - malloc(sizeof(char) * value.size() + 1)); - memcpy(tmp, value.c_str(), value.size() + 1); - tmp[value.size()] = '\0'; - - CssDecode::css_decode_inplace(reinterpret_cast(tmp), - value.size()); - - std::string ret(tmp, 0, value.size()); - free(tmp); - - const auto changed = ret != value; - value = ret; - return changed; -} - - /** * Decode a string that contains CSS-escaped characters. * @@ -47,15 +28,13 @@ bool CssDecode::transform(std::string &value, const Transaction *trans) const { * http://www.w3.org/TR/REC-CSS2/syndata.html#q4 * http://www.unicode.org/roadmaps/ */ -int CssDecode::css_decode_inplace(unsigned char *input, int64_t input_len) { - unsigned char *d = (unsigned char *)input; - int64_t i, j, count; +static inline bool css_decode_inplace(std::string &val) { + const auto input_len = val.length(); + auto input = reinterpret_cast(val.data()); + auto d = input; + bool changed = false; - if (input == NULL) { - return -1; - } - - i = count = 0; + std::string::size_type i = 0; while (i < input_len) { /* Is the character a backslash? */ if (input[i] == '\\') { @@ -64,7 +43,7 @@ int CssDecode::css_decode_inplace(unsigned char *input, int64_t input_len) { i++; /* We are not going to need the backslash. */ /* Check for 1-6 hex characters following the backslash */ - j = 0; + std::string::size_type j = 0; while ((j < 6) && (i + j < input_len) && (VALID_HEX(input[i + j]))) { @@ -146,37 +125,44 @@ int CssDecode::css_decode_inplace(unsigned char *input, int64_t input_len) { } /* Move over. */ - count++; i += j; + + changed = true; } else if (input[i] == '\n') { /* No hexadecimal digits after backslash */ /* A newline character following backslash is ignored. */ i++; + changed = true; } else { /* The character after backslash is not a hexadecimal digit, * nor a newline. */ /* Use one character after backslash as is. */ *d++ = input[i++]; - count++; } } else { /* No characters after backslash. */ /* Do not include backslash in output *(continuation to nothing) */ i++; + changed = true; } } else { /* Character is not a backslash. */ /* Copy one normal character to output. */ *d++ = input[i++]; - count++; } } /* Terminate output string. */ *d = '\0'; - return count; + val.resize(d - input); + return changed; +} + + +bool CssDecode::transform(std::string &value, const Transaction *trans) const { + return css_decode_inplace(value); } diff --git a/src/actions/transformations/css_decode.h b/src/actions/transformations/css_decode.h index 0441814952..67535a9a78 100644 --- a/src/actions/transformations/css_decode.h +++ b/src/actions/transformations/css_decode.h @@ -26,8 +26,6 @@ class CssDecode : public Transformation { : Transformation(action) { } bool transform(std::string &value, const Transaction *trans) const override; - - static int css_decode_inplace(unsigned char *input, int64_t input_len); }; } // namespace modsecurity::actions::transformations From a520369da025fe203c9302e643374eb5e76e0718 Mon Sep 17 00:00:00 2001 From: Eduardo Arias Date: Mon, 19 Aug 2024 08:28:04 -0700 Subject: [PATCH 13/24] Perform EscapeSeqDecode transformation in-place - Removed ansi_c_sequences_decode_inplace helper function from the class, as it's only referenced by the implementation. --- .../transformations/escape_seq_decode.cc | 35 ++++++------------- .../transformations/escape_seq_decode.h | 1 - 2 files changed, 11 insertions(+), 25 deletions(-) diff --git a/src/actions/transformations/escape_seq_decode.cc b/src/actions/transformations/escape_seq_decode.cc index a0dccb5393..290061447f 100644 --- a/src/actions/transformations/escape_seq_decode.cc +++ b/src/actions/transformations/escape_seq_decode.cc @@ -26,12 +26,13 @@ EscapeSeqDecode::EscapeSeqDecode(const std::string &action) } -int EscapeSeqDecode::ansi_c_sequences_decode_inplace(unsigned char *input, - int input_len) { - unsigned char *d = input; - int i, count; +static inline int ansi_c_sequences_decode_inplace(std::string &value) { + auto d = reinterpret_cast(value.data()); + const unsigned char* input = d; + const auto input_len = value.length(); - i = count = 0; + bool changed = false; + std::string::size_type i = 0; while (i < input_len) { if ((input[i] == '\\') && (i + 1 < input_len)) { int c = -1; @@ -109,42 +110,28 @@ int EscapeSeqDecode::ansi_c_sequences_decode_inplace(unsigned char *input, if (c == -1) { /* Didn't recognise encoding, copy raw bytes. */ *d++ = input[i + 1]; - count++; i += 2; } else { /* Converted the encoding. */ *d++ = c; - count++; } + + changed = true; } else { /* Input character not a backslash, copy it. */ *d++ = input[i++]; - count++; } } *d = '\0'; - return count; + value.resize(d - input); + return changed; } bool EscapeSeqDecode::transform(std::string &value, const Transaction *trans) const { - - unsigned char *tmp = (unsigned char *) malloc(sizeof(char) - * value.size() + 1); - memcpy(tmp, value.c_str(), value.size() + 1); - tmp[value.size()] = '\0'; - - int size = ansi_c_sequences_decode_inplace(tmp, value.size()); - - std::string ret(""); - ret.assign(reinterpret_cast(tmp), size); - free(tmp); - - const auto changed = ret != value; - value = ret; - return changed; + return ansi_c_sequences_decode_inplace(value); } diff --git a/src/actions/transformations/escape_seq_decode.h b/src/actions/transformations/escape_seq_decode.h index ab66464d6b..6a240715b3 100644 --- a/src/actions/transformations/escape_seq_decode.h +++ b/src/actions/transformations/escape_seq_decode.h @@ -25,7 +25,6 @@ class EscapeSeqDecode : public Transformation { explicit EscapeSeqDecode(const std::string &action); bool transform(std::string &value, const Transaction *trans) const override; - static int ansi_c_sequences_decode_inplace(unsigned char *input, int input_len); }; } // namespace modsecurity::actions::transformations From 7d5c9faa43252b6369db53691462d41b4e1f1ab4 Mon Sep 17 00:00:00 2001 From: Eduardo Arias Date: Mon, 19 Aug 2024 08:32:27 -0700 Subject: [PATCH 14/24] Perform JsDecode transformation in-place - Removed inplace helper function from the class, as it's only referenced by the implementation. --- src/actions/transformations/js_decode.cc | 52 ++++++++---------------- src/actions/transformations/js_decode.h | 1 - 2 files changed, 17 insertions(+), 36 deletions(-) diff --git a/src/actions/transformations/js_decode.cc b/src/actions/transformations/js_decode.cc index 5ed5715768..394a2cdcfd 100644 --- a/src/actions/transformations/js_decode.cc +++ b/src/actions/transformations/js_decode.cc @@ -21,35 +21,13 @@ namespace modsecurity::actions::transformations { -bool JsDecode::transform(std::string &value, const Transaction *trans) const { - std::string ret; - unsigned char *input; - - input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); - - if (input == NULL) { - return ""; - } - - memcpy(input, value.c_str(), value.length()+1); +static inline int inplace(std::string &value) { + auto d = reinterpret_cast(value.data()); + const unsigned char *input = d; + const auto input_len = value.length(); - size_t i = inplace(input, value.length()); - - ret.assign(reinterpret_cast(input), i); - free(input); - - const auto changed = ret != value; - value = ret; - return changed; -} - - -int JsDecode::inplace(unsigned char *input, uint64_t input_len) { - unsigned char *d = (unsigned char *)input; - int64_t i, count; - - i = count = 0; + bool changed = false; + std::string::size_type i = 0; while (i < input_len) { if (input[i] == '\\') { /* Character is an escape. */ @@ -70,14 +48,14 @@ int JsDecode::inplace(unsigned char *input, uint64_t input_len) { } d++; - count++; i += 6; + changed = true; } else if ((i + 3 < input_len) && (input[i + 1] == 'x') && VALID_HEX(input[i + 2]) && VALID_HEX(input[i + 3])) { /* \xHH */ *d++ = utils::string::x2c(&input[i + 2]); - count++; i += 4; + changed = true; } else if ((i + 1 < input_len) && ISODIGIT(input[i + 1])) { /* \OOO (only one byte, \000 - \377) */ char buf[4]; @@ -98,7 +76,7 @@ int JsDecode::inplace(unsigned char *input, uint64_t input_len) { } *d++ = (unsigned char)strtol(buf, NULL, 8); i += 1 + j; - count++; + changed = true; } } else if (i + 1 < input_len) { /* \C */ @@ -132,23 +110,27 @@ int JsDecode::inplace(unsigned char *input, uint64_t input_len) { *d++ = c; i += 2; - count++; + changed = true; } else { /* Not enough bytes */ while (i < input_len) { *d++ = input[i++]; - count++; } } } else { *d++ = input[i++]; - count++; } } *d = '\0'; - return count; + value.resize(d - input); + return changed; +} + + +bool JsDecode::transform(std::string &value, const Transaction *trans) const { + return inplace(value); } diff --git a/src/actions/transformations/js_decode.h b/src/actions/transformations/js_decode.h index b91ab9b83f..94156426ae 100644 --- a/src/actions/transformations/js_decode.h +++ b/src/actions/transformations/js_decode.h @@ -26,7 +26,6 @@ class JsDecode : public Transformation { : Transformation(action) { } bool transform(std::string &value, const Transaction *trans) const override; - static int inplace(unsigned char *input, uint64_t input_len); }; } // namespace modsecurity::actions::transformations From 8bf4d96e6b3604860586251f098ba5ade3f9b67d Mon Sep 17 00:00:00 2001 From: Eduardo Arias Date: Mon, 19 Aug 2024 09:04:42 -0700 Subject: [PATCH 15/24] Perform HtmlEntityDecode transformation in-place - Removed inplace helper function from the class, as it's only referenced by the implementation. --- .../transformations/html_entity_decode.cc | 106 +++++++----------- .../transformations/html_entity_decode.h | 2 - 2 files changed, 38 insertions(+), 70 deletions(-) diff --git a/src/actions/transformations/html_entity_decode.cc b/src/actions/transformations/html_entity_decode.cc index a730f1604f..0b9d811b3b 100644 --- a/src/actions/transformations/html_entity_decode.cc +++ b/src/actions/transformations/html_entity_decode.cc @@ -27,47 +27,21 @@ namespace modsecurity::actions::transformations { -bool HtmlEntityDecode::transform(std::string &value, const Transaction *trans) const { - std::string ret; - unsigned char *input; - - input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); - - if (input == NULL) { - return ""; - } - - memcpy(input, value.c_str(), value.length()+1); - - size_t i = inplace(input, value.length()); - - ret.assign(reinterpret_cast(input), i); - free(input); - - const auto changed = ret != value; - value = ret; - return changed; -} - +static inline bool inplace(std::string &value) { + const auto input_len = value.length(); + auto d = reinterpret_cast(value.data()); + const unsigned char *input = d; + const unsigned char *end = input + input_len; -int HtmlEntityDecode::inplace(unsigned char *input, uint64_t input_len) { - unsigned char *d = input; - int i, count; - - if ((input == NULL) || (input_len == 0)) { - return 0; - } - - i = count = 0; - while ((i < input_len) && (count < input_len)) { - int z, copy = 1; + std::string::size_type i = 0; + while (i < input_len) { + std::string::size_type copy = 1; /* Require an ampersand and at least one character to * start looking into the entity. */ if ((input[i] == '&') && (i + 1 < input_len)) { - int k, j = i + 1; + auto j = i + 1; if (input[j] == '#') { /* Numerical entity. */ @@ -87,19 +61,18 @@ int HtmlEntityDecode::inplace(unsigned char *input, uint64_t input_len) { } j++; /* j is the position of the first digit now. */ - k = j; - while ((j < input_len) && (isxdigit(input[j]))) { + constexpr int MAX_HEX_DIGITS = 2; // supports only bytes (max value 0xff) + auto k = j; + while ((j - k < MAX_HEX_DIGITS) && (j < input_len) && (isxdigit(input[j]))) { j++; } if (j > k) { /* Do we have at least one digit? */ /* Decode the entity. */ - char *x; - x = reinterpret_cast(calloc(sizeof(char), - ((j - k) + 1))); + char x[MAX_HEX_DIGITS + 1]; memcpy(x, (const char *)&input[k], j - k); - *d++ = (unsigned char)strtol(x, NULL, 16); - free(x); - count++; + x[j - k] = '\0'; + + *d++ = (unsigned char)strtol(x, nullptr, 16); /* Skip over the semicolon if it's there. */ if ((j < input_len) && (input[j] == ';')) { @@ -113,19 +86,18 @@ int HtmlEntityDecode::inplace(unsigned char *input, uint64_t input_len) { } } else { /* Decimal entity. */ - k = j; - while ((j < input_len) && (isdigit(input[j]))) { + constexpr int MAX_DEC_DIGITS = 3; // supports only bytes (max value 255) + auto k = j; + while ((j - k < MAX_DEC_DIGITS) && (j < input_len) && (isdigit(input[j]))) { j++; } if (j > k) { /* Do we have at least one digit? */ /* Decode the entity. */ - char *x; - x = reinterpret_cast(calloc(sizeof(char), - ((j - k) + 1))); + char x[MAX_DEC_DIGITS + 1]; memcpy(x, (const char *)&input[k], j - k); - *d++ = (unsigned char)strtol(x, NULL, 10); - free(x); - count++; + x[j - k] = '\0'; + + *d++ = (unsigned char)strtol(x, nullptr, 10); /* Skip over the semicolon if it's there. */ if ((j < input_len) && (input[j] == ';')) { @@ -140,38 +112,31 @@ int HtmlEntityDecode::inplace(unsigned char *input, uint64_t input_len) { } } else { /* Text entity. */ - k = j; + auto k = j; while ((j < input_len) && (isalnum(input[j]))) { j++; } if (j > k) { /* Do we have at least one digit? */ - char *x; - x = reinterpret_cast(calloc(sizeof(char), - ((j - k) + 1))); - memcpy(x, (const char *)&input[k], j - k); + const auto x = reinterpret_cast(&input[k]); /* Decode the entity. */ /* ENH What about others? */ - if (strcasecmp(x, "quot") == 0) { + if (strncasecmp(x, "quot", 4) == 0) { *d++ = '"'; - } else if (strcasecmp(x, "amp") == 0) { + } else if (strncasecmp(x, "amp", 3) == 0) { *d++ = '&'; - } else if (strcasecmp(x, "lt") == 0) { + } else if (strncasecmp(x, "lt", 2) == 0) { *d++ = '<'; - } else if (strcasecmp(x, "gt") == 0) { + } else if (strncasecmp(x, "gt", 2) == 0) { *d++ = '>'; - } else if (strcasecmp(x, "nbsp") == 0) { + } else if (strncasecmp(x, "nbsp", 4) == 0) { *d++ = NBSP; } else { /* We do no want to convert this entity, * copy the raw data over. */ copy = j - k + 1; - free(x); goto HTML_ENT_OUT; } - free(x); - - count++; /* Skip over the semicolon if it's there. */ if ((j < input_len) && (input[j] == ';')) { @@ -187,15 +152,20 @@ int HtmlEntityDecode::inplace(unsigned char *input, uint64_t input_len) { HTML_ENT_OUT: - for (z = 0; ((z < copy) && (count < input_len)); z++) { + for (auto z = 0; z < copy; z++) { *d++ = input[i++]; - count++; } } *d = '\0'; - return count; + value.resize(d - input); + return d != end; +} + + +bool HtmlEntityDecode::transform(std::string &value, const Transaction *trans) const { + return inplace(value); } diff --git a/src/actions/transformations/html_entity_decode.h b/src/actions/transformations/html_entity_decode.h index 558da5b975..5c17333a97 100644 --- a/src/actions/transformations/html_entity_decode.h +++ b/src/actions/transformations/html_entity_decode.h @@ -26,8 +26,6 @@ class HtmlEntityDecode : public Transformation { : Transformation(action) { } bool transform(std::string &value, const Transaction *trans) const override; - - static int inplace(unsigned char *input, uint64_t input_len); }; } // namespace modsecurity::actions::transformations From 17a2cbd164bbfc06c09a84ce35206db57da71c53 Mon Sep 17 00:00:00 2001 From: Eduardo Arias Date: Mon, 19 Aug 2024 09:12:12 -0700 Subject: [PATCH 16/24] Perform UrlDecodeUni & UrlDecode transformations in-place - Use std::string in UrlEncode transformation, instead of manually memory management. This avoids an additional copy after completing encoding by just swapping the encoded value and the input. - Removed inplace helper function from the class, as it's only referenced by the implementation. --- src/actions/transformations/url_decode.cc | 27 ++++------ src/actions/transformations/url_decode_uni.cc | 54 +++++++------------ src/actions/transformations/url_decode_uni.h | 2 - src/actions/transformations/url_encode.cc | 54 ++++++------------- src/actions/transformations/url_encode.h | 3 -- 5 files changed, 43 insertions(+), 97 deletions(-) diff --git a/src/actions/transformations/url_decode.cc b/src/actions/transformations/url_decode.cc index 7e5f87676f..6f23102204 100644 --- a/src/actions/transformations/url_decode.cc +++ b/src/actions/transformations/url_decode.cc @@ -27,25 +27,16 @@ UrlDecode::UrlDecode(const std::string &action) } bool UrlDecode::transform(std::string &value, const Transaction *trans) const { - unsigned char *val(NULL); int invalid_count = 0; - int _changed; - - val = (unsigned char *) malloc(sizeof(char) * value.size() + 1); - memcpy(val, value.c_str(), value.size() + 1); - val[value.size()] = '\0'; - - int size = utils::urldecode_nonstrict_inplace(val, value.size(), - &invalid_count, &_changed); - std::string out; - - out.append((const char *)val, size); - - free(val); - - const auto changed = out != value; - value = out; - return changed; + int changed; + const auto new_len = utils::urldecode_nonstrict_inplace( + (unsigned char*)value.data(), + value.length(), + &invalid_count, + &changed); + + value.resize(new_len); + return changed != 0; } diff --git a/src/actions/transformations/url_decode_uni.cc b/src/actions/transformations/url_decode_uni.cc index fdc2e79b56..57df7a566f 100644 --- a/src/actions/transformations/url_decode_uni.cc +++ b/src/actions/transformations/url_decode_uni.cc @@ -22,41 +22,19 @@ namespace modsecurity::actions::transformations { -bool UrlDecodeUni::transform(std::string &value, const Transaction *t) const { - std::string ret; - unsigned char *input; - - input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); - - if (input == NULL) { - return ""; - } - - memcpy(input, value.c_str(), value.length()+1); - - size_t i = inplace(input, value.length(), t); - - ret.assign(reinterpret_cast(input), i); - free(input); - - const auto changed = ret != value; - value = ret; - return changed; -} - - /** * * IMP1 Assumes NUL-terminated */ -int UrlDecodeUni::inplace(unsigned char *input, uint64_t input_len, +static inline bool inplace(std::string &value, const Transaction *t) { - unsigned char *d = input; - int64_t i, count, fact, j, xv; - int Code, hmap = -1; + bool changed = false; + auto d = reinterpret_cast(value.data()); + const unsigned char *input = d; + const auto input_len = value.length(); - if (input == NULL) return -1; + std::string::size_type i, count, fact, j, xv; + int Code, hmap = -1; i = count = 0; while (i < input_len) { @@ -116,19 +94,17 @@ int UrlDecodeUni::inplace(unsigned char *input, uint64_t input_len, } } d++; - count++; i += 6; + changed = true; } else { /* Invalid data, skip %u. */ *d++ = input[i++]; *d++ = input[i++]; - count += 2; } } else { /* Not enough bytes (4 data bytes), skip %u. */ *d++ = input[i++]; *d++ = input[i++]; - count += 2; } } else { /* Standard URL encoding. */ @@ -143,8 +119,8 @@ int UrlDecodeUni::inplace(unsigned char *input, uint64_t input_len, if (VALID_HEX(c1) && VALID_HEX(c2)) { *d++ = utils::string::x2c(&input[i + 1]); - count++; i += 3; + changed = true; } else { /* Not a valid encoding, skip this % */ *d++ = input[i++]; @@ -153,25 +129,31 @@ int UrlDecodeUni::inplace(unsigned char *input, uint64_t input_len, } else { /* Not enough bytes available, skip this % */ *d++ = input[i++]; - count++; } } } else { /* Character is not a percent sign. */ if (input[i] == '+') { *d++ = ' '; + changed = true; } else { *d++ = input[i]; } - count++; i++; } } *d = '\0'; - return count; + value.resize(d - input); + return changed; +} + + + +bool UrlDecodeUni::transform(std::string &value, const Transaction *trans) const { + return inplace(value, trans); } diff --git a/src/actions/transformations/url_decode_uni.h b/src/actions/transformations/url_decode_uni.h index 3196285127..8dbac4627b 100644 --- a/src/actions/transformations/url_decode_uni.h +++ b/src/actions/transformations/url_decode_uni.h @@ -26,8 +26,6 @@ class UrlDecodeUni : public Transformation { : Transformation(action) { } bool transform(std::string &value, const Transaction *trans) const override; - static int inplace(unsigned char *input, uint64_t input_len, - const Transaction *transaction); }; } // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/url_encode.cc b/src/actions/transformations/url_encode.cc index e7f59f85af..36fef77117 100644 --- a/src/actions/transformations/url_encode.cc +++ b/src/actions/transformations/url_encode.cc @@ -26,64 +26,42 @@ UrlEncode::UrlEncode(const std::string &action) } -std::string UrlEncode::url_enc(const char *input, - unsigned int input_len, int *changed) { - char *rval, *d; - unsigned int i, len; - int count = 0; +static inline bool url_enc(std::string &value) { + const auto len = value.size() * 3 + 1; + std::string ret(len, {}); - *changed = 0; - - len = input_len * 3 + 1; - d = rval = reinterpret_cast(malloc(len)); - if (rval == NULL) { - return {}; - } + bool changed = false; /* ENH Only encode the characters that really need to be encoded. */ - for (i = 0; i < input_len; i++) { - unsigned char c = input[i]; - + char *d = ret.data(); + for (const auto c : value) { if (c == ' ') { *d++ = '+'; - *changed = 1; - count++; + changed = true; } else { if ( (c == 42) || ((c >= 48) && (c <= 57)) || ((c >= 65) && (c <= 90)) || ((c >= 97) && (c <= 122))) { *d++ = c; - count++; - } else { + } + else + { *d++ = '%'; - count++; - utils::string::c2x(c, (unsigned char *)d); - d += 2; - count++; - count++; - *changed = 1; + d = (char *)utils::string::c2x(c, (unsigned char *)d); + changed = true; } } } - *d = '\0'; - - std::string ret(""); - ret.append(rval, count); - free(rval); - return ret; + ret.resize(d - ret.c_str()); + std::swap(value, ret); + return changed; } bool UrlEncode::transform(std::string &value, const Transaction *trans) const { - int _changed; - - std::string ret = url_enc(value.c_str(), value.size(), &_changed); - - const auto changed = ret != value; - value = ret; - return changed; + return url_enc(value); } diff --git a/src/actions/transformations/url_encode.h b/src/actions/transformations/url_encode.h index b300c40da0..4f3ffe7305 100644 --- a/src/actions/transformations/url_encode.h +++ b/src/actions/transformations/url_encode.h @@ -25,9 +25,6 @@ class UrlEncode : public Transformation { explicit UrlEncode(const std::string &action); bool transform(std::string &value, const Transaction *trans) const override; - - static std::string url_enc(const char *input, - unsigned int input_len, int *changed); }; } // namespace modsecurity::actions::transformations From 2c3c2287259b68206141efb6bc270ddd83727654 Mon Sep 17 00:00:00 2001 From: Eduardo Arias Date: Mon, 19 Aug 2024 10:15:12 -0700 Subject: [PATCH 17/24] Perform Utf8ToUnicode transformation in-place - Removed inplace helper function from the class, as it's only referenced by the implementation. --- .../transformations/utf8_to_unicode.cc | 85 +++++++------------ src/actions/transformations/utf8_to_unicode.h | 9 -- 2 files changed, 29 insertions(+), 65 deletions(-) diff --git a/src/actions/transformations/utf8_to_unicode.cc b/src/actions/transformations/utf8_to_unicode.cc index 2f40ce60b4..4b01583e7c 100644 --- a/src/actions/transformations/utf8_to_unicode.cc +++ b/src/actions/transformations/utf8_to_unicode.cc @@ -20,67 +20,33 @@ #include "src/utils/string.h" -namespace modsecurity::actions::transformations { - - -bool Utf8ToUnicode::transform(std::string &value, const Transaction *trans) const { - std::string ret; - unsigned char *input; - int _changed = 0; - char *out; - - input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); +constexpr int UNICODE_ERROR_CHARACTERS_MISSING = -1; +constexpr int UNICODE_ERROR_INVALID_ENCODING = -2; - if (input == NULL) { - return ""; - } - - memcpy(input, value.c_str(), value.length()+1); - out = inplace(input, value.size() + 1, &_changed); - free(input); - if (out != NULL) { - ret.assign(reinterpret_cast(out), - strlen(reinterpret_cast(out))); - free(out); - } +namespace modsecurity::actions::transformations { - const auto changed = ret != value; - value = ret; - return changed; -} +static inline bool encode(std::string &value) { + auto input = reinterpret_cast(value.data()); + const auto input_len = value.length(); -char *Utf8ToUnicode::inplace(unsigned char *input, - uint64_t input_len, int *changed) { - unsigned int count = 0; - char *data; - char *data_orig; - unsigned int i, len, j; - unsigned int bytes_left = input_len; + bool changed = false; + std::string::size_type count = 0; + auto bytes_left = input_len; unsigned char unicode[8]; - *changed = 0; /* RFC3629 states that UTF-8 are encoded using sequences of 1 to 4 octets. */ /* Max size per character should fit in 4 bytes */ - len = input_len * 4 + 1; - data = reinterpret_cast(malloc(sizeof(char) * len)); - if (data == NULL) { - return NULL; - } - data_orig = data; + const auto len = input_len * 4 + 1; + std::string ret(len, {}); + auto data = ret.data(); - if (input == NULL) { - free(data); - return NULL; - } - - for (i = 0; i < bytes_left;) { + for (std::string::size_type i = 0; i < bytes_left;) { int unicode_len = 0; unsigned int d = 0; unsigned char c; - unsigned char *utf = (unsigned char *)&input[i]; + auto utf = &input[i]; c = *utf; @@ -108,7 +74,7 @@ char *Utf8ToUnicode::inplace(unsigned char *input, unicode_len = UNICODE_ERROR_INVALID_ENCODING; } else { unicode_len = 2; - count+=6; + count += 6; if (count <= len) { int length = 0; /* compute character number */ @@ -138,11 +104,11 @@ char *Utf8ToUnicode::inplace(unsigned char *input, break; } - for (j = 0; j < length; j++) { + for (std::string::size_type j = 0; j < length; j++) { *data++ = unicode[j]; } - *changed = 1; + changed = true; } } } else if ((c & 0xF0) == 0xE0) { @@ -190,11 +156,11 @@ char *Utf8ToUnicode::inplace(unsigned char *input, break; } - for (j = 0; j < length; j++) { + for (std::string::size_type j = 0; j < length; j++) { *data++ = unicode[j]; } - *changed = 1; + changed = true; } } } else if ((c & 0xF8) == 0xF0) { @@ -252,11 +218,11 @@ char *Utf8ToUnicode::inplace(unsigned char *input, break; } - for (j = 0; j < length; j++) { + for (std::string::size_type j = 0; j < length; j++) { *data++ = unicode[j]; } - *changed = 1; + changed = true; } } } else { @@ -300,7 +266,14 @@ char *Utf8ToUnicode::inplace(unsigned char *input, *data ='\0'; - return data_orig; + ret.resize(data - ret.c_str()); + std::swap(value, ret); + return changed; +} + + +bool Utf8ToUnicode::transform(std::string &value, const Transaction *trans) const { + return encode(value); } diff --git a/src/actions/transformations/utf8_to_unicode.h b/src/actions/transformations/utf8_to_unicode.h index 83aba8199a..bbb6cdc4de 100644 --- a/src/actions/transformations/utf8_to_unicode.h +++ b/src/actions/transformations/utf8_to_unicode.h @@ -18,12 +18,6 @@ #include "transformation.h" -#define UNICODE_ERROR_CHARACTERS_MISSING -1 -#define UNICODE_ERROR_INVALID_ENCODING -2 -#define UNICODE_ERROR_OVERLONG_CHARACTER -3 -#define UNICODE_ERROR_RESTRICTED_CHARACTER -4 -#define UNICODE_ERROR_DECODING_ERROR -5 - namespace modsecurity::actions::transformations { class Utf8ToUnicode : public Transformation { @@ -32,9 +26,6 @@ class Utf8ToUnicode : public Transformation { : Transformation(action) { } bool transform(std::string &value, const Transaction *trans) const override; - - static char *inplace(unsigned char *input, uint64_t input_len, - int *changed); }; } // namespace modsecurity::actions::transformations From 021d0caa335637b493b9a1e45e2273c64659694f Mon Sep 17 00:00:00 2001 From: Eduardo Arias Date: Mon, 19 Aug 2024 10:20:12 -0700 Subject: [PATCH 18/24] Perform NormalisePath & NormalisePathWin transformations in-place --- src/actions/transformations/normalise_path.cc | 60 +++++++------------ src/actions/transformations/normalise_path.h | 3 +- .../transformations/normalise_path_win.cc | 19 +----- 3 files changed, 24 insertions(+), 58 deletions(-) diff --git a/src/actions/transformations/normalise_path.cc b/src/actions/transformations/normalise_path.cc index c663b98a6f..dd2b64d2ac 100644 --- a/src/actions/transformations/normalise_path.cc +++ b/src/actions/transformations/normalise_path.cc @@ -25,23 +25,7 @@ NormalisePath::NormalisePath(const std::string &action) } bool NormalisePath::transform(std::string &value, const Transaction *trans) const { - int _changed = 0; - - char *tmp = reinterpret_cast( - malloc(sizeof(char) * value.size() + 1)); - memcpy(tmp, value.c_str(), value.size() + 1); - tmp[value.size()] = '\0'; - - int i = normalize_path_inplace((unsigned char *)tmp, - value.size(), 0, &_changed); - - std::string ret(""); - ret.assign(tmp, i); - free(tmp); - - const auto changed = ret != value; - value = ret; - return changed; + return normalize_path_inplace(value, false); } @@ -49,21 +33,22 @@ bool NormalisePath::transform(std::string &value, const Transaction *trans) cons * * IMP1 Assumes NUL-terminated */ -int NormalisePath::normalize_path_inplace(unsigned char *input, int input_len, - int win, int *changed) { +bool NormalisePath::normalize_path_inplace(std::string &val, const bool win) { unsigned char *src; unsigned char *dst; unsigned char *end; - int ldst = 0; int hitroot = 0; int done = 0; int relative; int trailing; - *changed = 0; + bool changed = false; /* Need at least one byte to normalize */ - if (input_len <= 0) return 0; + if(val.empty()) return false; + + auto input = reinterpret_cast(val.data()); + const auto input_len = val.length(); /* * ENH: Deal with UNC and drive letters? @@ -71,7 +56,6 @@ int NormalisePath::normalize_path_inplace(unsigned char *input, int input_len, src = dst = input; end = input + (input_len - 1); - ldst = 1; relative = ((*input == '/') || (win && (*input == '\\'))) ? 0 : 1; trailing = ((*end == '/') || (win && (*end == '\\'))) ? 1 : 0; @@ -82,11 +66,11 @@ int NormalisePath::normalize_path_inplace(unsigned char *input, int input_len, if (win) { if (*src == '\\') { *src = '/'; - *changed = 1; + changed = true; } if ((src < end) && (*(src + 1) == '\\')) { *(src + 1) = '/'; - *changed = 1; + changed = true; } } @@ -104,7 +88,7 @@ int NormalisePath::normalize_path_inplace(unsigned char *input, int input_len, /* Could it be an empty path segment? */ if ((src != end) && *src == '/') { /* Ignore */ - *changed = 1; + changed = true; goto copy; /* Copy will take care of this. */ } else if (*src == '.') { /* Could it be a back or self reference? */ @@ -141,25 +125,25 @@ int NormalisePath::normalize_path_inplace(unsigned char *input, int input_len, } } - if (done) goto length; /* Skip the copy. */ + if (done) goto skip_copy; /* Skip the copy. */ src++; - *changed = 1; + changed = true; } else if (dst == input) { /* Relative Self-reference? */ - *changed = 1; + changed = true; /* Ignore. */ - if (done) goto length; /* Skip the copy. */ + if (done) goto skip_copy; /* Skip the copy. */ src++; } else if (*(dst - 1) == '/') { /* Self-reference? */ - *changed = 1; + changed = true; /* Ignore. */ - if (done) goto length; /* Skip the copy. */ + if (done) goto skip_copy; /* Skip the copy. */ dst--; src++; } @@ -179,7 +163,7 @@ int NormalisePath::normalize_path_inplace(unsigned char *input, int input_len, && ((*(src + 1) == '/') || (win && (*(src + 1) == '\\'))) ) { src++; } - if (oldsrc != src) *changed = 1; + if (oldsrc != src) changed = true; /* Do not copy the forward slash to the root * if it is not a relative path. Instead @@ -187,27 +171,27 @@ int NormalisePath::normalize_path_inplace(unsigned char *input, int input_len, */ if (relative && (dst == input)) { src++; - goto length; /* Skip the copy */ + goto skip_copy; /* Skip the copy */ } } *(dst++) = *(src++); -length: - ldst = (dst - input); +skip_copy: + ; // nop for the goto label to work } /* Make sure that there is not a trailing slash in the * normalized form if there was not one in the original form. */ if (!trailing && (dst > input) && *(dst - 1) == '/') { - ldst--; dst--; } /* Always NUL terminate */ *dst = '\0'; - return ldst; + val.resize(dst - input); + return changed; } diff --git a/src/actions/transformations/normalise_path.h b/src/actions/transformations/normalise_path.h index d5b84085d6..248def7f19 100644 --- a/src/actions/transformations/normalise_path.h +++ b/src/actions/transformations/normalise_path.h @@ -26,8 +26,7 @@ class NormalisePath : public Transformation { bool transform(std::string &value, const Transaction *trans) const override; - static int normalize_path_inplace(unsigned char *input, int input_len, - int win, int *changed); + static bool normalize_path_inplace(std::string &val, const bool win); }; } // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/normalise_path_win.cc b/src/actions/transformations/normalise_path_win.cc index 49f6989fc0..b60943e155 100644 --- a/src/actions/transformations/normalise_path_win.cc +++ b/src/actions/transformations/normalise_path_win.cc @@ -22,24 +22,7 @@ namespace modsecurity::actions::transformations { bool NormalisePathWin::transform(std::string &value, const Transaction *trans) const { - int _changed; - - char *tmp = reinterpret_cast( - malloc(sizeof(char) * value.size() + 1)); - memcpy(tmp, value.c_str(), value.size() + 1); - tmp[value.size()] = '\0'; - - int i = NormalisePath::normalize_path_inplace( - reinterpret_cast(tmp), - value.size(), 1, &_changed); - - std::string ret(""); - ret.assign(tmp, i); - free(tmp); - - const auto changed = ret != value; - value = ret; - return changed; + return NormalisePath::normalize_path_inplace(value, true); } From b647dbd905302cf85f7eb8d6e83813229ef8dc58 Mon Sep 17 00:00:00 2001 From: Eduardo Arias Date: Sat, 1 Jun 2024 21:59:16 +0000 Subject: [PATCH 19/24] Remove unnecessary heap-allocation & copy in Transaction::extractArguments - utils::urldecode_nonstrict_inplace decodes inplace so key & value, which are values returned by utils::string::ssplit_pair can be just be modified and do not need to be copied. - Updated signature of utils::urldecode_nonstrict_inplace, as its two callers already have std::string values. --- src/actions/transformations/url_decode.cc | 12 +---- src/transaction.cc | 48 +++++------------- src/utils/decode.cc | 62 ++++++++++------------- src/utils/decode.h | 4 +- 4 files changed, 43 insertions(+), 83 deletions(-) diff --git a/src/actions/transformations/url_decode.cc b/src/actions/transformations/url_decode.cc index 6f23102204..c67e9fa6ba 100644 --- a/src/actions/transformations/url_decode.cc +++ b/src/actions/transformations/url_decode.cc @@ -27,16 +27,8 @@ UrlDecode::UrlDecode(const std::string &action) } bool UrlDecode::transform(std::string &value, const Transaction *trans) const { - int invalid_count = 0; - int changed; - const auto new_len = utils::urldecode_nonstrict_inplace( - (unsigned char*)value.data(), - value.length(), - &invalid_count, - &changed); - - value.resize(new_len); - return changed != 0; + int invalid_count; + return utils::urldecode_nonstrict_inplace(value, invalid_count); } diff --git a/src/transaction.cc b/src/transaction.cc index f69df1887a..8c9dd669d9 100644 --- a/src/transaction.cc +++ b/src/transaction.cc @@ -348,46 +348,22 @@ bool Transaction::extractArguments(const std::string &orig, if (m_rules->m_secArgumentSeparator.m_set) { sep1 = m_rules->m_secArgumentSeparator.m_value.at(0); } - std::vector key_value_sets = utils::string::ssplit(buf, sep1); - - for (std::string t : key_value_sets) { - char sep2 = '='; - size_t key_s = 0; - size_t value_s = 0; - int invalid = 0; - int changed = 0; - - std::string key; - std::string value; - std::pair key_value_pair = utils::string::ssplit_pair(t, sep2); - key = key_value_pair.first; - value = key_value_pair.second; - - key_s = (key.length() + 1); - value_s = (value.length() + 1); - unsigned char *key_c = reinterpret_cast( - calloc(sizeof(char), key_s)); - unsigned char *value_c = reinterpret_cast( - calloc(sizeof(char), value_s)); - - memcpy(key_c, key.c_str(), key_s); - memcpy(value_c, value.c_str(), value_s); - - key_s = utils::urldecode_nonstrict_inplace(key_c, key_s, - &invalid, &changed); - value_s = utils::urldecode_nonstrict_inplace(value_c, value_s, - &invalid, &changed); - - if (invalid) { + const auto key_value_sets = utils::string::ssplit(buf, sep1); + + for (const auto &t : key_value_sets) { + const auto sep2 = '='; + auto [key, value] = utils::string::ssplit_pair(t, sep2); + + int invalid_count; + utils::urldecode_nonstrict_inplace(key, invalid_count); + utils::urldecode_nonstrict_inplace(value, invalid_count); + + if (invalid_count > 0) { m_variableUrlEncodedError.set("1", m_variableOffset); } - addArgument(orig, std::string(reinterpret_cast(key_c), key_s-1), - std::string(reinterpret_cast(value_c), value_s-1), offset); + addArgument(orig, key, value, offset); offset = offset + t.size() + 1; - - free(key_c); - free(value_c); } return true; diff --git a/src/utils/decode.cc b/src/utils/decode.cc index 8629f8fb0c..32d95301e7 100644 --- a/src/utils/decode.cc +++ b/src/utils/decode.cc @@ -22,63 +22,55 @@ namespace modsecurity { namespace utils { -int urldecode_nonstrict_inplace(unsigned char *input, - uint64_t input_len, int *invalid_count, int *changed) { - unsigned char *d = (unsigned char *)input; - uint64_t i, count; +bool urldecode_nonstrict_inplace(std::string &val, + int &invalid_count) { + unsigned char *d = (unsigned char *)val.data(); + unsigned char *s = d; + const unsigned char *e = s + val.size(); - *changed = 0; + invalid_count = 0; + bool changed = false; - if (input == NULL) { - return -1; - } - - i = count = 0; - while (i < input_len) { - if (input[i] == '%') { + while (s != e) { + if (*s == '%') { /* Character is a percent sign. */ /* Are there enough bytes available? */ - if (i + 2 < input_len) { - char c1 = input[i + 1]; - char c2 = input[i + 2]; + if (s + 2 < e) { + const auto c1 = *(s + 1); + const auto c2 = *(s + 2); if (VALID_HEX(c1) && VALID_HEX(c2)) { - uint64_t uni = string::x2c(&input[i + 1]); + const auto uni = string::x2c(s + 1); - *d++ = (wchar_t)uni; - count++; - i += 3; - *changed = 1; + *d++ = uni; + s += 3; + changed = true; } else { /* Not a valid encoding, skip this % */ - *d++ = input[i++]; - count++; - (*invalid_count)++; + *d++ = *s++; + invalid_count++; } } else { /* Not enough bytes available, copy the raw bytes. */ - *d++ = input[i++]; - count++; - (*invalid_count)++; + *d++ = *s++; + invalid_count++; } } else { /* Character is not a percent sign. */ - if (input[i] == '+') { + if (*s == '+') { *d++ = ' '; - *changed = 1; + changed = true; } else { - *d++ = input[i]; + *d++ = *s; } - count++; - i++; + s++; } } -#if 0 - *d = '\0'; -#endif + if (changed) + val.resize((char*) d - val.c_str()); - return count; + return changed; } diff --git a/src/utils/decode.h b/src/utils/decode.h index e0e31bcbf9..d80a55d5b8 100644 --- a/src/utils/decode.h +++ b/src/utils/decode.h @@ -29,8 +29,8 @@ namespace modsecurity { namespace utils { -int urldecode_nonstrict_inplace(unsigned char *input, - uint64_t input_len, int *invalid_count, int *changed); +bool urldecode_nonstrict_inplace(std::string &val, + int &invalid_count); std::string uri_decode(const std::string & sSrc); From 34da8eeeee3f3272c7e8e0b8846ef7d1e7f4e47e Mon Sep 17 00:00:00 2001 From: Eduardo Arias Date: Fri, 9 Aug 2024 13:03:34 -0700 Subject: [PATCH 20/24] Pass RuleWithActions::executeTransformation arguments by reference - This function already expects these arguments not to be null pointers, doesn't validate them and just dereference them. - In order to make this explicit and enforced by the compiler, they're now passed as references. --- headers/modsecurity/rule_with_actions.h | 6 ++--- src/rule_with_actions.cc | 30 ++++++++++++------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/headers/modsecurity/rule_with_actions.h b/headers/modsecurity/rule_with_actions.h index bb63f499bd..26967f2aa6 100644 --- a/headers/modsecurity/rule_with_actions.h +++ b/headers/modsecurity/rule_with_actions.h @@ -161,9 +161,9 @@ class RuleWithActions : public Rule { const actions::transformations::Transformation &a, std::string &value, const Transaction *trans, - TransformationResults *ret, - std::string *path, - int *nth) const; + TransformationResults &ret, + std::string &path, + int &nth) const; /* actions */ actions::Action *m_disruptiveAction; diff --git a/src/rule_with_actions.cc b/src/rule_with_actions.cc index 1b76005c70..7aa0e649f2 100644 --- a/src/rule_with_actions.cc +++ b/src/rule_with_actions.cc @@ -327,24 +327,24 @@ inline void RuleWithActions::executeTransformation( const actions::transformations::Transformation &a, std::string &value, const Transaction *trans, - TransformationResults *ret, - std::string *path, - int *nth) const { + TransformationResults &ret, + std::string &path, + int &nth) const { if (a.transform(value, trans) && m_containsMultiMatchAction) { ret.emplace_back(value, a.m_name); - (*nth)++; + nth++; } - if (path->empty()) { - path->append(*a.m_name.get()); + if (path.empty()) { + path.append(*a.m_name.get()); } else { - path->append("," + *a.m_name.get()); + path.append("," + *a.m_name.get()); } ms_dbg_a(trans, 9, " T (" + \ - std::to_string(*nth) + ") " + \ + std::to_string(nth) + ") " + \ *a.m_name.get() + ": \"" + \ utils::string::limitTo(80, value) +"\""); } @@ -353,7 +353,7 @@ void RuleWithActions::executeTransformations( const Transaction *trans, const std::string &in, TransformationResults &ret) { int none = 0; int transformations = 0; - std::string path(""); + std::string path; auto value = in; if (m_containsMultiMatchAction == true) { @@ -381,16 +381,16 @@ void RuleWithActions::executeTransformations( // FIXME: here the object needs to be a transformation already. auto t = dynamic_cast(a.get()); assert(t != nullptr); - executeTransformation(*t, value, trans, &ret, &path, - &transformations); + executeTransformation(*t, value, trans, ret, path, + transformations); } } for (const Transformation *a : m_transformations) { assert(a != nullptr); if (none == 0) { - executeTransformation(*a, value, trans, &ret, &path, - &transformations); + executeTransformation(*a, value, trans, ret, path, + transformations); } if (a->m_isNone) { none--; @@ -419,8 +419,8 @@ void RuleWithActions::executeTransformations( auto a = dynamic_cast(b.second.get()); assert(a != nullptr); if (none == 0) { - executeTransformation(*a, value, trans, &ret, &path, - &transformations); + executeTransformation(*a, value, trans, ret, path, + transformations); } if (a->m_isNone) { none--; From fedec96a7ec21c2f9cc7fa1c0e36d2033d563316 Mon Sep 17 00:00:00 2001 From: Eduardo Arias Date: Mon, 19 Aug 2024 10:25:36 -0700 Subject: [PATCH 21/24] Refactored base64 utils to share implementation and reduce code duplication. --- src/utils/base64.cc | 81 ++++++++++----------------------------------- 1 file changed, 18 insertions(+), 63 deletions(-) diff --git a/src/utils/base64.cc b/src/utils/base64.cc index ebbb7393c9..7b1f4b07e6 100644 --- a/src/utils/base64.cc +++ b/src/utils/base64.cc @@ -23,33 +23,30 @@ #include "mbedtls/base64.h" -namespace modsecurity { -namespace Utils { +template +inline std::string base64Helper(const char *data, const unsigned int len, Operation op) { + size_t out_len = 0; + op(nullptr, 0, &out_len, + reinterpret_cast(data), len); -std::string Base64::encode(const std::string& data) { - size_t encoded_len = 0; - unsigned char *d; - std::string ret; - - mbedtls_base64_encode(NULL, 0, &encoded_len, - reinterpret_cast(data.c_str()), data.size()); + std::string ret(out_len, {}); + if(out_len > 0) { + op(reinterpret_cast(ret.data()), ret.size(), &out_len, + reinterpret_cast(data), len); - d = reinterpret_cast(malloc(sizeof(char) * encoded_len)); - if (d == NULL) { - return data; + ret.resize(out_len); } - memset(d, '\0', encoded_len); - - mbedtls_base64_encode(d, encoded_len, &encoded_len, - (unsigned char*) data.c_str(), data.size()); + return ret; +} - ret.assign(reinterpret_cast(d), encoded_len); - free(d); +namespace modsecurity { +namespace Utils { - return ret; +std::string Base64::encode(const std::string& data) { + return base64Helper(data.c_str(), data.size(), mbedtls_base64_encode); } @@ -63,53 +60,12 @@ std::string Base64::decode(const std::string& data, bool forgiven) { std::string Base64::decode(const std::string& data) { - size_t decoded_len = 0; - unsigned char *d; - std::string ret; - size_t len = strlen(data.c_str()); - - mbedtls_base64_decode(NULL, 0, &decoded_len, - reinterpret_cast(data.c_str()), len); - - d = reinterpret_cast(malloc(sizeof(char) * decoded_len)); - if (d == NULL) { - return data; - } - - memset(d, '\0', decoded_len); - - mbedtls_base64_decode(d, decoded_len, &decoded_len, - reinterpret_cast(data.c_str()), len); - - ret.assign(reinterpret_cast(d), decoded_len); - free(d); - - return ret; + return base64Helper(data.c_str(), strlen(data.c_str()), mbedtls_base64_decode); } std::string Base64::decode_forgiven(const std::string& data) { - size_t decoded_len = 0; - unsigned char *d; - std::string ret; - - decode_forgiven_engine(NULL, 0, &decoded_len, - reinterpret_cast(data.c_str()), data.size()); - - d = reinterpret_cast(malloc(sizeof(char) * decoded_len)); - if (d == NULL) { - return data; - } - - memset(d, '\0', decoded_len); - - decode_forgiven_engine(d, decoded_len, &decoded_len, - reinterpret_cast(data.c_str()), data.size()); - - ret.assign(reinterpret_cast(d), decoded_len); - free(d); - - return ret; + return base64Helper(data.c_str(), data.size(), decode_forgiven_engine); } @@ -215,6 +171,5 @@ void Base64::decode_forgiven_engine(unsigned char *plain_text, } } - } // namespace Utils } // namespace modsecurity From 7023c0a8b4850e020837dcc00539715f943992a5 Mon Sep 17 00:00:00 2001 From: Eduardo Arias Date: Mon, 19 Aug 2024 10:34:00 -0700 Subject: [PATCH 22/24] Refactored sha1 & md5 utils to share implementation and reduce code duplication. --- src/Makefile.am | 2 -- src/utils/md5.cc | 40 ------------------------------- src/utils/md5.h | 23 ++++++------------ src/utils/sha1.cc | 60 ----------------------------------------------- src/utils/sha1.h | 59 +++++++++++++++++++++++++++++++++++++--------- 5 files changed, 55 insertions(+), 129 deletions(-) delete mode 100644 src/utils/md5.cc delete mode 100644 src/utils/sha1.cc diff --git a/src/Makefile.am b/src/Makefile.am index 6f358655a0..2a32b97b65 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -248,11 +248,9 @@ UTILS = \ utils/geo_lookup.cc \ utils/https_client.cc \ utils/ip_tree.cc \ - utils/md5.cc \ utils/msc_tree.cc \ utils/random.cc \ utils/regex.cc \ - utils/sha1.cc \ utils/system.cc \ utils/shared_files.cc diff --git a/src/utils/md5.cc b/src/utils/md5.cc deleted file mode 100644 index 99b9d27820..0000000000 --- a/src/utils/md5.cc +++ /dev/null @@ -1,40 +0,0 @@ - - -#include "src/utils/md5.h" -#include "mbedtls/md5.h" - -namespace modsecurity { -namespace Utils { - - -std::string Md5::hexdigest(const std::string& input) { - unsigned char digest[16]; - - mbedtls_md5(reinterpret_cast(input.c_str()), - input.size(), digest); - - char buf[33]; - for (int i = 0; i < 16; i++) { - sprintf(buf+i*2, "%02x", digest[i]); - } - - return std::string(buf, 32); -} - - -std::string Md5::digest(const std::string& input) { - unsigned char output[16]; - std::string ret; - - mbedtls_md5(reinterpret_cast(input.c_str()), - input.size(), output); - - ret.assign(reinterpret_cast(output), 16); - - return ret; -} - - -} // namespace Utils -} // namespace modsecurity - diff --git a/src/utils/md5.h b/src/utils/md5.h index b6ebc12013..68f5d748e4 100644 --- a/src/utils/md5.h +++ b/src/utils/md5.h @@ -13,29 +13,20 @@ * */ -#include - -#include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" - #ifndef SRC_UTILS_MD5_H_ #define SRC_UTILS_MD5_H_ -#include -#include +#include "src/utils/sha1.h" +#include "mbedtls/md5.h" +#include -namespace modsecurity { -namespace Utils { +namespace modsecurity::Utils { -class Md5 { - public: - Md5() { } - static std::string hexdigest(const std::string& input); - static std::string digest(const std::string& input); +class Md5 : public DigestImpl<&mbedtls_md5, 16> { }; -} // namespace Utils -} // namespace modsecurity + +} // namespace modsecurity::Utils #endif // SRC_UTILS_MD5_H_ \ No newline at end of file diff --git a/src/utils/sha1.cc b/src/utils/sha1.cc deleted file mode 100644 index 4c28d4ed30..0000000000 --- a/src/utils/sha1.cc +++ /dev/null @@ -1,60 +0,0 @@ -/* - * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) - * - * You may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * If any of the files related to licensing are missing or if you have any - * other questions related to licensing please contact Trustwave Holdings, Inc. - * directly using the email address security@modsecurity.org. - * - */ - - -#include "src/utils/sha1.h" -#include "mbedtls/sha1.h" -#include -#include -#include - -namespace modsecurity { -namespace Utils { - - -std::string Sha1::hexdigest(const std::string& input) { - unsigned char digest[20] = { 0 }; - static const char* const lut = "0123456789abcdef"; - - mbedtls_sha1(reinterpret_cast(input.c_str()), - input.size(), digest); - std::string a; - - for (int i = 0; i < 20; i++) { - const unsigned char c = digest[i]; - a.push_back(lut[c >> 4]); - a.push_back(lut[c & 15]); - } - - return a; -} - - -std::string Sha1::digest(const std::string& input) { - unsigned char output[20]; - std::string ret; - - mbedtls_sha1(reinterpret_cast(input.c_str()), - input.size(), output); - - ret.assign(reinterpret_cast(output), 20); - - return ret; -} - - -} // namespace Utils -} // namespace modsecurity - diff --git a/src/utils/sha1.h b/src/utils/sha1.h index 6bae47c2b2..2dac3ea2c4 100644 --- a/src/utils/sha1.h +++ b/src/utils/sha1.h @@ -13,26 +13,63 @@ * */ - #ifndef SRC_UTILS_SHA1_H_ #define SRC_UTILS_SHA1_H_ -#include -#include #include +#include + +#include "src/utils/string.h" +#include "mbedtls/sha1.h" + +namespace modsecurity::Utils { + -namespace modsecurity { -namespace Utils { +using DigestOp = int (*)(const unsigned char *, size_t, unsigned char []); -class Sha1 { + +template +class DigestImpl { public: - Sha1() { } - static std::string hexdigest(const std::string& input); - static std::string digest(const std::string& input); + static std::string digest(const std::string& input) { + return digestHelper(input, [](const auto digest) { + return std::string(digest); + }); + } + + static void digestReplace(std::string& value) { + digestHelper(value, [&value](const auto digest) mutable { + value = digest; + }); + } + + static std::string hexdigest(const std::string &input) { + return digestHelper(input, [](const auto digest) { + return utils::string::string_to_hex(digest); + }); + } + +private: + + template + static auto digestHelper(const std::string &input, + ConvertOp convertOp) -> auto { + char digest[DigestSize]; + + auto ret = digestOp(reinterpret_cast(input.c_str()), + input.size(), reinterpret_cast(digest)); + assert(ret == 0); + + return convertOp(std::string_view(digest, DigestSize)); + } }; -} // namespace Utils -} // namespace modsecurity + +class Sha1 : public DigestImpl<&mbedtls_sha1, 20> { +}; + + +} // namespace modsecurity::Utils #endif // SRC_UTILS_SHA1_H_ From 2f5dac5c4cbd41ecb4c07bfc01ba02effff98d62 Mon Sep 17 00:00:00 2001 From: Eduardo Arias Date: Mon, 19 Aug 2024 11:26:56 -0700 Subject: [PATCH 23/24] Simplified initialization of Transformation's action_kind - Some of the Transformation classes would initialize their Action's action_kind using the default (using Transformation constructor without an action_kind parameter). - Others, however, would use that constructor and initialize action_kind manually in their constructor, but setting the default value (RunTimeBeforeMatchAttemptKind = 1), which was redundant. - Removed unused Transformation constructor to specify action_kind. - Converted Action::Kind into an 'enum class' to require using the enum constants (instead of integer values, which are difficult to track in the codebase and change) --- headers/modsecurity/actions/action.h | 70 +++++++++---------- src/actions/accuracy.h | 2 +- src/actions/audit_log.h | 2 +- src/actions/capture.h | 2 +- src/actions/chain.h | 2 +- src/actions/ctl/audit_engine.h | 2 +- src/actions/ctl/audit_log_parts.h | 2 +- src/actions/ctl/request_body_access.h | 2 +- src/actions/ctl/request_body_processor_json.h | 2 +- .../ctl/request_body_processor_urlencoded.h | 2 +- src/actions/ctl/request_body_processor_xml.h | 2 +- src/actions/ctl/rule_engine.h | 2 +- src/actions/ctl/rule_remove_by_id.h | 2 +- src/actions/ctl/rule_remove_by_tag.h | 2 +- src/actions/ctl/rule_remove_target_by_id.h | 2 +- src/actions/ctl/rule_remove_target_by_tag.h | 2 +- src/actions/data/status.h | 4 +- src/actions/disruptive/allow.h | 2 +- src/actions/disruptive/redirect.h | 4 +- src/actions/expire_var.h | 2 +- src/actions/init_col.h | 2 +- src/actions/log.h | 2 +- src/actions/log_data.h | 4 +- src/actions/maturity.h | 2 +- src/actions/msg.h | 4 +- src/actions/multi_match.h | 2 +- src/actions/no_audit_log.h | 2 +- src/actions/no_log.h | 2 +- src/actions/phase.h | 2 +- src/actions/rev.h | 2 +- src/actions/rule_id.h | 2 +- src/actions/set_env.h | 2 +- src/actions/set_rsc.h | 2 +- src/actions/set_sid.h | 2 +- src/actions/set_uid.h | 2 +- src/actions/skip.h | 2 +- src/actions/skip_after.h | 2 +- src/actions/tag.h | 2 +- src/actions/transformations/base64_decode.h | 3 +- .../transformations/base64_decode_ext.h | 3 +- src/actions/transformations/base64_encode.h | 3 +- src/actions/transformations/cmd_line.h | 3 +- .../transformations/compress_whitespace.cc | 5 -- .../transformations/compress_whitespace.h | 2 +- src/actions/transformations/css_decode.h | 3 +- .../transformations/escape_seq_decode.cc | 6 -- .../transformations/escape_seq_decode.h | 2 +- src/actions/transformations/hex_decode.h | 3 +- src/actions/transformations/hex_encode.cc | 4 -- src/actions/transformations/hex_encode.h | 2 +- .../transformations/html_entity_decode.h | 3 +- src/actions/transformations/js_decode.h | 3 +- src/actions/transformations/length.cc | 5 -- src/actions/transformations/length.h | 2 +- src/actions/transformations/lower_case.cc | 4 -- src/actions/transformations/lower_case.h | 2 +- src/actions/transformations/md5.h | 3 +- src/actions/transformations/normalise_path.cc | 5 -- src/actions/transformations/normalise_path.h | 2 +- .../transformations/normalise_path_win.h | 3 +- .../transformations/parity_even_7bit.h | 3 +- src/actions/transformations/parity_odd_7bit.h | 3 +- .../transformations/parity_zero_7bit.h | 3 +- src/actions/transformations/remove_comments.h | 3 +- .../transformations/remove_comments_char.cc | 4 -- .../transformations/remove_comments_char.h | 2 +- src/actions/transformations/remove_nulls.h | 3 +- .../transformations/remove_whitespace.cc | 5 -- .../transformations/remove_whitespace.h | 2 +- .../transformations/replace_comments.cc | 6 -- .../transformations/replace_comments.h | 2 +- src/actions/transformations/replace_nulls.cc | 4 -- src/actions/transformations/replace_nulls.h | 2 +- src/actions/transformations/sha1.cc | 5 +- src/actions/transformations/sha1.h | 2 +- src/actions/transformations/sql_hex_decode.h | 3 +- src/actions/transformations/transformation.h | 5 +- src/actions/transformations/trim.cc | 6 -- src/actions/transformations/trim.h | 4 +- src/actions/transformations/trim_left.cc | 9 +-- src/actions/transformations/trim_left.h | 5 +- src/actions/transformations/trim_right.cc | 8 +-- src/actions/transformations/trim_right.h | 5 +- src/actions/transformations/upper_case.cc | 4 -- src/actions/transformations/upper_case.h | 2 +- src/actions/transformations/url_decode.cc | 5 -- src/actions/transformations/url_decode.h | 2 +- src/actions/transformations/url_decode_uni.h | 3 +- src/actions/transformations/url_encode.cc | 6 -- src/actions/transformations/url_encode.h | 2 +- src/actions/transformations/utf8_to_unicode.h | 3 +- src/actions/ver.h | 2 +- src/parser/seclang-parser.cc | 4 +- src/parser/seclang-parser.yy | 4 +- src/rule_with_actions.cc | 8 +-- src/rules_exceptions.cc | 6 +- 96 files changed, 131 insertions(+), 237 deletions(-) diff --git a/headers/modsecurity/actions/action.h b/headers/modsecurity/actions/action.h index b1839fe70f..24f0da6dbe 100644 --- a/headers/modsecurity/actions/action.h +++ b/headers/modsecurity/actions/action.h @@ -32,15 +32,47 @@ namespace actions { class Action { public: + /** + * + * Define the action kind regarding to the execution time. + * + * + */ + enum class Kind { + /** + * + * Action that are executed while loading the configuration. For instance + * the rule ID or the rule phase. + * + */ + ConfigurationKind, + /** + * + * Those are actions that demands to be executed before call the operator. + * For instance the tranformations. + * + * + */ + RunTimeBeforeMatchAttemptKind, + /** + * + * Actions that are executed after the execution of the operator, only if + * the operator returned Match (or True). For instance the disruptive + * actions. + * + */ + RunTimeOnlyIfMatchKind, + }; + explicit Action(const std::string& _action) : m_isNone(false), temporaryAction(false), - action_kind(2), + action_kind(Kind::RunTimeOnlyIfMatchKind), m_name(nullptr), m_parser_payload("") { set_name_and_payload(_action); } - explicit Action(const std::string& _action, int kind) + explicit Action(const std::string& _action, Kind kind) : m_isNone(false), temporaryAction(false), action_kind(kind), @@ -100,41 +132,9 @@ class Action { bool m_isNone; bool temporaryAction; - int action_kind; + Kind action_kind; std::shared_ptr m_name; std::string m_parser_payload; - - /** - * - * Define the action kind regarding to the execution time. - * - * - */ - enum Kind { - /** - * - * Action that are executed while loading the configuration. For instance - * the rule ID or the rule phase. - * - */ - ConfigurationKind, - /** - * - * Those are actions that demands to be executed before call the operator. - * For instance the tranformations. - * - * - */ - RunTimeBeforeMatchAttemptKind, - /** - * - * Actions that are executed after the execution of the operator, only if - * the operator returned Match (or True). For instance the disruptive - * actions. - * - */ - RunTimeOnlyIfMatchKind, - }; }; diff --git a/src/actions/accuracy.h b/src/actions/accuracy.h index f787af190c..bbcdba5864 100644 --- a/src/actions/accuracy.h +++ b/src/actions/accuracy.h @@ -30,7 +30,7 @@ namespace actions { class Accuracy : public Action { public: explicit Accuracy(const std::string &action) - : Action(action, ConfigurationKind), + : Action(action, Kind::ConfigurationKind), m_accuracy(0) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; diff --git a/src/actions/audit_log.h b/src/actions/audit_log.h index d870de2ac3..cde743870a 100644 --- a/src/actions/audit_log.h +++ b/src/actions/audit_log.h @@ -33,7 +33,7 @@ namespace actions { class AuditLog : public Action { public: explicit AuditLog(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + : Action(action) { } bool evaluate(RuleWithActions *rule, Transaction *transaction, std::shared_ptr rm) override; diff --git a/src/actions/capture.h b/src/actions/capture.h index 33207439c9..0b072ece0b 100644 --- a/src/actions/capture.h +++ b/src/actions/capture.h @@ -29,7 +29,7 @@ namespace actions { class Capture : public Action { public: explicit Capture(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + : Action(action) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; }; diff --git a/src/actions/chain.h b/src/actions/chain.h index c5642baa6e..3b04f17e9b 100644 --- a/src/actions/chain.h +++ b/src/actions/chain.h @@ -33,7 +33,7 @@ namespace actions { class Chain : public Action { public: explicit Chain(const std::string &action) - : Action(action, ConfigurationKind) { } + : Action(action, Kind::ConfigurationKind) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; }; diff --git a/src/actions/ctl/audit_engine.h b/src/actions/ctl/audit_engine.h index 03e0cb4cc6..b822a6675e 100644 --- a/src/actions/ctl/audit_engine.h +++ b/src/actions/ctl/audit_engine.h @@ -34,7 +34,7 @@ namespace ctl { class AuditEngine : public Action { public: explicit AuditEngine(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), + : Action(action), m_auditEngine(audit_log::AuditLog::AuditLogStatus::NotSetLogStatus) { } bool init(std::string *error) override; diff --git a/src/actions/ctl/audit_log_parts.h b/src/actions/ctl/audit_log_parts.h index f4980780ef..0eb7c6b2fd 100644 --- a/src/actions/ctl/audit_log_parts.h +++ b/src/actions/ctl/audit_log_parts.h @@ -29,7 +29,7 @@ namespace ctl { class AuditLogParts : public Action { public: explicit AuditLogParts(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), + : Action(action), mPartsAction(0), mParts("") { } diff --git a/src/actions/ctl/request_body_access.h b/src/actions/ctl/request_body_access.h index afe3b3d489..1dcc88c587 100644 --- a/src/actions/ctl/request_body_access.h +++ b/src/actions/ctl/request_body_access.h @@ -30,7 +30,7 @@ namespace ctl { class RequestBodyAccess : public Action { public: explicit RequestBodyAccess(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), + : Action(action), m_request_body_access(false) { } bool init(std::string *error) override; diff --git a/src/actions/ctl/request_body_processor_json.h b/src/actions/ctl/request_body_processor_json.h index 48125597e0..9d726b1722 100644 --- a/src/actions/ctl/request_body_processor_json.h +++ b/src/actions/ctl/request_body_processor_json.h @@ -29,7 +29,7 @@ namespace ctl { class RequestBodyProcessorJSON : public Action { public: explicit RequestBodyProcessorJSON(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + : Action(action) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; }; diff --git a/src/actions/ctl/request_body_processor_urlencoded.h b/src/actions/ctl/request_body_processor_urlencoded.h index 5b5557d431..0277664aff 100644 --- a/src/actions/ctl/request_body_processor_urlencoded.h +++ b/src/actions/ctl/request_body_processor_urlencoded.h @@ -29,7 +29,7 @@ namespace ctl { class RequestBodyProcessorURLENCODED : public Action { public: explicit RequestBodyProcessorURLENCODED(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + : Action(action) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; }; diff --git a/src/actions/ctl/request_body_processor_xml.h b/src/actions/ctl/request_body_processor_xml.h index 9084d1d98a..5bd15edd8e 100644 --- a/src/actions/ctl/request_body_processor_xml.h +++ b/src/actions/ctl/request_body_processor_xml.h @@ -29,7 +29,7 @@ namespace ctl { class RequestBodyProcessorXML : public Action { public: explicit RequestBodyProcessorXML(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + : Action(action) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; }; diff --git a/src/actions/ctl/rule_engine.h b/src/actions/ctl/rule_engine.h index fca5d39b16..7aef4232dc 100644 --- a/src/actions/ctl/rule_engine.h +++ b/src/actions/ctl/rule_engine.h @@ -31,7 +31,7 @@ namespace ctl { class RuleEngine : public Action { public: explicit RuleEngine(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), + : Action(action), m_ruleEngine(RulesSetProperties::PropertyNotSetRuleEngine) { } bool init(std::string *error) override; diff --git a/src/actions/ctl/rule_remove_by_id.h b/src/actions/ctl/rule_remove_by_id.h index e0f0902b8a..f731db31cc 100644 --- a/src/actions/ctl/rule_remove_by_id.h +++ b/src/actions/ctl/rule_remove_by_id.h @@ -30,7 +30,7 @@ namespace ctl { class RuleRemoveById : public Action { public: explicit RuleRemoveById(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + : Action(action) { } bool init(std::string *error) override; bool evaluate(RuleWithActions *rule, Transaction *transaction) override; diff --git a/src/actions/ctl/rule_remove_by_tag.h b/src/actions/ctl/rule_remove_by_tag.h index 5689b7b166..e85cdbfa78 100644 --- a/src/actions/ctl/rule_remove_by_tag.h +++ b/src/actions/ctl/rule_remove_by_tag.h @@ -30,7 +30,7 @@ namespace ctl { class RuleRemoveByTag : public Action { public: explicit RuleRemoveByTag(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), + : Action(action), m_tag("") { } bool init(std::string *error) override; diff --git a/src/actions/ctl/rule_remove_target_by_id.h b/src/actions/ctl/rule_remove_target_by_id.h index d71e4fc215..92b7286dfb 100644 --- a/src/actions/ctl/rule_remove_target_by_id.h +++ b/src/actions/ctl/rule_remove_target_by_id.h @@ -30,7 +30,7 @@ namespace ctl { class RuleRemoveTargetById : public Action { public: explicit RuleRemoveTargetById(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), + : Action(action), m_id(0), m_target("") { } diff --git a/src/actions/ctl/rule_remove_target_by_tag.h b/src/actions/ctl/rule_remove_target_by_tag.h index 7863e5a521..b4e212395c 100644 --- a/src/actions/ctl/rule_remove_target_by_tag.h +++ b/src/actions/ctl/rule_remove_target_by_tag.h @@ -30,7 +30,7 @@ namespace ctl { class RuleRemoveTargetByTag : public Action { public: explicit RuleRemoveTargetByTag(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + : Action(action) { } bool init(std::string *error) override; bool evaluate(RuleWithActions *rule, Transaction *transaction) override; diff --git a/src/actions/data/status.h b/src/actions/data/status.h index d792247d68..566a927ea3 100644 --- a/src/actions/data/status.h +++ b/src/actions/data/status.h @@ -33,8 +33,8 @@ namespace data { class Status : public Action { public: - explicit Status(const std::string &action) : Action(action, 2), - m_status(0) { } + explicit Status(const std::string &action) + : Action(action), m_status(0) { } bool init(std::string *error) override; bool evaluate(RuleWithActions *rule, Transaction *transaction, diff --git a/src/actions/disruptive/allow.h b/src/actions/disruptive/allow.h index d9a716cec7..a6d538a476 100644 --- a/src/actions/disruptive/allow.h +++ b/src/actions/disruptive/allow.h @@ -54,7 +54,7 @@ enum AllowType : int { class Allow : public Action { public: explicit Allow(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), + : Action(action), m_allowType(NoneAllowType) { } diff --git a/src/actions/disruptive/redirect.h b/src/actions/disruptive/redirect.h index 46b5d51a96..72ecf98e4b 100644 --- a/src/actions/disruptive/redirect.h +++ b/src/actions/disruptive/redirect.h @@ -37,12 +37,12 @@ namespace disruptive { class Redirect : public Action { public: explicit Redirect(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), + : Action(action), m_status(0), m_string(nullptr) { } explicit Redirect(std::unique_ptr z) - : Action("redirert", RunTimeOnlyIfMatchKind), + : Action("redirert"), m_status(0), m_string(std::move(z)) { } diff --git a/src/actions/expire_var.h b/src/actions/expire_var.h index 1b1537bb94..f0ca7496fe 100644 --- a/src/actions/expire_var.h +++ b/src/actions/expire_var.h @@ -36,7 +36,7 @@ class ExpireVar : public Action { explicit ExpireVar(const std::string &action) : Action(action) { } explicit ExpireVar(std::unique_ptr z) - : Action("expirevar", RunTimeOnlyIfMatchKind), + : Action("expirevar"), m_string(std::move(z)) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; diff --git a/src/actions/init_col.h b/src/actions/init_col.h index 16d7ace921..f5a9263b93 100644 --- a/src/actions/init_col.h +++ b/src/actions/init_col.h @@ -35,7 +35,7 @@ class InitCol : public Action { explicit InitCol(const std::string &action) : Action(action) { } InitCol(const std::string &action, std::unique_ptr z) - : Action(action, RunTimeOnlyIfMatchKind), + : Action(action), m_string(std::move(z)) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; diff --git a/src/actions/log.h b/src/actions/log.h index 736d4a1304..d2cb5cd26c 100644 --- a/src/actions/log.h +++ b/src/actions/log.h @@ -31,7 +31,7 @@ namespace actions { class Log : public Action { public: explicit Log(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + : Action(action) { } bool evaluate(RuleWithActions *rule, Transaction *transaction, std::shared_ptr rm) override; diff --git a/src/actions/log_data.h b/src/actions/log_data.h index da2fbf4df0..6e618f2a86 100644 --- a/src/actions/log_data.h +++ b/src/actions/log_data.h @@ -33,10 +33,10 @@ namespace actions { class LogData : public Action { public: explicit LogData(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + : Action(action) { } explicit LogData(std::unique_ptr z) - : Action("logdata", RunTimeOnlyIfMatchKind), + : Action("logdata"), m_string(std::move(z)) { } bool evaluate(RuleWithActions *rule, Transaction *transaction, diff --git a/src/actions/maturity.h b/src/actions/maturity.h index dd185efaa2..3f873af404 100644 --- a/src/actions/maturity.h +++ b/src/actions/maturity.h @@ -30,7 +30,7 @@ namespace actions { class Maturity : public Action { public: explicit Maturity(const std::string &action) - : Action(action, ConfigurationKind), + : Action(action, Kind::ConfigurationKind), m_maturity(0) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; diff --git a/src/actions/msg.h b/src/actions/msg.h index 61661194ba..c75e6d6eb3 100644 --- a/src/actions/msg.h +++ b/src/actions/msg.h @@ -34,10 +34,10 @@ namespace actions { class Msg : public Action { public: explicit Msg(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + : Action(action) { } explicit Msg(std::unique_ptr z) - : Action("msg", RunTimeOnlyIfMatchKind), + : Action("msg"), m_string(std::move(z)) { } bool evaluate(RuleWithActions *rule, Transaction *transaction, diff --git a/src/actions/multi_match.h b/src/actions/multi_match.h index b0fd2c767e..71fe288fe9 100644 --- a/src/actions/multi_match.h +++ b/src/actions/multi_match.h @@ -33,7 +33,7 @@ namespace actions { class MultiMatch : public Action { public: explicit MultiMatch(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + : Action(action) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; }; diff --git a/src/actions/no_audit_log.h b/src/actions/no_audit_log.h index dbd5d098fb..6deb5e4a88 100644 --- a/src/actions/no_audit_log.h +++ b/src/actions/no_audit_log.h @@ -33,7 +33,7 @@ namespace actions { class NoAuditLog : public Action { public: explicit NoAuditLog(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + : Action(action) { } bool evaluate(RuleWithActions *rule, Transaction *transaction, std::shared_ptr rm) override; diff --git a/src/actions/no_log.h b/src/actions/no_log.h index 87d4e30593..193a64ea2e 100644 --- a/src/actions/no_log.h +++ b/src/actions/no_log.h @@ -31,7 +31,7 @@ namespace actions { class NoLog : public Action { public: explicit NoLog(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + : Action(action) { } bool evaluate(RuleWithActions *rule, Transaction *transaction, std::shared_ptr rm) override; diff --git a/src/actions/phase.h b/src/actions/phase.h index 0fada3c3c5..7c81458440 100644 --- a/src/actions/phase.h +++ b/src/actions/phase.h @@ -32,7 +32,7 @@ namespace actions { class Phase : public Action { public: - explicit Phase(const std::string &action) : Action(action, ConfigurationKind), + explicit Phase(const std::string &action) : Action(action, Kind::ConfigurationKind), m_phase(0), m_secRulesPhase(0) { } diff --git a/src/actions/rev.h b/src/actions/rev.h index 9e3c1bfb64..a023b42521 100644 --- a/src/actions/rev.h +++ b/src/actions/rev.h @@ -29,7 +29,7 @@ namespace actions { class Rev : public Action { public: - explicit Rev(const std::string &action) : Action(action, ConfigurationKind) { } + explicit Rev(const std::string &action) : Action(action, Kind::ConfigurationKind) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; bool init(std::string *error) override; diff --git a/src/actions/rule_id.h b/src/actions/rule_id.h index 2e26f87f52..8f16c95e17 100644 --- a/src/actions/rule_id.h +++ b/src/actions/rule_id.h @@ -33,7 +33,7 @@ namespace actions { class RuleId : public Action { public: explicit RuleId(const std::string &action) - : Action(action, ConfigurationKind), + : Action(action, Kind::ConfigurationKind), m_ruleId(0) { } bool init(std::string *error) override; diff --git a/src/actions/set_env.h b/src/actions/set_env.h index 33ccfc3380..cc24c28508 100644 --- a/src/actions/set_env.h +++ b/src/actions/set_env.h @@ -36,7 +36,7 @@ class SetENV : public Action { : Action(_action) { } explicit SetENV(std::unique_ptr z) - : Action("setenv", RunTimeOnlyIfMatchKind), + : Action("setenv"), m_string(std::move(z)) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; diff --git a/src/actions/set_rsc.h b/src/actions/set_rsc.h index 5913b7c799..7830ee92c3 100644 --- a/src/actions/set_rsc.h +++ b/src/actions/set_rsc.h @@ -36,7 +36,7 @@ class SetRSC : public Action { : Action(_action) { } explicit SetRSC(std::unique_ptr z) - : Action("setsrc", RunTimeOnlyIfMatchKind), + : Action("setsrc"), m_string(std::move(z)) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; diff --git a/src/actions/set_sid.h b/src/actions/set_sid.h index 64f8f3cc78..dca45433d1 100644 --- a/src/actions/set_sid.h +++ b/src/actions/set_sid.h @@ -36,7 +36,7 @@ class SetSID : public Action { : Action(_action) { } explicit SetSID(std::unique_ptr z) - : Action("setsid", RunTimeOnlyIfMatchKind), + : Action("setsid"), m_string(std::move(z)) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; diff --git a/src/actions/set_uid.h b/src/actions/set_uid.h index b8c3a0db74..76893999fc 100644 --- a/src/actions/set_uid.h +++ b/src/actions/set_uid.h @@ -36,7 +36,7 @@ class SetUID : public Action { : Action(_action) { } explicit SetUID(std::unique_ptr z) - : Action("setuid", RunTimeOnlyIfMatchKind), + : Action("setuid"), m_string(std::move(z)) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; diff --git a/src/actions/skip.h b/src/actions/skip.h index 71e5d7aa05..ee24abe7be 100644 --- a/src/actions/skip.h +++ b/src/actions/skip.h @@ -30,7 +30,7 @@ namespace actions { class Skip : public Action { public: explicit Skip(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), + : Action(action), m_skip_next(0) { } bool init(std::string *error) override; diff --git a/src/actions/skip_after.h b/src/actions/skip_after.h index f7e0680d72..39b2c26967 100644 --- a/src/actions/skip_after.h +++ b/src/actions/skip_after.h @@ -31,7 +31,7 @@ namespace actions { class SkipAfter : public Action { public: explicit SkipAfter(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), + : Action(action), m_skipName(std::make_shared(m_parser_payload)) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; diff --git a/src/actions/tag.h b/src/actions/tag.h index 75369f5f7c..bf3988b5bb 100644 --- a/src/actions/tag.h +++ b/src/actions/tag.h @@ -33,7 +33,7 @@ namespace actions { class Tag : public Action { public: explicit Tag(std::unique_ptr z) - : Action("tag", RunTimeOnlyIfMatchKind), + : Action("tag"), m_string(std::move(z)) { } std::string getName(Transaction *transaction); diff --git a/src/actions/transformations/base64_decode.h b/src/actions/transformations/base64_decode.h index 3527bd5e76..8c97dbe87e 100644 --- a/src/actions/transformations/base64_decode.h +++ b/src/actions/transformations/base64_decode.h @@ -22,8 +22,7 @@ namespace modsecurity::actions::transformations { class Base64Decode : public Transformation { public: - explicit Base64Decode(const std::string &action) - : Transformation(action) { } + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/base64_decode_ext.h b/src/actions/transformations/base64_decode_ext.h index 8f1f069edb..66b0678fa5 100644 --- a/src/actions/transformations/base64_decode_ext.h +++ b/src/actions/transformations/base64_decode_ext.h @@ -22,8 +22,7 @@ namespace modsecurity::actions::transformations { class Base64DecodeExt : public Transformation { public: - explicit Base64DecodeExt(const std::string &action) - : Transformation(action) { } + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/base64_encode.h b/src/actions/transformations/base64_encode.h index 7b3ac25ef3..3c1d96f196 100644 --- a/src/actions/transformations/base64_encode.h +++ b/src/actions/transformations/base64_encode.h @@ -22,8 +22,7 @@ namespace modsecurity::actions::transformations { class Base64Encode : public Transformation { public: - explicit Base64Encode(const std::string &action) - : Transformation(action) { } + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/cmd_line.h b/src/actions/transformations/cmd_line.h index 9ba5c6b2a3..27672b604b 100644 --- a/src/actions/transformations/cmd_line.h +++ b/src/actions/transformations/cmd_line.h @@ -22,8 +22,7 @@ namespace modsecurity::actions::transformations { class CmdLine : public Transformation { public: - explicit CmdLine(const std::string &action) - : Transformation(action) { } + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/compress_whitespace.cc b/src/actions/transformations/compress_whitespace.cc index 065b4ee094..a9b31c962b 100644 --- a/src/actions/transformations/compress_whitespace.cc +++ b/src/actions/transformations/compress_whitespace.cc @@ -19,11 +19,6 @@ namespace modsecurity::actions::transformations { -CompressWhitespace::CompressWhitespace(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - bool CompressWhitespace::transform(std::string &value, const Transaction *trans) const { bool inWhiteSpace = false; diff --git a/src/actions/transformations/compress_whitespace.h b/src/actions/transformations/compress_whitespace.h index bf90b0ba20..8f74a3c1c1 100644 --- a/src/actions/transformations/compress_whitespace.h +++ b/src/actions/transformations/compress_whitespace.h @@ -22,7 +22,7 @@ namespace modsecurity::actions::transformations { class CompressWhitespace : public Transformation { public: - explicit CompressWhitespace(const std::string &action); + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/css_decode.h b/src/actions/transformations/css_decode.h index 67535a9a78..c9b451f837 100644 --- a/src/actions/transformations/css_decode.h +++ b/src/actions/transformations/css_decode.h @@ -22,8 +22,7 @@ namespace modsecurity::actions::transformations { class CssDecode : public Transformation { public: - explicit CssDecode(const std::string &action) - : Transformation(action) { } + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/escape_seq_decode.cc b/src/actions/transformations/escape_seq_decode.cc index 290061447f..2cc413e711 100644 --- a/src/actions/transformations/escape_seq_decode.cc +++ b/src/actions/transformations/escape_seq_decode.cc @@ -20,12 +20,6 @@ namespace modsecurity::actions::transformations { -EscapeSeqDecode::EscapeSeqDecode(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - - static inline int ansi_c_sequences_decode_inplace(std::string &value) { auto d = reinterpret_cast(value.data()); const unsigned char* input = d; diff --git a/src/actions/transformations/escape_seq_decode.h b/src/actions/transformations/escape_seq_decode.h index 6a240715b3..71976fe126 100644 --- a/src/actions/transformations/escape_seq_decode.h +++ b/src/actions/transformations/escape_seq_decode.h @@ -22,7 +22,7 @@ namespace modsecurity::actions::transformations { class EscapeSeqDecode : public Transformation { public: - explicit EscapeSeqDecode(const std::string &action); + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/hex_decode.h b/src/actions/transformations/hex_decode.h index 158f91aa15..1ee6a1b773 100644 --- a/src/actions/transformations/hex_decode.h +++ b/src/actions/transformations/hex_decode.h @@ -22,8 +22,7 @@ namespace modsecurity::actions::transformations { class HexDecode : public Transformation { public: - explicit HexDecode(const std::string &action) - : Transformation(action) { } + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/hex_encode.cc b/src/actions/transformations/hex_encode.cc index a07197263f..689a132f76 100644 --- a/src/actions/transformations/hex_encode.cc +++ b/src/actions/transformations/hex_encode.cc @@ -20,10 +20,6 @@ namespace modsecurity::actions::transformations { -HexEncode::HexEncode(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} bool HexEncode::transform(std::string &value, const Transaction *trans) const { if (value.empty()) return false; diff --git a/src/actions/transformations/hex_encode.h b/src/actions/transformations/hex_encode.h index 3bb744b5cb..9037a514fe 100644 --- a/src/actions/transformations/hex_encode.h +++ b/src/actions/transformations/hex_encode.h @@ -22,7 +22,7 @@ namespace modsecurity::actions::transformations { class HexEncode : public Transformation { public: - explicit HexEncode(const std::string &action); + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/html_entity_decode.h b/src/actions/transformations/html_entity_decode.h index 5c17333a97..499f8f2ff8 100644 --- a/src/actions/transformations/html_entity_decode.h +++ b/src/actions/transformations/html_entity_decode.h @@ -22,8 +22,7 @@ namespace modsecurity::actions::transformations { class HtmlEntityDecode : public Transformation { public: - explicit HtmlEntityDecode(const std::string &action) - : Transformation(action) { } + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/js_decode.h b/src/actions/transformations/js_decode.h index 94156426ae..840577cb6c 100644 --- a/src/actions/transformations/js_decode.h +++ b/src/actions/transformations/js_decode.h @@ -22,8 +22,7 @@ namespace modsecurity::actions::transformations { class JsDecode : public Transformation { public: - explicit JsDecode(const std::string &action) - : Transformation(action) { } + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/length.cc b/src/actions/transformations/length.cc index 10aadfe8ce..ac98914c6e 100644 --- a/src/actions/transformations/length.cc +++ b/src/actions/transformations/length.cc @@ -19,11 +19,6 @@ namespace modsecurity::actions::transformations { -Length::Length(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - bool Length::transform(std::string &value, const Transaction *trans) const { value = std::to_string(value.size()); return true; diff --git a/src/actions/transformations/length.h b/src/actions/transformations/length.h index e7b6b0816d..39465238f4 100644 --- a/src/actions/transformations/length.h +++ b/src/actions/transformations/length.h @@ -22,7 +22,7 @@ namespace modsecurity::actions::transformations { class Length : public Transformation { public: - explicit Length(const std::string &action); + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/lower_case.cc b/src/actions/transformations/lower_case.cc index 080429d952..0238b5a457 100644 --- a/src/actions/transformations/lower_case.cc +++ b/src/actions/transformations/lower_case.cc @@ -22,10 +22,6 @@ namespace modsecurity::actions::transformations { -LowerCase::LowerCase(const std::string &a) - : Transformation(a) { -} - bool LowerCase::transform(std::string &value, const Transaction *trans) const { return convert(value, [](auto c) { return std::tolower(c); }); diff --git a/src/actions/transformations/lower_case.h b/src/actions/transformations/lower_case.h index 7bdf2d8443..192b2aa3fc 100644 --- a/src/actions/transformations/lower_case.h +++ b/src/actions/transformations/lower_case.h @@ -24,7 +24,7 @@ namespace modsecurity::actions::transformations { class LowerCase : public Transformation { public: - explicit LowerCase(const std::string &action); + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; diff --git a/src/actions/transformations/md5.h b/src/actions/transformations/md5.h index 9d5a15f881..d1813c5ff3 100644 --- a/src/actions/transformations/md5.h +++ b/src/actions/transformations/md5.h @@ -22,8 +22,7 @@ namespace modsecurity::actions::transformations { class Md5 : public Transformation { public: - explicit Md5(const std::string &action) - : Transformation(action) { } + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/normalise_path.cc b/src/actions/transformations/normalise_path.cc index dd2b64d2ac..91c0402729 100644 --- a/src/actions/transformations/normalise_path.cc +++ b/src/actions/transformations/normalise_path.cc @@ -19,11 +19,6 @@ namespace modsecurity::actions::transformations { -NormalisePath::NormalisePath(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - bool NormalisePath::transform(std::string &value, const Transaction *trans) const { return normalize_path_inplace(value, false); } diff --git a/src/actions/transformations/normalise_path.h b/src/actions/transformations/normalise_path.h index 248def7f19..a1ef89189a 100644 --- a/src/actions/transformations/normalise_path.h +++ b/src/actions/transformations/normalise_path.h @@ -22,7 +22,7 @@ namespace modsecurity::actions::transformations { class NormalisePath : public Transformation { public: - explicit NormalisePath(const std::string &action); + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; diff --git a/src/actions/transformations/normalise_path_win.h b/src/actions/transformations/normalise_path_win.h index af312693e6..0cf11260fc 100644 --- a/src/actions/transformations/normalise_path_win.h +++ b/src/actions/transformations/normalise_path_win.h @@ -22,8 +22,7 @@ namespace modsecurity::actions::transformations { class NormalisePathWin : public Transformation { public: - explicit NormalisePathWin(const std::string &action) - : Transformation(action) { } + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/parity_even_7bit.h b/src/actions/transformations/parity_even_7bit.h index 786f72e419..8e107a5da8 100644 --- a/src/actions/transformations/parity_even_7bit.h +++ b/src/actions/transformations/parity_even_7bit.h @@ -22,8 +22,7 @@ namespace modsecurity::actions::transformations { class ParityEven7bit : public Transformation { public: - explicit ParityEven7bit(const std::string &action) - : Transformation(action) { } + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; diff --git a/src/actions/transformations/parity_odd_7bit.h b/src/actions/transformations/parity_odd_7bit.h index d0a1583c55..0b9164b912 100644 --- a/src/actions/transformations/parity_odd_7bit.h +++ b/src/actions/transformations/parity_odd_7bit.h @@ -22,8 +22,7 @@ namespace modsecurity::actions::transformations { class ParityOdd7bit : public Transformation { public: - explicit ParityOdd7bit(const std::string &action) - : Transformation(action) { } + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/parity_zero_7bit.h b/src/actions/transformations/parity_zero_7bit.h index c7f27d7484..aa9d1bf328 100644 --- a/src/actions/transformations/parity_zero_7bit.h +++ b/src/actions/transformations/parity_zero_7bit.h @@ -22,8 +22,7 @@ namespace modsecurity::actions::transformations { class ParityZero7bit : public Transformation { public: - explicit ParityZero7bit(const std::string &action) - : Transformation(action) { } + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/remove_comments.h b/src/actions/transformations/remove_comments.h index 67f0ff5b7c..948536cbf5 100644 --- a/src/actions/transformations/remove_comments.h +++ b/src/actions/transformations/remove_comments.h @@ -22,8 +22,7 @@ namespace modsecurity::actions::transformations { class RemoveComments : public Transformation { public: - explicit RemoveComments(const std::string &action) - : Transformation(action) { } + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/remove_comments_char.cc b/src/actions/transformations/remove_comments_char.cc index 2eeb86f65e..7e666db31f 100644 --- a/src/actions/transformations/remove_comments_char.cc +++ b/src/actions/transformations/remove_comments_char.cc @@ -18,10 +18,6 @@ namespace modsecurity::actions::transformations { -RemoveCommentsChar::RemoveCommentsChar(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} bool RemoveCommentsChar::transform(std::string &value, const Transaction *trans) const { char *d = value.data(); diff --git a/src/actions/transformations/remove_comments_char.h b/src/actions/transformations/remove_comments_char.h index 2066fd6535..d11b0148a3 100644 --- a/src/actions/transformations/remove_comments_char.h +++ b/src/actions/transformations/remove_comments_char.h @@ -22,7 +22,7 @@ namespace modsecurity::actions::transformations { class RemoveCommentsChar : public Transformation { public: - explicit RemoveCommentsChar(const std::string &action); + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/remove_nulls.h b/src/actions/transformations/remove_nulls.h index 163f9ddfc7..67c90ee018 100644 --- a/src/actions/transformations/remove_nulls.h +++ b/src/actions/transformations/remove_nulls.h @@ -24,8 +24,7 @@ namespace modsecurity::actions::transformations { class RemoveNulls : public Transformation { public: - explicit RemoveNulls(const std::string &action) - : Transformation(action) { } + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; diff --git a/src/actions/transformations/remove_whitespace.cc b/src/actions/transformations/remove_whitespace.cc index 934f1d29fe..f7047f4760 100644 --- a/src/actions/transformations/remove_whitespace.cc +++ b/src/actions/transformations/remove_whitespace.cc @@ -20,11 +20,6 @@ namespace modsecurity::actions::transformations { -RemoveWhitespace::RemoveWhitespace(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - bool RemoveWhitespace::transform(std::string &value, const Transaction *trans) const { const char nonBreakingSpaces = 0xa0; const char nonBreakingSpaces2 = 0xc2; diff --git a/src/actions/transformations/remove_whitespace.h b/src/actions/transformations/remove_whitespace.h index a9925f8e74..b95a508b74 100644 --- a/src/actions/transformations/remove_whitespace.h +++ b/src/actions/transformations/remove_whitespace.h @@ -22,7 +22,7 @@ namespace modsecurity::actions::transformations { class RemoveWhitespace : public Transformation { public: - explicit RemoveWhitespace(const std::string &action); + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/replace_comments.cc b/src/actions/transformations/replace_comments.cc index a6bab9727c..78ae786c73 100644 --- a/src/actions/transformations/replace_comments.cc +++ b/src/actions/transformations/replace_comments.cc @@ -59,12 +59,6 @@ static inline bool inplace(std::string &value) { } -ReplaceComments::ReplaceComments(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - - bool ReplaceComments::transform(std::string &value, const Transaction *trans) const { return inplace(value); } diff --git a/src/actions/transformations/replace_comments.h b/src/actions/transformations/replace_comments.h index 95e5e8540d..db206e538f 100644 --- a/src/actions/transformations/replace_comments.h +++ b/src/actions/transformations/replace_comments.h @@ -22,7 +22,7 @@ namespace modsecurity::actions::transformations { class ReplaceComments : public Transformation { public: - explicit ReplaceComments(const std::string &action); + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/replace_nulls.cc b/src/actions/transformations/replace_nulls.cc index 479f2f5ac8..9792da5d03 100644 --- a/src/actions/transformations/replace_nulls.cc +++ b/src/actions/transformations/replace_nulls.cc @@ -18,10 +18,6 @@ namespace modsecurity::actions::transformations { -ReplaceNulls::ReplaceNulls(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} bool ReplaceNulls::transform(std::string &value, const Transaction *trans) const { bool changed = false; diff --git a/src/actions/transformations/replace_nulls.h b/src/actions/transformations/replace_nulls.h index ad206ae40b..a01077c704 100644 --- a/src/actions/transformations/replace_nulls.h +++ b/src/actions/transformations/replace_nulls.h @@ -22,7 +22,7 @@ namespace modsecurity::actions::transformations { class ReplaceNulls : public Transformation { public: - explicit ReplaceNulls(const std::string &action); + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/sha1.cc b/src/actions/transformations/sha1.cc index af1eda415f..388633455c 100644 --- a/src/actions/transformations/sha1.cc +++ b/src/actions/transformations/sha1.cc @@ -20,14 +20,11 @@ namespace modsecurity::actions::transformations { -Sha1::Sha1(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} bool Sha1::transform(std::string &value, const Transaction *trans) const { value = Utils::Sha1::digest(value); return true; } + } // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/sha1.h b/src/actions/transformations/sha1.h index 263ed97879..f777641141 100644 --- a/src/actions/transformations/sha1.h +++ b/src/actions/transformations/sha1.h @@ -22,7 +22,7 @@ namespace modsecurity::actions::transformations { class Sha1 : public Transformation { public: - explicit Sha1(const std::string &action); + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/sql_hex_decode.h b/src/actions/transformations/sql_hex_decode.h index 44f45d172d..0acb1cff6b 100644 --- a/src/actions/transformations/sql_hex_decode.h +++ b/src/actions/transformations/sql_hex_decode.h @@ -22,8 +22,7 @@ namespace modsecurity::actions::transformations { class SqlHexDecode : public Transformation { public: - explicit SqlHexDecode(const std::string &action) - : Transformation(action) { } + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/transformation.h b/src/actions/transformations/transformation.h index 3677dcefd8..1d0ea99aa6 100644 --- a/src/actions/transformations/transformation.h +++ b/src/actions/transformations/transformation.h @@ -23,10 +23,7 @@ namespace modsecurity::actions::transformations { class Transformation : public Action { public: explicit Transformation(const std::string& _action) - : Action(_action, RunTimeBeforeMatchAttemptKind) { } - - explicit Transformation(const std::string& _action, int kind) - : Action(_action, kind) { } + : Action(_action, Kind::RunTimeBeforeMatchAttemptKind) { } static Transformation* instantiate(std::string a); diff --git a/src/actions/transformations/trim.cc b/src/actions/transformations/trim.cc index bc90b4ecb6..2056b25622 100644 --- a/src/actions/transformations/trim.cc +++ b/src/actions/transformations/trim.cc @@ -55,12 +55,6 @@ bool Trim::trim(std::string &s) { } -Trim::Trim(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - - bool Trim::transform(std::string &value, const Transaction *trans) const { return trim(value); } diff --git a/src/actions/transformations/trim.h b/src/actions/transformations/trim.h index 0e3d26f676..e436f5bf54 100644 --- a/src/actions/transformations/trim.h +++ b/src/actions/transformations/trim.h @@ -22,12 +22,10 @@ namespace modsecurity::actions::transformations { class Trim : public Transformation { public: - explicit Trim(const std::string &action); + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; - protected: - static bool ltrim(std::string &s); static bool rtrim(std::string &s); static bool trim(std::string &s); diff --git a/src/actions/transformations/trim_left.cc b/src/actions/transformations/trim_left.cc index 10276acff6..2ce7014910 100644 --- a/src/actions/transformations/trim_left.cc +++ b/src/actions/transformations/trim_left.cc @@ -14,19 +14,14 @@ */ #include "trim_left.h" +#include "trim.h" namespace modsecurity::actions::transformations { - -TrimLeft::TrimLeft(const std::string &action) - : Trim(action) { - this->action_kind = 1; -} - bool TrimLeft::transform(std::string &value, const Transaction *trans) const { - return ltrim(value); + return Trim::ltrim(value); } diff --git a/src/actions/transformations/trim_left.h b/src/actions/transformations/trim_left.h index 5d5a0a57b3..8acf1fe593 100644 --- a/src/actions/transformations/trim_left.h +++ b/src/actions/transformations/trim_left.h @@ -17,13 +17,12 @@ #define SRC_ACTIONS_TRANSFORMATIONS_TRIM_LEFT_H_ #include "transformation.h" -#include "trim.h" namespace modsecurity::actions::transformations { -class TrimLeft : public Trim { +class TrimLeft : public Transformation { public: - explicit TrimLeft(const std::string &action); + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/trim_right.cc b/src/actions/transformations/trim_right.cc index aa38c3488f..e6536786ba 100644 --- a/src/actions/transformations/trim_right.cc +++ b/src/actions/transformations/trim_right.cc @@ -14,18 +14,14 @@ */ #include "trim_right.h" +#include "trim.h" namespace modsecurity::actions::transformations { -TrimRight::TrimRight(const std::string &action) - : Trim(action) { - this->action_kind = 1; -} - bool TrimRight::transform(std::string &value, const Transaction *trans) const { - return rtrim(value); + return Trim::rtrim(value); } diff --git a/src/actions/transformations/trim_right.h b/src/actions/transformations/trim_right.h index eb13fb20f3..7e31795a31 100644 --- a/src/actions/transformations/trim_right.h +++ b/src/actions/transformations/trim_right.h @@ -17,13 +17,12 @@ #define SRC_ACTIONS_TRANSFORMATIONS_TRIM_RIGHT_H_ #include "transformation.h" -#include "trim.h" namespace modsecurity::actions::transformations { -class TrimRight : public Trim { +class TrimRight : public Transformation { public: - explicit TrimRight(const std::string &action); + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/upper_case.cc b/src/actions/transformations/upper_case.cc index f811bcbbdb..2b3978c740 100644 --- a/src/actions/transformations/upper_case.cc +++ b/src/actions/transformations/upper_case.cc @@ -24,10 +24,6 @@ namespace modsecurity::actions::transformations { -UpperCase::UpperCase(const std::string &a) - : Transformation(a) { -} - bool UpperCase::transform(std::string &value, const Transaction *trans) const { return LowerCase::convert(value, [](auto c) { return std::toupper(c); }); diff --git a/src/actions/transformations/upper_case.h b/src/actions/transformations/upper_case.h index 70c806b0c6..87a1df8a0a 100644 --- a/src/actions/transformations/upper_case.h +++ b/src/actions/transformations/upper_case.h @@ -22,7 +22,7 @@ namespace modsecurity::actions::transformations { class UpperCase : public Transformation { public: - explicit UpperCase(const std::string &action); + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/url_decode.cc b/src/actions/transformations/url_decode.cc index c67e9fa6ba..dbc7bf9fb9 100644 --- a/src/actions/transformations/url_decode.cc +++ b/src/actions/transformations/url_decode.cc @@ -21,11 +21,6 @@ namespace modsecurity::actions::transformations { -UrlDecode::UrlDecode(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - bool UrlDecode::transform(std::string &value, const Transaction *trans) const { int invalid_count; return utils::urldecode_nonstrict_inplace(value, invalid_count); diff --git a/src/actions/transformations/url_decode.h b/src/actions/transformations/url_decode.h index 5c5c266209..cc73c9c3fa 100644 --- a/src/actions/transformations/url_decode.h +++ b/src/actions/transformations/url_decode.h @@ -22,7 +22,7 @@ namespace modsecurity::actions::transformations { class UrlDecode : public Transformation { public: - explicit UrlDecode(const std::string &action); + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/url_decode_uni.h b/src/actions/transformations/url_decode_uni.h index 8dbac4627b..046f251a42 100644 --- a/src/actions/transformations/url_decode_uni.h +++ b/src/actions/transformations/url_decode_uni.h @@ -22,8 +22,7 @@ namespace modsecurity::actions::transformations { class UrlDecodeUni : public Transformation { public: - explicit UrlDecodeUni(const std::string &action) - : Transformation(action) { } + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/url_encode.cc b/src/actions/transformations/url_encode.cc index 36fef77117..2692a2d3d8 100644 --- a/src/actions/transformations/url_encode.cc +++ b/src/actions/transformations/url_encode.cc @@ -20,12 +20,6 @@ namespace modsecurity::actions::transformations { -UrlEncode::UrlEncode(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - - static inline bool url_enc(std::string &value) { const auto len = value.size() * 3 + 1; std::string ret(len, {}); diff --git a/src/actions/transformations/url_encode.h b/src/actions/transformations/url_encode.h index 4f3ffe7305..e112fb57fe 100644 --- a/src/actions/transformations/url_encode.h +++ b/src/actions/transformations/url_encode.h @@ -22,7 +22,7 @@ namespace modsecurity::actions::transformations { class UrlEncode : public Transformation { public: - explicit UrlEncode(const std::string &action); + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/transformations/utf8_to_unicode.h b/src/actions/transformations/utf8_to_unicode.h index bbb6cdc4de..af1253382a 100644 --- a/src/actions/transformations/utf8_to_unicode.h +++ b/src/actions/transformations/utf8_to_unicode.h @@ -22,8 +22,7 @@ namespace modsecurity::actions::transformations { class Utf8ToUnicode : public Transformation { public: - explicit Utf8ToUnicode(const std::string &action) - : Transformation(action) { } + using Transformation::Transformation; bool transform(std::string &value, const Transaction *trans) const override; }; diff --git a/src/actions/ver.h b/src/actions/ver.h index 364d567b31..8bce189ce4 100644 --- a/src/actions/ver.h +++ b/src/actions/ver.h @@ -29,7 +29,7 @@ namespace actions { class Ver : public Action { public: - explicit Ver(const std::string &action) : Action(action, ConfigurationKind) { } + explicit Ver(const std::string &action) : Action(action, Kind::ConfigurationKind) { } bool evaluate(RuleWithActions *rule, Transaction *transaction) override; diff --git a/src/parser/seclang-parser.cc b/src/parser/seclang-parser.cc index 767b8b229c..fbce57040d 100644 --- a/src/parser/seclang-parser.cc +++ b/src/parser/seclang-parser.cc @@ -2424,8 +2424,8 @@ namespace yy { definedPhase = phase->m_phase; secRuleDefinedPhase = phase->m_secRulesPhase; delete phase; - } else if (a->action_kind == actions::Action::RunTimeOnlyIfMatchKind || - a->action_kind == actions::Action::RunTimeBeforeMatchAttemptKind) { + } else if (a->action_kind == actions::Action::Kind::RunTimeOnlyIfMatchKind || + a->action_kind == actions::Action::Kind::RunTimeBeforeMatchAttemptKind) { actions::transformations::None *none = dynamic_cast(a); if (none != NULL) { driver.error(yystack_[2].location, "The transformation none is not suitable to be part of the SecDefaultActions"); diff --git a/src/parser/seclang-parser.yy b/src/parser/seclang-parser.yy index f661095128..41583768f5 100644 --- a/src/parser/seclang-parser.yy +++ b/src/parser/seclang-parser.yy @@ -1199,8 +1199,8 @@ expression: definedPhase = phase->m_phase; secRuleDefinedPhase = phase->m_secRulesPhase; delete phase; - } else if (a->action_kind == actions::Action::RunTimeOnlyIfMatchKind || - a->action_kind == actions::Action::RunTimeBeforeMatchAttemptKind) { + } else if (a->action_kind == actions::Action::Kind::RunTimeOnlyIfMatchKind || + a->action_kind == actions::Action::Kind::RunTimeBeforeMatchAttemptKind) { actions::transformations::None *none = dynamic_cast(a); if (none != NULL) { driver.error(@0, "The transformation none is not suitable to be part of the SecDefaultActions"); diff --git a/src/rule_with_actions.cc b/src/rule_with_actions.cc index 7aa0e649f2..1cde80054c 100644 --- a/src/rule_with_actions.cc +++ b/src/rule_with_actions.cc @@ -89,11 +89,11 @@ RuleWithActions::RuleWithActions( if (actions) { for (Action *a : *actions) { switch (a->action_kind) { - case Action::ConfigurationKind: + case Action::Kind::ConfigurationKind: a->evaluate(this, NULL); delete a; break; - case Action::RunTimeOnlyIfMatchKind: + case Action::Kind::RunTimeOnlyIfMatchKind: if (dynamic_cast(a)) { m_containsCaptureAction = true; delete a; @@ -247,7 +247,7 @@ void RuleWithActions::executeActionsAfterFullMatch(Transaction *trans, bool disruptiveAlreadyExecuted = false; for (const auto &a : trans->m_rules->m_defaultActions[getPhase()]) { // cppcheck-suppress ctunullpointer - if (a.get()->action_kind != actions::Action::RunTimeOnlyIfMatchKind) { + if (a.get()->action_kind != actions::Action::Kind::RunTimeOnlyIfMatchKind) { continue; } if (!a.get()->isDisruptive()) { @@ -374,7 +374,7 @@ void RuleWithActions::executeTransformations( if (none == 0) { for (auto &a : trans->m_rules->m_defaultActions[getPhase()]) { if (a->action_kind \ - != actions::Action::RunTimeBeforeMatchAttemptKind) { + != actions::Action::Kind::RunTimeBeforeMatchAttemptKind) { continue; } diff --git a/src/rules_exceptions.cc b/src/rules_exceptions.cc index 1349866d44..71cf28c223 100644 --- a/src/rules_exceptions.cc +++ b/src/rules_exceptions.cc @@ -36,15 +36,15 @@ bool RulesExceptions::loadUpdateActionById(double id, std::string *error) { for (auto &a : *actions) { - if (a->action_kind == actions::Action::ConfigurationKind) { + if (a->action_kind == actions::Action::Kind::ConfigurationKind) { std::cout << "General failure, action: " << a->m_name; std::cout << " has not expected to be used with UpdateActionByID."; std::cout << std::endl; } else if (a->action_kind - == actions::Action::RunTimeBeforeMatchAttemptKind) { + == actions::Action::Kind::RunTimeBeforeMatchAttemptKind) { m_action_pre_update_target_by_id.emplace(std::pair>(id , std::move(a))); - } else if (a->action_kind == actions::Action::RunTimeOnlyIfMatchKind) { + } else if (a->action_kind == actions::Action::Kind::RunTimeOnlyIfMatchKind) { m_action_pos_update_target_by_id.emplace(std::pair>(id , std::move(a))); } else { From a6d64bf615f9bce451bc5132f60a9bcfabb26901 Mon Sep 17 00:00:00 2001 From: Eduardo Arias Date: Sat, 17 Aug 2024 00:53:54 +0000 Subject: [PATCH 24/24] Replaced VALID_HEX, ISODIGIT & NBSP macros in string.h - Moved them into modsecurity::utils::string to avoid polluting the global namespace. --- src/actions/transformations/css_decode.cc | 1 + .../transformations/escape_seq_decode.cc | 2 ++ .../transformations/html_entity_decode.cc | 1 + src/actions/transformations/js_decode.cc | 1 + src/actions/transformations/sql_hex_decode.cc | 1 + src/actions/transformations/url_decode_uni.cc | 1 + src/utils/decode.cc | 7 ++--- src/utils/string.h | 28 +++++++++++-------- 8 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/actions/transformations/css_decode.cc b/src/actions/transformations/css_decode.cc index c5de63f73a..41da9390ea 100644 --- a/src/actions/transformations/css_decode.cc +++ b/src/actions/transformations/css_decode.cc @@ -17,6 +17,7 @@ #include "src/utils/string.h" +using namespace modsecurity::utils::string; namespace modsecurity::actions::transformations { diff --git a/src/actions/transformations/escape_seq_decode.cc b/src/actions/transformations/escape_seq_decode.cc index 2cc413e711..94df2269d5 100644 --- a/src/actions/transformations/escape_seq_decode.cc +++ b/src/actions/transformations/escape_seq_decode.cc @@ -17,6 +17,8 @@ #include "src/utils/string.h" +using namespace modsecurity::utils::string; + namespace modsecurity::actions::transformations { diff --git a/src/actions/transformations/html_entity_decode.cc b/src/actions/transformations/html_entity_decode.cc index 0b9d811b3b..8a0cc3e97d 100644 --- a/src/actions/transformations/html_entity_decode.cc +++ b/src/actions/transformations/html_entity_decode.cc @@ -23,6 +23,7 @@ #include "src/compat/msvc.h" #endif +using namespace modsecurity::utils::string; namespace modsecurity::actions::transformations { diff --git a/src/actions/transformations/js_decode.cc b/src/actions/transformations/js_decode.cc index 394a2cdcfd..857125c746 100644 --- a/src/actions/transformations/js_decode.cc +++ b/src/actions/transformations/js_decode.cc @@ -17,6 +17,7 @@ #include "src/utils/string.h" +using namespace modsecurity::utils::string; namespace modsecurity::actions::transformations { diff --git a/src/actions/transformations/sql_hex_decode.cc b/src/actions/transformations/sql_hex_decode.cc index 8f19e6197d..0ce2408726 100644 --- a/src/actions/transformations/sql_hex_decode.cc +++ b/src/actions/transformations/sql_hex_decode.cc @@ -19,6 +19,7 @@ #include "src/utils/string.h" +using namespace modsecurity::utils::string; namespace modsecurity::actions::transformations { diff --git a/src/actions/transformations/url_decode_uni.cc b/src/actions/transformations/url_decode_uni.cc index 57df7a566f..58d683c85b 100644 --- a/src/actions/transformations/url_decode_uni.cc +++ b/src/actions/transformations/url_decode_uni.cc @@ -18,6 +18,7 @@ #include "modsecurity/rules_set.h" #include "src/utils/string.h" +using namespace modsecurity::utils::string; namespace modsecurity::actions::transformations { diff --git a/src/utils/decode.cc b/src/utils/decode.cc index 32d95301e7..2735cf3eee 100644 --- a/src/utils/decode.cc +++ b/src/utils/decode.cc @@ -17,9 +17,9 @@ #include "modsecurity/modsecurity.h" #include "src/utils/string.h" +using namespace modsecurity::utils::string; -namespace modsecurity { -namespace utils { +namespace modsecurity::utils { bool urldecode_nonstrict_inplace(std::string &val, @@ -112,5 +112,4 @@ std::string uri_decode(const std::string & sSrc) { } -} // namespace utils -} // namespace modsecurity +} // namespace modsecurity::utils diff --git a/src/utils/string.h b/src/utils/string.h index dbfb9b4795..f5e52ff06d 100644 --- a/src/utils/string.h +++ b/src/utils/string.h @@ -13,6 +13,9 @@ * */ +#ifndef SRC_UTILS_STRING_H_ +#define SRC_UTILS_STRING_H_ + #include #include #include @@ -27,18 +30,21 @@ #include "src/compat/msvc.h" #endif -#ifndef SRC_UTILS_STRING_H_ -#define SRC_UTILS_STRING_H_ +namespace modsecurity::utils::string { -#define VALID_HEX(X) (((X >= '0') && (X <= '9')) || \ - ((X >= 'a') && (X <= 'f')) || ((X >= 'A') && (X <= 'F'))) -#define ISODIGIT(X) ((X >= '0') && (X <= '7')) -#define NBSP 160 +template +constexpr bool VALID_HEX(CharT X) { + return ((X >= '0') && (X <= '9')) + || ((X >= 'a') && (X <= 'f')) + || ((X >= 'A') && (X <= 'F')); +} +template +constexpr bool ISODIGIT(CharT X) { + return (X >= '0') && (X <= '7'); +} -namespace modsecurity { -namespace utils { -namespace string { +constexpr unsigned char NBSP = 160; const char HEX2DEC[256] = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ @@ -271,8 +277,6 @@ inline std::string toupper(std::string str) { // cppcheck-suppress passedByValue } -} // namespace string -} // namespace utils -} // namespace modsecurity +} // namespace modsecurity::utils::string #endif // SRC_UTILS_STRING_H_