diff --git a/headers/modsecurity/actions/action.h b/headers/modsecurity/actions/action.h index 374b77d6c6..24f0da6dbe 100644 --- a/headers/modsecurity/actions/action.h +++ b/headers/modsecurity/actions/action.h @@ -13,41 +13,66 @@ * */ -#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 { 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), @@ -74,8 +99,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 +110,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); } @@ -109,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/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..26967f2aa6 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/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/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/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/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/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.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/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.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/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.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/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.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/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.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/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.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..8c97dbe87e 100644 --- a/src/actions/transformations/base64_decode.h +++ b/src/actions/transformations/base64_decode.h @@ -13,33 +13,20 @@ * */ -#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) { } + using Transformation::Transformation; - 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..66b0678fa5 100644 --- a/src/actions/transformations/base64_decode_ext.h +++ b/src/actions/transformations/base64_decode_ext.h @@ -13,33 +13,20 @@ * */ -#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) { } + using Transformation::Transformation; - 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..3c1d96f196 100644 --- a/src/actions/transformations/base64_encode.h +++ b/src/actions/transformations/base64_encode.h @@ -13,33 +13,20 @@ * */ -#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) { } + using Transformation::Transformation; - 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..8db1529dfb 100644 --- a/src/actions/transformations/cmd_line.cc +++ b/src/actions/transformations/cmd_line.cc @@ -13,30 +13,17 @@ * */ -#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 { +bool CmdLine::transform(std::string &value, const Transaction *trans) const { + char *d = value.data(); + bool space = false; - -std::string CmdLine::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; - int space = 0; - - for (auto& a : value) { + for (const auto& a : value) { switch (a) { /* remove some characters */ case '"': @@ -52,9 +39,9 @@ std::string CmdLine::evaluate(const std::string &value, case '\t': case '\r': case '\n': - if (space == 0) { - ret.append(" "); - space++; + if (space == false) { + *d++ = ' '; + space = true; } break; @@ -62,26 +49,27 @@ std::string CmdLine::evaluate(const std::string &value, 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; } } - return ret; + const auto new_len = d - value.c_str(); + const auto changed = new_len != value.length(); + value.resize(new_len); + 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..27672b604b 100644 --- a/src/actions/transformations/cmd_line.h +++ b/src/actions/transformations/cmd_line.h @@ -13,35 +13,21 @@ * */ -#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) { } + using Transformation::Transformation; - 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..a9b31c962b 100644 --- a/src/actions/transformations/compress_whitespace.cc +++ b/src/actions/transformations/compress_whitespace.cc @@ -13,54 +13,36 @@ * */ -#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 { +bool CompressWhitespace::transform(std::string &value, const Transaction *trans) const { + bool inWhiteSpace = false; -CompressWhitespace::CompressWhitespace(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - -std::string CompressWhitespace::evaluate(const std::string &value, - Transaction *transaction) { + auto d = value.data(); - std::string a; - int inWhiteSpace = 0; - int i = 0; - - 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++; } - return a; + const auto new_len = d - value.c_str(); + const auto changed = new_len != value.length(); + value.resize(new_len); + 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..8f74a3c1c1 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: + using Transformation::Transformation; - 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..41da9390ea 100644 --- a/src/actions/transformations/css_decode.cc +++ b/src/actions/transformations/css_decode.cc @@ -13,42 +13,13 @@ * */ -#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" +using namespace modsecurity::utils::string; -namespace modsecurity { -namespace actions { -namespace transformations { - - -std::string CssDecode::evaluate(const std::string &value, - Transaction *transaction) { - - 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); - return ret; -} +namespace modsecurity::actions::transformations { /** @@ -58,15 +29,13 @@ std::string CssDecode::evaluate(const std::string &value, * 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; - - if (input == NULL) { - return -1; - } +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; - i = count = 0; + std::string::size_type i = 0; while (i < input_len) { /* Is the character a backslash? */ if (input[i] == '\\') { @@ -75,7 +44,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]))) { @@ -157,40 +126,45 @@ 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); } -} // 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..c9b451f837 100644 --- a/src/actions/transformations/css_decode.h +++ b/src/actions/transformations/css_decode.h @@ -13,37 +13,20 @@ * */ -#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; + using Transformation::Transformation; - static int css_decode_inplace(unsigned char *input, int64_t input_len); + 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_CSS_DECODE_H_ diff --git a/src/actions/transformations/escape_seq_decode.cc b/src/actions/transformations/escape_seq_decode.cc index 03303272ef..94df2269d5 100644 --- a/src/actions/transformations/escape_seq_decode.cc +++ b/src/actions/transformations/escape_seq_decode.cc @@ -13,36 +13,22 @@ * */ -#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 { +using namespace modsecurity::utils::string; -EscapeSeqDecode::EscapeSeqDecode(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} +namespace modsecurity::actions::transformations { -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; @@ -120,43 +106,29 @@ 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; } -std::string EscapeSeqDecode::evaluate(const std::string &value, - Transaction *transaction) { - - 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); - - return ret; +bool EscapeSeqDecode::transform(std::string &value, const Transaction *trans) const { + return ansi_c_sequences_decode_inplace(value); } -} // 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..71976fe126 100644 --- a/src/actions/transformations/escape_seq_decode.h +++ b/src/actions/transformations/escape_seq_decode.h @@ -13,35 +13,20 @@ * */ -#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: + using Transformation::Transformation; - 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; }; -} // 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..1b43b6cdf2 100644 --- a/src/actions/transformations/hex_decode.cc +++ b/src/actions/transformations/hex_decode.cc @@ -13,67 +13,35 @@ * */ -#include "src/actions/transformations/hex_decode.h" +#include "hex_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 { - -std::string HexDecode::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; - unsigned char *input; - int size = 0; +namespace modsecurity::actions::transformations { - input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); - if (input == NULL) { - return ""; - } +static inline int inplace(std::string &value) { + if (value.empty()) return false; - memcpy(input, value.c_str(), value.length()+1); + const auto len = value.length(); + auto d = reinterpret_cast(value.data()); + const auto data = d; - size = inplace(input, value.length()); + for (int i = 0; i <= len - 2; i += 2) { + *d++ = utils::string::x2c(&data[i]); + } - ret.assign(reinterpret_cast(input), size); - free(input); + *d = '\0'; - return ret; + 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); } -} // 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..1ee6a1b773 100644 --- a/src/actions/transformations/hex_decode.h +++ b/src/actions/transformations/hex_decode.h @@ -13,35 +13,20 @@ * */ -#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) { } + using Transformation::Transformation; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; - - static int inplace(unsigned char *data, int len); + 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_DECODE_H_ diff --git a/src/actions/transformations/hex_encode.cc b/src/actions/transformations/hex_encode.cc index 4e6121df60..689a132f76 100644 --- a/src/actions/transformations/hex_encode.cc +++ b/src/actions/transformations/hex_encode.cc @@ -13,41 +13,25 @@ * */ -#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::actions::transformations { -namespace modsecurity { -namespace actions { -namespace 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..9037a514fe 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: + using Transformation::Transformation; - 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..8a0cc3e97d 100644 --- a/src/actions/transformations/html_entity_decode.cc +++ b/src/actions/transformations/html_entity_decode.cc @@ -13,70 +13,36 @@ * */ -#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 +using namespace modsecurity::utils::string; -namespace modsecurity { -namespace actions { -namespace transformations { - - -std::string HtmlEntityDecode::evaluate(const std::string &value, - Transaction *transaction) { - 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); - - return ret; -} - +namespace modsecurity::actions::transformations { -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; - } +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; - 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. */ @@ -96,19 +62,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] == ';')) { @@ -122,19 +87,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] == ';')) { @@ -149,38 +113,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] == ';')) { @@ -196,17 +153,21 @@ 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; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity + +bool HtmlEntityDecode::transform(std::string &value, const Transaction *trans) const { + return inplace(value); +} + + +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/html_entity_decode.h b/src/actions/transformations/html_entity_decode.h index 44fcc32319..499f8f2ff8 100644 --- a/src/actions/transformations/html_entity_decode.h +++ b/src/actions/transformations/html_entity_decode.h @@ -13,40 +13,20 @@ * */ -#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) { } + using Transformation::Transformation; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; - - static int inplace(unsigned char *input, uint64_t input_len); + 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_HTML_ENTITY_DECODE_H_ diff --git a/src/actions/transformations/js_decode.cc b/src/actions/transformations/js_decode.cc index 2f4cf8bb57..857125c746 100644 --- a/src/actions/transformations/js_decode.cc +++ b/src/actions/transformations/js_decode.cc @@ -13,55 +13,22 @@ * */ -#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" +using namespace modsecurity::utils::string; -namespace modsecurity { -namespace actions { -namespace transformations { - - -std::string JsDecode::evaluate(const std::string &value, - Transaction *transaction) { - 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); - - return ret; -} +namespace modsecurity::actions::transformations { -int JsDecode::inplace(unsigned char *input, uint64_t input_len) { - unsigned char *d = (unsigned char *)input; - int64_t i, count; +static inline int 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] == '\\') { /* Character is an escape. */ @@ -82,14 +49,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]; @@ -110,7 +77,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 */ @@ -144,25 +111,28 @@ 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; } -} // namespace transformations -} // namespace actions -} // namespace modsecurity + +bool JsDecode::transform(std::string &value, const Transaction *trans) const { + return inplace(value); +} + + +} // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/js_decode.h b/src/actions/transformations/js_decode.h index 60d6617b35..840577cb6c 100644 --- a/src/actions/transformations/js_decode.h +++ b/src/actions/transformations/js_decode.h @@ -13,35 +13,20 @@ * */ -#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) { } + using Transformation::Transformation; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; - static int inplace(unsigned char *input, uint64_t input_len); + 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_JS_DECODE_H_ diff --git a/src/actions/transformations/length.cc b/src/actions/transformations/length.cc index 61015b82bf..ac98914c6e 100644 --- a/src/actions/transformations/length.cc +++ b/src/actions/transformations/length.cc @@ -13,34 +13,16 @@ * */ -#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; +bool Length::transform(std::string &value, const Transaction *trans) const { + value = std::to_string(value.size()); + return true; } -std::string Length::evaluate(const std::string &value, - Transaction *transaction) { - - return std::to_string(value.size()); -} -} // 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..39465238f4 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: + using Transformation::Transformation; - 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..0238b5a457 100644 --- a/src/actions/transformations/lower_case.cc +++ b/src/actions/transformations/lower_case.cc @@ -13,37 +13,19 @@ * */ -#include "src/actions/transformations/lower_case.h" -#include -#include -#include +#include "lower_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 { -LowerCase::LowerCase(const std::string &a) - : Transformation(a) { -} - -std::string LowerCase::evaluate(const std::string &val, - Transaction *transaction) { - 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); - } - - return value; +bool LowerCase::transform(std::string &value, const Transaction *trans) const { + return convert(value, [](auto c) { + return std::tolower(c); }); } -} // 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..192b2aa3fc 100644 --- a/src/actions/transformations/lower_case.h +++ b/src/actions/transformations/lower_case.h @@ -13,34 +13,35 @@ * */ -#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 +#include "transformation.h" -namespace modsecurity { -class Transaction; -namespace actions { -namespace transformations { +#include +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; -}; + using Transformation::Transformation; + + bool transform(std::string &value, const Transaction *trans) const override; -} // namespace transformations -} // namespace actions -} // namespace modsecurity + 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; + } +}; -#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..d1813c5ff3 100644 --- a/src/actions/transformations/md5.h +++ b/src/actions/transformations/md5.h @@ -13,33 +13,20 @@ * */ -#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) { } + using Transformation::Transformation; - 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..91c0402729 100644 --- a/src/actions/transformations/normalise_path.cc +++ b/src/actions/transformations/normalise_path.cc @@ -13,47 +13,14 @@ * */ -#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; - - 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); - - return ret; +bool NormalisePath::transform(std::string &value, const Transaction *trans) const { + return normalize_path_inplace(value, false); } @@ -61,21 +28,22 @@ std::string NormalisePath::evaluate(const std::string &value, * * 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? @@ -83,7 +51,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; @@ -94,11 +61,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; } } @@ -116,7 +83,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? */ @@ -153,25 +120,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++; } @@ -191,7 +158,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 @@ -199,30 +166,28 @@ 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; } -} // 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..a1ef89189a 100644 --- a/src/actions/transformations/normalise_path.h +++ b/src/actions/transformations/normalise_path.h @@ -13,37 +13,22 @@ * */ -#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: + using Transformation::Transformation; - explicit NormalisePath(const std::string &action); + bool transform(std::string &value, const Transaction *trans) const override; - std::string evaluate(const std::string &exp, - Transaction *transaction) 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 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..b60943e155 100644 --- a/src/actions/transformations/normalise_path_win.cc +++ b/src/actions/transformations/normalise_path_win.cc @@ -13,48 +13,17 @@ * */ -#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; - - 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); - - return ret; +bool NormalisePathWin::transform(std::string &value, const Transaction *trans) const { + return NormalisePath::normalize_path_inplace(value, true); } -} // 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..0cf11260fc 100644 --- a/src/actions/transformations/normalise_path_win.h +++ b/src/actions/transformations/normalise_path_win.h @@ -13,33 +13,20 @@ * */ -#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) { } + using Transformation::Transformation; - 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..d9327b9eb2 100644 --- a/src/actions/transformations/parity_even_7bit.cc +++ b/src/actions/transformations/parity_even_7bit.cc @@ -13,70 +13,15 @@ * */ -#include "src/actions/transformations/parity_even_7bit.h" +#include "parity_even_7bit.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 ParityEven7bit::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; - 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); - - inplace(input, value.length()); - - ret.assign(reinterpret_cast(input), value.length()); - free(input); - - return ret; +bool ParityEven7bit::transform(std::string &value, const Transaction *trans) const { + return ParityEven7bit::inplace(value); } -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; -} - - -} // 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..8e107a5da8 100644 --- a/src/actions/transformations/parity_even_7bit.h +++ b/src/actions/transformations/parity_even_7bit.h @@ -13,33 +13,42 @@ * */ -#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) { } + using Transformation::Transformation; - std::string evaluate(const std::string &exp, Transaction *transaction) override; - static bool inplace(unsigned char *input, uint64_t input_len); -}; + bool transform(std::string &value, const Transaction *trans) const override; + + template + static bool inplace(std::string &value) { + if (value.empty()) return false; -} // namespace transformations -} // namespace actions -} // namespace modsecurity + 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; + } +}; -#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..865a2754ed 100644 --- a/src/actions/transformations/parity_odd_7bit.cc +++ b/src/actions/transformations/parity_odd_7bit.cc @@ -13,69 +13,16 @@ * */ -#include "src/actions/transformations/parity_odd_7bit.h" +#include "parity_odd_7bit.h" +#include "parity_even_7bit.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 ParityOdd7bit::evaluate(const std::string &value, - Transaction *transaction) { - 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); - - inplace(input, value.length()); - - ret.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; +bool ParityOdd7bit::transform(std::string &value, const Transaction *trans) const { + return ParityEven7bit::inplace(value); } -} // 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..0b9164b912 100644 --- a/src/actions/transformations/parity_odd_7bit.h +++ b/src/actions/transformations/parity_odd_7bit.h @@ -13,33 +13,20 @@ * */ -#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) { } + using Transformation::Transformation; - std::string evaluate(const std::string &exp, Transaction *transaction) override; - static bool inplace(unsigned char *input, uint64_t input_len); + 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_PARITY_ODD_7BIT_H_ diff --git a/src/actions/transformations/parity_zero_7bit.cc b/src/actions/transformations/parity_zero_7bit.cc index 7bb846362c..77ad05145b 100644 --- a/src/actions/transformations/parity_zero_7bit.cc +++ b/src/actions/transformations/parity_zero_7bit.cc @@ -13,61 +13,26 @@ * */ -#include "src/actions/transformations/parity_zero_7bit.h" +#include "parity_zero_7bit.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 { +static inline bool inplace(std::string &value) { + if (value.empty()) return false; - -std::string ParityZero7bit::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; - 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); - - inplace(input, value.length()); - - ret.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); } -} // 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..aa9d1bf328 100644 --- a/src/actions/transformations/parity_zero_7bit.h +++ b/src/actions/transformations/parity_zero_7bit.h @@ -13,33 +13,20 @@ * */ -#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) { } + using Transformation::Transformation; - std::string evaluate(const std::string &exp, Transaction *transaction) override; - static bool inplace(unsigned char *input, uint64_t input_len); + 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_PARITY_ZERO_7BIT_H_ diff --git a/src/actions/transformations/remove_comments.cc b/src/actions/transformations/remove_comments.cc index 043dd9505a..5f3edaef58 100644 --- a/src/actions/transformations/remove_comments.cc +++ b/src/actions/transformations/remove_comments.cc @@ -13,61 +13,40 @@ * */ -#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 { +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; - -std::string RemoveComments::evaluate(const std::string &value, - Transaction *transaction) { - 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; - - 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]; @@ -77,7 +56,7 @@ std::string RemoveComments::evaluate(const std::string &value, } else { if ((input[i] == '*') && (i + 1 < input_len) && (input[i + 1] == '/')) { - incomment = 0; + incomment = false; i += 2; input[j] = input[i]; i++; @@ -85,7 +64,7 @@ std::string RemoveComments::evaluate(const std::string &value, } 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++; @@ -100,13 +79,14 @@ std::string RemoveComments::evaluate(const std::string &value, input[j++] = ' '; } - ret.assign(reinterpret_cast(input), j); - free(input); + value.resize(j); + return changed; +} + - return ret; +bool RemoveComments::transform(std::string &value, const Transaction *trans) const { + return inplace(value); } -} // 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..948536cbf5 100644 --- a/src/actions/transformations/remove_comments.h +++ b/src/actions/transformations/remove_comments.h @@ -13,35 +13,20 @@ * */ -#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) { } + using Transformation::Transformation; - 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..7e666db31f 100644 --- a/src/actions/transformations/remove_comments_char.cc +++ b/src/actions/transformations/remove_comments_char.cc @@ -13,62 +13,51 @@ * */ -#include "src/actions/transformations/remove_comments_char.h" - -#include - -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" - - -namespace modsecurity { -namespace actions { -namespace transformations { - -RemoveCommentsChar::RemoveCommentsChar(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - -std::string RemoveCommentsChar::evaluate(const std::string &val, - Transaction *transaction) { - size_t i = 0; - std::string transformed_value; - transformed_value.reserve(val.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; +#include "remove_comments_char.h" + + +namespace modsecurity::actions::transformations { + + +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 (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++; } } - return transformed_value; + + const auto changed = d != s; + const auto new_len = d - value.c_str(); + value.resize(new_len); + 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..d11b0148a3 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); + using Transformation::Transformation; - 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..1d3cc552e6 100644 --- a/src/actions/transformations/remove_nulls.cc +++ b/src/actions/transformations/remove_nulls.cc @@ -13,40 +13,15 @@ * */ -#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) { - 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++; - } - - return transformed_value; +bool RemoveNulls::transform(std::string &value, const Transaction *trans) const { + return remove_if(value, [](const auto c) { return c == '\0'; }); } -} // 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..67c90ee018 100644 --- a/src/actions/transformations/remove_nulls.h +++ b/src/actions/transformations/remove_nulls.h @@ -13,34 +13,34 @@ * */ -#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 { +#include + +namespace modsecurity::actions::transformations { class RemoveNulls : public Transformation { public: - explicit RemoveNulls(const std::string &action) - : Transformation(action) { } + using Transformation::Transformation; - 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 + 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; + } +}; -#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..f7047f4760 100644 --- a/src/actions/transformations/remove_whitespace.cc +++ b/src/actions/transformations/remove_whitespace.cc @@ -13,49 +13,27 @@ * */ -#include "src/actions/transformations/remove_whitespace.h" +#include "remove_whitespace.h" -#include +#include "remove_nulls.h" -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +namespace modsecurity::actions::transformations { -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) { - 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++; - } - - return transformed_value; + return std::isspace(static_cast(c)) + || c == nonBreakingSpaces + || c == nonBreakingSpaces2; + }; + + return RemoveNulls::remove_if(value, pred); } -} // 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..b95a508b74 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); + using Transformation::Transformation; - 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..78ae786c73 100644 --- a/src/actions/transformations/replace_comments.cc +++ b/src/actions/transformations/replace_comments.cc @@ -13,54 +13,34 @@ * */ -#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 { +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; -ReplaceComments::ReplaceComments(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - -std::string ReplaceComments::evaluate(const std::string &value, - Transaction *transaction) { - 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()) + 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++; @@ -74,15 +54,14 @@ std::string ReplaceComments::evaluate(const std::string &value, input[j++] = ' '; } + value.resize(j); + return changed; +} - std::string resp; - resp.append(reinterpret_cast(input), j); - - free(input); - return resp; +bool ReplaceComments::transform(std::string &value, const Transaction *trans) const { + return inplace(value); } -} // 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..db206e538f 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: + using Transformation::Transformation; - 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..9792da5d03 100644 --- a/src/actions/transformations/replace_nulls.cc +++ b/src/actions/transformations/replace_nulls.cc @@ -13,40 +13,23 @@ * */ -#include "src/actions/transformations/replace_nulls.h" +#include "replace_nulls.h" -#include -#include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +namespace modsecurity::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { +bool ReplaceNulls::transform(std::string &value, const Transaction *trans) const { + bool changed = false; -ReplaceNulls::ReplaceNulls(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - -std::string ReplaceNulls::evaluate(const std::string &val, - Transaction *transaction) { - int64_t i; - std::string value(val); - - i = 0; - while (i < value.size()) { - if (value.at(i) == '\0') { - value[i] = ' '; - } else { - i++; + for(auto &c : value) { + if (c == '\0') { + c = ' '; + changed = true; } } - return 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..a01077c704 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: + using Transformation::Transformation; - 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..388633455c 100644 --- a/src/actions/transformations/sha1.cc +++ b/src/actions/transformations/sha1.cc @@ -13,35 +13,18 @@ * */ -#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 { - -Sha1::Sha1(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} +namespace modsecurity::actions::transformations { -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..f777641141 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; -}; + using Transformation::Transformation; -} // 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..0ce2408726 100644 --- a/src/actions/transformations/sql_hex_decode.cc +++ b/src/actions/transformations/sql_hex_decode.cc @@ -13,101 +13,62 @@ * */ -#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" +using namespace modsecurity::utils::string; -namespace modsecurity { -namespace actions { -namespace 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 - -std::string SqlHexDecode::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; - unsigned char *input; - int size = 0; +namespace modsecurity::actions::transformations { - 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); - - return ret; +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; - } - - data++; - ++count; - - // Do we need to keep "0x" if no hexa after? - if (!VALID_HEX(data[0]) || !VALID_HEX(data[1])) { - data -= 2; - count -= 2; - continue; - } - - while (VALID_HEX(data[0]) && VALID_HEX(data[1])) { - *d++ = utils::string::x2c(data); - data += 2; - count += 2; + else { + *d++ = *data++; } } *d = '\0'; - return strlen(reinterpret_cast(begin)); + + value.resize(d - reinterpret_cast(value.c_str())); + return changed; } +bool SqlHexDecode::transform(std::string &value, const Transaction *trans) const { + return inplace(value); +} + -} // 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..0acb1cff6b 100644 --- a/src/actions/transformations/sql_hex_decode.h +++ b/src/actions/transformations/sql_hex_decode.h @@ -13,42 +13,20 @@ * */ -#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) { } - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + using Transformation::Transformation; - 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; - } + 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_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..1d0ea99aa6 100644 --- a/src/actions/transformations/transformation.h +++ b/src/actions/transformations/transformation.h @@ -13,37 +13,23 @@ * */ -#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: explicit Transformation(const std::string& _action) - : Action(_action, RunTimeBeforeMatchAttemptKind) { } - - explicit Transformation(const std::string& _action, int kind) - : Action(_action, kind) { } - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + : Action(_action, Kind::RunTimeBeforeMatchAttemptKind) { } 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..2056b25622 100644 --- a/src/actions/transformations/trim.cc +++ b/src/actions/transformations/trim.cc @@ -13,67 +13,51 @@ * */ -#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) { - 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); - }) - ); + }); - return s; + const bool changed = it != s.begin(); + + s.erase(s.begin(), it); + + 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(); - return s; -} + const bool changed = it != s.end(); + s.erase(it, s.end()); -std::string *Trim::trim(std::string *s) { - return ltrim(rtrim(s)); + return changed; } -Trim::Trim(const std::string &action) - : Transformation(action) { - this->action_kind = 1; +bool Trim::trim(std::string &s) { + bool changed = false; + changed |= rtrim(s); + changed |= ltrim(s); + return changed; } -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 { + return trim(value); } -} // 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..e436f5bf54 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: + using Transformation::Transformation; - 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 bool ltrim(std::string &s); + static bool rtrim(std::string &s); + static bool 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..2ce7014910 100644 --- a/src/actions/transformations/trim_left.cc +++ b/src/actions/transformations/trim_left.cc @@ -13,37 +13,16 @@ * */ -#include "src/actions/transformations/trim_left.h" +#include "trim_left.h" +#include "trim.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::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { - - -TrimLeft::TrimLeft(const std::string &action) - : Trim(action) { - this->action_kind = 1; +bool TrimLeft::transform(std::string &value, const Transaction *trans) const { + return Trim::ltrim(value); } -std::string TrimLeft::evaluate(const std::string &val, - Transaction *transaction) { - std::string value(val); - return *ltrim(&value); -} -} // 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..8acf1fe593 100644 --- a/src/actions/transformations/trim_left.h +++ b/src/actions/transformations/trim_left.h @@ -13,34 +13,20 @@ * */ -#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" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { -class TrimLeft : public Trim { +class TrimLeft : public Transformation { public: - explicit TrimLeft(const std::string &action) ; + using Transformation::Transformation; - 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..e6536786ba 100644 --- a/src/actions/transformations/trim_right.cc +++ b/src/actions/transformations/trim_right.cc @@ -13,35 +13,16 @@ * */ -#include "src/actions/transformations/trim_right.h" +#include "trim_right.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::actions::transformations { -namespace modsecurity { -namespace actions { -namespace transformations { - -TrimRight::TrimRight(const std::string &action) - : Trim(action) { - this->action_kind = 1; +bool TrimRight::transform(std::string &value, const Transaction *trans) const { + return Trim::rtrim(value); } -std::string TrimRight::evaluate(const std::string &val, - Transaction *transaction) { - std::string value(val); - return *this->rtrim(&value); -} -} // 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..7e31795a31 100644 --- a/src/actions/transformations/trim_right.h +++ b/src/actions/transformations/trim_right.h @@ -13,34 +13,20 @@ * */ -#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" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { -class TrimRight : public Trim { +class TrimRight : public Transformation { public: - explicit TrimRight(const std::string &action) ; + using Transformation::Transformation; - 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..2b3978c740 100644 --- a/src/actions/transformations/upper_case.cc +++ b/src/actions/transformations/upper_case.cc @@ -13,37 +13,21 @@ * */ -#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 { +#include "lower_case.h" -UpperCase::UpperCase(const std::string &a) - : Transformation(a) { -} - -std::string UpperCase::evaluate(const std::string &val, - Transaction *transaction) { - std::string value(val); - std::locale loc; +namespace modsecurity::actions::transformations { - for (std::string::size_type i=0; i < value.length(); ++i) { - value[i] = std::toupper(value[i], loc); - } - return value; +bool UpperCase::transform(std::string &value, const Transaction *trans) const { + return LowerCase::convert(value, [](auto c) + { return std::toupper(c); }); } -} // 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..87a1df8a0a 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) ; + using Transformation::Transformation; - 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..dbc7bf9fb9 100644 --- a/src/actions/transformations/url_decode.cc +++ b/src/actions/transformations/url_decode.cc @@ -13,52 +13,18 @@ * */ -#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 { - - -UrlDecode::UrlDecode(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - -std::string UrlDecode::evaluate(const std::string &value, - Transaction *transaction) { - 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); +namespace modsecurity::actions::transformations { - free(val); - return out; +bool UrlDecode::transform(std::string &value, const Transaction *trans) const { + int invalid_count; + return utils::urldecode_nonstrict_inplace(value, invalid_count); } -} // 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..cc73c9c3fa 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: + using Transformation::Transformation; - 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..58d683c85b 100644 --- a/src/actions/transformations/url_decode_uni.cc +++ b/src/actions/transformations/url_decode_uni.cc @@ -13,66 +13,30 @@ * */ -#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 { - -std::string UrlDecodeUni::evaluate(const std::string &value, - Transaction *t) { - std::string ret; - unsigned char *input; +using namespace modsecurity::utils::string; - 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); - - return ret; -} +namespace modsecurity::actions::transformations { /** * * IMP1 Assumes NUL-terminated */ -int UrlDecodeUni::inplace(unsigned char *input, uint64_t input_len, - Transaction *t) { - unsigned char *d = input; - int64_t i, count, fact, j, xv; +static inline bool inplace(std::string &value, + const Transaction *t) { + bool changed = false; + auto d = reinterpret_cast(value.data()); + const unsigned char *input = d; + const auto input_len = value.length(); + + std::string::size_type i, count, fact, j, xv; int Code, hmap = -1; - if (input == NULL) return -1; - i = count = 0; while (i < input_len) { if (input[i] == '%') { @@ -131,19 +95,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. */ @@ -158,8 +120,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++]; @@ -168,28 +130,32 @@ 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); } -} // 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..046f251a42 100644 --- a/src/actions/transformations/url_decode_uni.h +++ b/src/actions/transformations/url_decode_uni.h @@ -13,35 +13,20 @@ * */ -#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) { } + using Transformation::Transformation; - std::string evaluate(const std::string &exp, Transaction *transaction) override; - static int inplace(unsigned char *input, uint64_t input_len, - Transaction *transaction); + 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_UNI_H_ diff --git a/src/actions/transformations/url_encode.cc b/src/actions/transformations/url_encode.cc index 056755ca2d..2692a2d3d8 100644 --- a/src/actions/transformations/url_encode.cc +++ b/src/actions/transformations/url_encode.cc @@ -13,90 +13,50 @@ * */ -#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 { - - -UrlEncode::UrlEncode(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - +namespace modsecurity::actions::transformations { -std::string UrlEncode::url_enc(const char *input, - unsigned int input_len, int *changed) { - char *rval, *d; - unsigned int i, len; - int count = 0; - *changed = 0; +static inline bool url_enc(std::string &value) { + const auto len = value.size() * 3 + 1; + std::string ret(len, {}); - 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; } -std::string UrlEncode::evaluate(const std::string &value, - Transaction *transaction) { - int changed; - - std::string ret = url_enc(value.c_str(), value.size(), &changed); - - return ret; +bool UrlEncode::transform(std::string &value, const Transaction *trans) const { + return url_enc(value); } -} // 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..e112fb57fe 100644 --- a/src/actions/transformations/url_encode.h +++ b/src/actions/transformations/url_encode.h @@ -13,37 +13,20 @@ * */ -#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: + using Transformation::Transformation; - explicit UrlEncode(const std::string &action) ; - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; - - std::string url_enc(const char *input, - unsigned int input_len, int *changed); + 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_ENCODE_H_ diff --git a/src/actions/transformations/utf8_to_unicode.cc b/src/actions/transformations/utf8_to_unicode.cc index 70c1f9c8e1..4b01583e7c 100644 --- a/src/actions/transformations/utf8_to_unicode.cc +++ b/src/actions/transformations/utf8_to_unicode.cc @@ -13,83 +13,40 @@ * */ -#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 { - - -std::string Utf8ToUnicode::evaluate(const std::string &value, - Transaction *transaction) { - 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 { - return ret; -} +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; - - if (input == NULL) { - free(data); - return NULL; - } + const auto len = input_len * 4 + 1; + std::string ret(len, {}); + auto data = ret.data(); - 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; @@ -117,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 */ @@ -147,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) { @@ -199,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) { @@ -261,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 { @@ -309,10 +266,15 @@ 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); } -} // 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..af1253382a 100644 --- a/src/actions/transformations/utf8_to_unicode.h +++ b/src/actions/transformations/utf8_to_unicode.h @@ -13,40 +13,20 @@ * */ -#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_ -#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; +#include "transformation.h" -namespace actions { -namespace transformations { +namespace modsecurity::actions::transformations { class Utf8ToUnicode : public Transformation { public: - explicit Utf8ToUnicode(const std::string &action) : Transformation(action) { } + using Transformation::Transformation; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; - - static char *inplace(unsigned char *input, uint64_t input_len, - int *changed); + bool transform(std::string &value, const Transaction *trans) const override; }; -} // 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/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/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/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 e5d8183f67..1cde80054c 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" @@ -88,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; @@ -246,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()) { @@ -323,49 +324,42 @@ void RuleWithActions::executeAction(Transaction *trans, inline void RuleWithActions::executeTransformation( - actions::transformations::Transformation *a, - std::shared_ptr *value, - 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; + const actions::transformations::Transformation &a, + std::string &value, + const Transaction *trans, + TransformationResults &ret, + std::string &path, + int &nth) const { + + if (a.transform(value, trans) && + m_containsMultiMatchAction) { + ret.emplace_back(value, a.m_name); + 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) + ") " + \ - *a->m_name.get() + ": \"" + \ - utils::string::limitTo(80, newValue) +"\""); + std::to_string(nth) + ") " + \ + *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); + std::string path; + 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) { @@ -380,21 +374,23 @@ 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; } // FIXME: here the object needs to be a transformation already. - Transformation *t = dynamic_cast(a.get()); - executeTransformation(t, &value, trans, &ret, &path, - &transformations); + 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, - &transformations); + executeTransformation(*a, value, trans, ret, path, + transformations); } if (a->m_isNone) { none--; @@ -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,10 +416,11 @@ 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, - &transformations); + executeTransformation(*a, value, trans, ret, path, + transformations); } if (a->m_isNone) { none--; @@ -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/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 { 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/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 diff --git a/src/utils/decode.cc b/src/utils/decode.cc index 8629f8fb0c..2735cf3eee 100644 --- a/src/utils/decode.cc +++ b/src/utils/decode.cc @@ -17,68 +17,60 @@ #include "modsecurity/modsecurity.h" #include "src/utils/string.h" +using namespace modsecurity::utils::string; -namespace modsecurity { -namespace utils { +namespace modsecurity::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; } @@ -120,5 +112,4 @@ std::string uri_decode(const std::string & sSrc) { } -} // namespace utils -} // namespace modsecurity +} // namespace modsecurity::utils 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); 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_ diff --git a/src/utils/string.h b/src/utils/string.h index b0c3c17d97..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 */ @@ -235,18 +241,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(); +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(); - 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]); + for (const unsigned char c : input) { + *d++ = lut[c >> 4]; + *d++ = lut[c & 15]; } - return output; + + return a; } @@ -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_ 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) {