Merge pull request #3231 from eduar-hte/remove-copies-transformations

Remove unnecessary heap allocated copies in Transformation actions
This commit is contained in:
Ervin Hegedus 2024-08-28 14:33:59 +02:00 committed by GitHub
commit 9148668571
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
146 changed files with 1185 additions and 2816 deletions

View File

@ -13,41 +13,66 @@
* *
*/ */
#ifdef __cplusplus
#include <string>
#include <iostream>
#include <memory>
#endif
#include "modsecurity/intervention.h"
#include "modsecurity/rule.h"
#include "modsecurity/rule_with_actions.h"
#ifndef HEADERS_MODSECURITY_ACTIONS_ACTION_H_ #ifndef HEADERS_MODSECURITY_ACTIONS_ACTION_H_
#define HEADERS_MODSECURITY_ACTIONS_ACTION_H_ #define HEADERS_MODSECURITY_ACTIONS_ACTION_H_
#ifdef __cplusplus #ifdef __cplusplus
#include <string>
#include <memory>
namespace modsecurity { namespace modsecurity {
class Transaction; class Transaction;
class RuleWithOperator; class RuleWithOperator;
class RuleWithActions;
class RuleMessage;
namespace actions { namespace actions {
class Action { class Action {
public: 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) explicit Action(const std::string& _action)
: m_isNone(false), : m_isNone(false),
temporaryAction(false), temporaryAction(false),
action_kind(2), action_kind(Kind::RunTimeOnlyIfMatchKind),
m_name(nullptr), m_name(nullptr),
m_parser_payload("") { m_parser_payload("") {
set_name_and_payload(_action); set_name_and_payload(_action);
} }
explicit Action(const std::string& _action, int kind) explicit Action(const std::string& _action, Kind kind)
: m_isNone(false), : m_isNone(false),
temporaryAction(false), temporaryAction(false),
action_kind(kind), action_kind(kind),
@ -74,8 +99,6 @@ class Action {
virtual ~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);
virtual bool evaluate(RuleWithActions *rule, Transaction *transaction, virtual bool evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> ruleMessage) { std::shared_ptr<RuleMessage> ruleMessage) {
@ -87,9 +110,9 @@ class Action {
void set_name_and_payload(const std::string& data) { void set_name_and_payload(const std::string& data) {
size_t pos = data.find(":"); 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); pos = data.find(":", 2);
} }
@ -109,41 +132,9 @@ class Action {
bool m_isNone; bool m_isNone;
bool temporaryAction; bool temporaryAction;
int action_kind; Kind action_kind;
std::shared_ptr<std::string> m_name; std::shared_ptr<std::string> m_name;
std::string m_parser_payload; 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,
};
}; };

View File

@ -52,7 +52,7 @@ namespace operators {
class Operator; class Operator;
} }
using TransformationResult = std::pair<std::shared_ptr<std::string>, using TransformationResult = std::pair<std::string,
std::shared_ptr<std::string>>; std::shared_ptr<std::string>>;
using TransformationResults = std::list<TransformationResult>; using TransformationResults = std::list<TransformationResult>;

View File

@ -119,16 +119,7 @@ class RuleWithActions : public Rule {
void executeTransformations( void executeTransformations(
Transaction *trasn, const std::string &value, TransformationResults &ret); const Transaction *trasn, const std::string &value, TransformationResults &ret);
inline void executeTransformation(
actions::transformations::Transformation *a,
std::shared_ptr<std::string> *value,
Transaction *trans,
TransformationResults *ret,
std::string *path,
int *nth) const;
void performLogging(Transaction *trans, void performLogging(Transaction *trans,
std::shared_ptr<RuleMessage> ruleMessage, std::shared_ptr<RuleMessage> ruleMessage,
@ -166,6 +157,14 @@ class RuleWithActions : public Rule {
RuleWithActions *m_chainedRuleParent; RuleWithActions *m_chainedRuleParent;
private: 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 */
actions::Action *m_disruptiveAction; actions::Action *m_disruptiveAction;
actions::LogData *m_logData; actions::LogData *m_logData;

View File

@ -247,11 +247,9 @@ UTILS = \
utils/geo_lookup.cc \ utils/geo_lookup.cc \
utils/https_client.cc \ utils/https_client.cc \
utils/ip_tree.cc \ utils/ip_tree.cc \
utils/md5.cc \
utils/msc_tree.cc \ utils/msc_tree.cc \
utils/random.cc \ utils/random.cc \
utils/regex.cc \ utils/regex.cc \
utils/sha1.cc \
utils/system.cc \ utils/system.cc \
utils/shared_files.cc utils/shared_files.cc

View File

@ -15,16 +15,10 @@
#include "src/actions/accuracy.h" #include "src/actions/accuracy.h"
#include <iostream> #include "modsecurity/rule_with_actions.h"
#include <string>
#include "modsecurity/actions/action.h"
#include "modsecurity/transaction.h"
#include "modsecurity/rule.h"
namespace modsecurity { namespace modsecurity::actions {
namespace actions {
bool Accuracy::init(std::string *error) { bool Accuracy::init(std::string *error) {
@ -45,5 +39,4 @@ bool Accuracy::evaluate(RuleWithActions *rule, Transaction *transaction) {
} }
} // namespace actions } // namespace modsecurity::actions
} // namespace modsecurity

View File

@ -30,7 +30,7 @@ namespace actions {
class Accuracy : public Action { class Accuracy : public Action {
public: public:
explicit Accuracy(const std::string &action) explicit Accuracy(const std::string &action)
: Action(action, ConfigurationKind), : Action(action, Kind::ConfigurationKind),
m_accuracy(0) { } m_accuracy(0) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction) override; bool evaluate(RuleWithActions *rule, Transaction *transaction) override;

View File

@ -45,12 +45,6 @@ namespace modsecurity {
namespace actions { namespace actions {
std::string Action::evaluate(const std::string &value,
Transaction *transaction) {
return value;
}
bool Action::evaluate(RuleWithActions *rule, Transaction *transaction) { bool Action::evaluate(RuleWithActions *rule, Transaction *transaction) {
return true; return true;
} }

View File

@ -33,7 +33,7 @@ namespace actions {
class AuditLog : public Action { class AuditLog : public Action {
public: public:
explicit AuditLog(const std::string &action) explicit AuditLog(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind) { } : Action(action) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction, bool evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) override; std::shared_ptr<RuleMessage> rm) override;

View File

@ -29,7 +29,7 @@ namespace actions {
class Capture : public Action { class Capture : public Action {
public: public:
explicit Capture(const std::string &action) explicit Capture(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind) { } : Action(action) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction) override; bool evaluate(RuleWithActions *rule, Transaction *transaction) override;
}; };

View File

@ -15,14 +15,9 @@
#include "src/actions/chain.h" #include "src/actions/chain.h"
#include <iostream> #include "modsecurity/rule_with_actions.h"
#include <string>
#include "modsecurity/transaction.h" namespace modsecurity::actions {
#include "modsecurity/rule.h"
namespace modsecurity {
namespace actions {
bool Chain::evaluate(RuleWithActions *rule, Transaction *transaction) { bool Chain::evaluate(RuleWithActions *rule, Transaction *transaction) {
@ -31,5 +26,4 @@ bool Chain::evaluate(RuleWithActions *rule, Transaction *transaction) {
} }
} // namespace actions } // namespace modsecurity::actions
} // namespace modsecurity

View File

@ -33,7 +33,7 @@ namespace actions {
class Chain : public Action { class Chain : public Action {
public: public:
explicit Chain(const std::string &action) explicit Chain(const std::string &action)
: Action(action, ConfigurationKind) { } : Action(action, Kind::ConfigurationKind) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction) override; bool evaluate(RuleWithActions *rule, Transaction *transaction) override;
}; };

View File

@ -34,7 +34,7 @@ namespace ctl {
class AuditEngine : public Action { class AuditEngine : public Action {
public: public:
explicit AuditEngine(const std::string &action) explicit AuditEngine(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind), : Action(action),
m_auditEngine(audit_log::AuditLog::AuditLogStatus::NotSetLogStatus) { } m_auditEngine(audit_log::AuditLog::AuditLogStatus::NotSetLogStatus) { }
bool init(std::string *error) override; bool init(std::string *error) override;

View File

@ -29,7 +29,7 @@ namespace ctl {
class AuditLogParts : public Action { class AuditLogParts : public Action {
public: public:
explicit AuditLogParts(const std::string &action) explicit AuditLogParts(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind), : Action(action),
mPartsAction(0), mPartsAction(0),
mParts("") { } mParts("") { }

View File

@ -30,7 +30,7 @@ namespace ctl {
class RequestBodyAccess : public Action { class RequestBodyAccess : public Action {
public: public:
explicit RequestBodyAccess(const std::string &action) explicit RequestBodyAccess(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind), : Action(action),
m_request_body_access(false) { } m_request_body_access(false) { }
bool init(std::string *error) override; bool init(std::string *error) override;

View File

@ -29,7 +29,7 @@ namespace ctl {
class RequestBodyProcessorJSON : public Action { class RequestBodyProcessorJSON : public Action {
public: public:
explicit RequestBodyProcessorJSON(const std::string &action) explicit RequestBodyProcessorJSON(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind) { } : Action(action) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction) override; bool evaluate(RuleWithActions *rule, Transaction *transaction) override;
}; };

View File

@ -29,7 +29,7 @@ namespace ctl {
class RequestBodyProcessorURLENCODED : public Action { class RequestBodyProcessorURLENCODED : public Action {
public: public:
explicit RequestBodyProcessorURLENCODED(const std::string &action) explicit RequestBodyProcessorURLENCODED(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind) { } : Action(action) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction) override; bool evaluate(RuleWithActions *rule, Transaction *transaction) override;
}; };

View File

@ -29,7 +29,7 @@ namespace ctl {
class RequestBodyProcessorXML : public Action { class RequestBodyProcessorXML : public Action {
public: public:
explicit RequestBodyProcessorXML(const std::string &action) explicit RequestBodyProcessorXML(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind) { } : Action(action) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction) override; bool evaluate(RuleWithActions *rule, Transaction *transaction) override;
}; };

View File

@ -31,7 +31,7 @@ namespace ctl {
class RuleEngine : public Action { class RuleEngine : public Action {
public: public:
explicit RuleEngine(const std::string &action) explicit RuleEngine(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind), : Action(action),
m_ruleEngine(RulesSetProperties::PropertyNotSetRuleEngine) { } m_ruleEngine(RulesSetProperties::PropertyNotSetRuleEngine) { }
bool init(std::string *error) override; bool init(std::string *error) override;

View File

@ -30,7 +30,7 @@ namespace ctl {
class RuleRemoveById : public Action { class RuleRemoveById : public Action {
public: public:
explicit RuleRemoveById(const std::string &action) explicit RuleRemoveById(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind) { } : Action(action) { }
bool init(std::string *error) override; bool init(std::string *error) override;
bool evaluate(RuleWithActions *rule, Transaction *transaction) override; bool evaluate(RuleWithActions *rule, Transaction *transaction) override;

View File

@ -30,7 +30,7 @@ namespace ctl {
class RuleRemoveByTag : public Action { class RuleRemoveByTag : public Action {
public: public:
explicit RuleRemoveByTag(const std::string &action) explicit RuleRemoveByTag(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind), : Action(action),
m_tag("") { } m_tag("") { }
bool init(std::string *error) override; bool init(std::string *error) override;

View File

@ -30,7 +30,7 @@ namespace ctl {
class RuleRemoveTargetById : public Action { class RuleRemoveTargetById : public Action {
public: public:
explicit RuleRemoveTargetById(const std::string &action) explicit RuleRemoveTargetById(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind), : Action(action),
m_id(0), m_id(0),
m_target("") { } m_target("") { }

View File

@ -30,7 +30,7 @@ namespace ctl {
class RuleRemoveTargetByTag : public Action { class RuleRemoveTargetByTag : public Action {
public: public:
explicit RuleRemoveTargetByTag(const std::string &action) explicit RuleRemoveTargetByTag(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind) { } : Action(action) { }
bool init(std::string *error) override; bool init(std::string *error) override;
bool evaluate(RuleWithActions *rule, Transaction *transaction) override; bool evaluate(RuleWithActions *rule, Transaction *transaction) override;

View File

@ -33,8 +33,8 @@ namespace data {
class Status : public Action { class Status : public Action {
public: public:
explicit Status(const std::string &action) : Action(action, 2), explicit Status(const std::string &action)
m_status(0) { } : Action(action), m_status(0) { }
bool init(std::string *error) override; bool init(std::string *error) override;
bool evaluate(RuleWithActions *rule, Transaction *transaction, bool evaluate(RuleWithActions *rule, Transaction *transaction,

View File

@ -54,7 +54,7 @@ enum AllowType : int {
class Allow : public Action { class Allow : public Action {
public: public:
explicit Allow(const std::string &action) explicit Allow(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind), : Action(action),
m_allowType(NoneAllowType) { } m_allowType(NoneAllowType) { }

View File

@ -37,12 +37,12 @@ namespace disruptive {
class Redirect : public Action { class Redirect : public Action {
public: public:
explicit Redirect(const std::string &action) explicit Redirect(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind), : Action(action),
m_status(0), m_status(0),
m_string(nullptr) { } m_string(nullptr) { }
explicit Redirect(std::unique_ptr<RunTimeString> z) explicit Redirect(std::unique_ptr<RunTimeString> z)
: Action("redirert", RunTimeOnlyIfMatchKind), : Action("redirert"),
m_status(0), m_status(0),
m_string(std::move(z)) { } m_string(std::move(z)) { }

View File

@ -36,7 +36,7 @@ class ExpireVar : public Action {
explicit ExpireVar(const std::string &action) : Action(action) { } explicit ExpireVar(const std::string &action) : Action(action) { }
explicit ExpireVar(std::unique_ptr<RunTimeString> z) explicit ExpireVar(std::unique_ptr<RunTimeString> z)
: Action("expirevar", RunTimeOnlyIfMatchKind), : Action("expirevar"),
m_string(std::move(z)) { } m_string(std::move(z)) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction) override; bool evaluate(RuleWithActions *rule, Transaction *transaction) override;

View File

@ -35,7 +35,7 @@ class InitCol : public Action {
explicit InitCol(const std::string &action) : Action(action) { } explicit InitCol(const std::string &action) : Action(action) { }
InitCol(const std::string &action, std::unique_ptr<RunTimeString> z) InitCol(const std::string &action, std::unique_ptr<RunTimeString> z)
: Action(action, RunTimeOnlyIfMatchKind), : Action(action),
m_string(std::move(z)) { } m_string(std::move(z)) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction) override; bool evaluate(RuleWithActions *rule, Transaction *transaction) override;

View File

@ -31,7 +31,7 @@ namespace actions {
class Log : public Action { class Log : public Action {
public: public:
explicit Log(const std::string &action) explicit Log(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind) { } : Action(action) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction, bool evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) override; std::shared_ptr<RuleMessage> rm) override;

View File

@ -33,10 +33,10 @@ namespace actions {
class LogData : public Action { class LogData : public Action {
public: public:
explicit LogData(const std::string &action) explicit LogData(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind) { } : Action(action) { }
explicit LogData(std::unique_ptr<RunTimeString> z) explicit LogData(std::unique_ptr<RunTimeString> z)
: Action("logdata", RunTimeOnlyIfMatchKind), : Action("logdata"),
m_string(std::move(z)) { } m_string(std::move(z)) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction, bool evaluate(RuleWithActions *rule, Transaction *transaction,

View File

@ -15,16 +15,10 @@
#include "src/actions/maturity.h" #include "src/actions/maturity.h"
#include <iostream> #include "modsecurity/rule_with_actions.h"
#include <string>
#include "modsecurity/actions/action.h"
#include "modsecurity/transaction.h"
#include "modsecurity/rule.h"
namespace modsecurity { namespace modsecurity::actions {
namespace actions {
bool Maturity::init(std::string *error) { bool Maturity::init(std::string *error) {
@ -45,5 +39,4 @@ bool Maturity::evaluate(RuleWithActions *rule, Transaction *transaction) {
} }
} // namespace actions } // namespace modsecurity::actions
} // namespace modsecurity

View File

@ -30,7 +30,7 @@ namespace actions {
class Maturity : public Action { class Maturity : public Action {
public: public:
explicit Maturity(const std::string &action) explicit Maturity(const std::string &action)
: Action(action, ConfigurationKind), : Action(action, Kind::ConfigurationKind),
m_maturity(0) { } m_maturity(0) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction) override; bool evaluate(RuleWithActions *rule, Transaction *transaction) override;

View File

@ -34,10 +34,10 @@ namespace actions {
class Msg : public Action { class Msg : public Action {
public: public:
explicit Msg(const std::string &action) explicit Msg(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind) { } : Action(action) { }
explicit Msg(std::unique_ptr<RunTimeString> z) explicit Msg(std::unique_ptr<RunTimeString> z)
: Action("msg", RunTimeOnlyIfMatchKind), : Action("msg"),
m_string(std::move(z)) { } m_string(std::move(z)) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction, bool evaluate(RuleWithActions *rule, Transaction *transaction,

View File

@ -33,7 +33,7 @@ namespace actions {
class MultiMatch : public Action { class MultiMatch : public Action {
public: public:
explicit MultiMatch(const std::string &action) explicit MultiMatch(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind) { } : Action(action) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction) override; bool evaluate(RuleWithActions *rule, Transaction *transaction) override;
}; };

View File

@ -33,7 +33,7 @@ namespace actions {
class NoAuditLog : public Action { class NoAuditLog : public Action {
public: public:
explicit NoAuditLog(const std::string &action) explicit NoAuditLog(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind) { } : Action(action) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction, bool evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) override; std::shared_ptr<RuleMessage> rm) override;

View File

@ -31,7 +31,7 @@ namespace actions {
class NoLog : public Action { class NoLog : public Action {
public: public:
explicit NoLog(const std::string &action) explicit NoLog(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind) { } : Action(action) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction, bool evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> rm) override; std::shared_ptr<RuleMessage> rm) override;

View File

@ -15,20 +15,15 @@
#include "src/actions/phase.h" #include "src/actions/phase.h"
#include <iostream> #include "modsecurity/rule_with_actions.h"
#include <string>
#include "modsecurity/transaction.h"
#include "modsecurity/rule.h"
#include "modsecurity/modsecurity.h"
#include "src/utils/string.h" #include "src/utils/string.h"
namespace modsecurity { namespace modsecurity::actions {
namespace actions {
bool Phase::init(std::string *error) { 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; m_phase = -1;
try { try {
@ -77,5 +72,5 @@ bool Phase::evaluate(RuleWithActions *rule, Transaction *transaction) {
return true; return true;
} }
} // namespace actions
} // namespace modsecurity } // namespace modsecurity::actions

View File

@ -32,7 +32,7 @@ namespace actions {
class Phase : public Action { class Phase : public Action {
public: public:
explicit Phase(const std::string &action) : Action(action, ConfigurationKind), explicit Phase(const std::string &action) : Action(action, Kind::ConfigurationKind),
m_phase(0), m_phase(0),
m_secRulesPhase(0) { } m_secRulesPhase(0) { }

View File

@ -15,16 +15,10 @@
#include "src/actions/rev.h" #include "src/actions/rev.h"
#include <iostream> #include "modsecurity/rule_with_actions.h"
#include <string>
#include "modsecurity/actions/action.h"
#include "modsecurity/transaction.h"
#include "modsecurity/rule.h"
namespace modsecurity { namespace modsecurity::actions {
namespace actions {
bool Rev::init(std::string *error) { bool Rev::init(std::string *error) {
@ -39,5 +33,4 @@ bool Rev::evaluate(RuleWithActions *rule, Transaction *transaction) {
} }
} // namespace actions } // namespace modsecurity::actions
} // namespace modsecurity

View File

@ -29,7 +29,7 @@ namespace actions {
class Rev : public Action { class Rev : public Action {
public: 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 evaluate(RuleWithActions *rule, Transaction *transaction) override;
bool init(std::string *error) override; bool init(std::string *error) override;

View File

@ -15,14 +15,10 @@
#include "src/actions/rule_id.h" #include "src/actions/rule_id.h"
#include <iostream> #include "modsecurity/rule_with_actions.h"
#include <string>
#include "modsecurity/transaction.h"
#include "modsecurity/rule.h"
namespace modsecurity { namespace modsecurity::actions {
namespace actions {
bool RuleId::init(std::string *error) { bool RuleId::init(std::string *error) {
@ -54,5 +50,4 @@ bool RuleId::evaluate(RuleWithActions *rule, Transaction *transaction) {
} }
} // namespace actions } // namespace modsecurity::actions
} // namespace modsecurity

View File

@ -33,7 +33,7 @@ namespace actions {
class RuleId : public Action { class RuleId : public Action {
public: public:
explicit RuleId(const std::string &action) explicit RuleId(const std::string &action)
: Action(action, ConfigurationKind), : Action(action, Kind::ConfigurationKind),
m_ruleId(0) { } m_ruleId(0) { }
bool init(std::string *error) override; bool init(std::string *error) override;

View File

@ -36,7 +36,7 @@ class SetENV : public Action {
: Action(_action) { } : Action(_action) { }
explicit SetENV(std::unique_ptr<RunTimeString> z) explicit SetENV(std::unique_ptr<RunTimeString> z)
: Action("setenv", RunTimeOnlyIfMatchKind), : Action("setenv"),
m_string(std::move(z)) { } m_string(std::move(z)) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction) override; bool evaluate(RuleWithActions *rule, Transaction *transaction) override;

View File

@ -36,7 +36,7 @@ class SetRSC : public Action {
: Action(_action) { } : Action(_action) { }
explicit SetRSC(std::unique_ptr<RunTimeString> z) explicit SetRSC(std::unique_ptr<RunTimeString> z)
: Action("setsrc", RunTimeOnlyIfMatchKind), : Action("setsrc"),
m_string(std::move(z)) { } m_string(std::move(z)) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction) override; bool evaluate(RuleWithActions *rule, Transaction *transaction) override;

View File

@ -36,7 +36,7 @@ class SetSID : public Action {
: Action(_action) { } : Action(_action) { }
explicit SetSID(std::unique_ptr<RunTimeString> z) explicit SetSID(std::unique_ptr<RunTimeString> z)
: Action("setsid", RunTimeOnlyIfMatchKind), : Action("setsid"),
m_string(std::move(z)) { } m_string(std::move(z)) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction) override; bool evaluate(RuleWithActions *rule, Transaction *transaction) override;

View File

@ -36,7 +36,7 @@ class SetUID : public Action {
: Action(_action) { } : Action(_action) { }
explicit SetUID(std::unique_ptr<RunTimeString> z) explicit SetUID(std::unique_ptr<RunTimeString> z)
: Action("setuid", RunTimeOnlyIfMatchKind), : Action("setuid"),
m_string(std::move(z)) { } m_string(std::move(z)) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction) override; bool evaluate(RuleWithActions *rule, Transaction *transaction) override;

View File

@ -30,7 +30,7 @@ namespace actions {
class Skip : public Action { class Skip : public Action {
public: public:
explicit Skip(const std::string &action) explicit Skip(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind), : Action(action),
m_skip_next(0) { } m_skip_next(0) { }
bool init(std::string *error) override; bool init(std::string *error) override;

View File

@ -31,7 +31,7 @@ namespace actions {
class SkipAfter : public Action { class SkipAfter : public Action {
public: public:
explicit SkipAfter(const std::string &action) explicit SkipAfter(const std::string &action)
: Action(action, RunTimeOnlyIfMatchKind), : Action(action),
m_skipName(std::make_shared<std::string>(m_parser_payload)) { } m_skipName(std::make_shared<std::string>(m_parser_payload)) { }
bool evaluate(RuleWithActions *rule, Transaction *transaction) override; bool evaluate(RuleWithActions *rule, Transaction *transaction) override;

View File

@ -33,7 +33,7 @@ namespace actions {
class Tag : public Action { class Tag : public Action {
public: public:
explicit Tag(std::unique_ptr<RunTimeString> z) explicit Tag(std::unique_ptr<RunTimeString> z)
: Action("tag", RunTimeOnlyIfMatchKind), : Action("tag"),
m_string(std::move(z)) { } m_string(std::move(z)) { }
std::string getName(Transaction *transaction); std::string getName(Transaction *transaction);

View File

@ -13,33 +13,19 @@
* *
*/ */
#include "src/actions/transformations/base64_decode.h" #include "base64_decode.h"
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include "modsecurity/transaction.h"
#include "src/actions/transformations/transformation.h"
#include "src/utils/base64.h" #include "src/utils/base64.h"
namespace modsecurity { namespace modsecurity::actions::transformations {
namespace actions {
namespace transformations {
std::string Base64Decode::evaluate(const std::string &value, bool Base64Decode::transform(std::string &value, const Transaction *trans) const {
Transaction *transaction) { if (value.empty()) return false;
std::string ret = Utils::Base64::decode(value); value = Utils::Base64::decode(value);
return true;
return ret;
} }
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity

View File

@ -13,33 +13,20 @@
* *
*/ */
#include <string>
#include "modsecurity/actions/action.h"
#include "src/actions/transformations/transformation.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_H_ #ifndef SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_H_
#define SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_H_
#ifdef __cplusplus #include "transformation.h"
namespace modsecurity {
class Transaction;
namespace actions { namespace modsecurity::actions::transformations {
namespace transformations {
class Base64Decode : public Transformation { class Base64Decode : public Transformation {
public: public:
explicit Base64Decode(const std::string &action) : Transformation(action) { } using Transformation::Transformation;
std::string evaluate(const std::string &exp, bool transform(std::string &value, const Transaction *trans) const override;
Transaction *transaction) override;
}; };
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity
#endif
#endif // SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_H_ #endif // SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_H_

View File

@ -13,33 +13,19 @@
* *
*/ */
#include "src/actions/transformations/base64_decode_ext.h" #include "base64_decode_ext.h"
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include "modsecurity/transaction.h"
#include "src/actions/transformations/transformation.h"
#include "src/utils/base64.h" #include "src/utils/base64.h"
namespace modsecurity { namespace modsecurity::actions::transformations {
namespace actions {
namespace transformations {
std::string Base64DecodeExt::evaluate(const std::string &value, bool Base64DecodeExt::transform(std::string &value, const Transaction *trans) const {
Transaction *transaction) { if (value.empty()) return false;
std::string ret = Utils::Base64::decode_forgiven(value); value = Utils::Base64::decode_forgiven(value);
return true;
return ret;
} }
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity

View File

@ -13,33 +13,20 @@
* *
*/ */
#include <string>
#include "modsecurity/actions/action.h"
#include "src/actions/transformations/transformation.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_EXT_H_ #ifndef SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_EXT_H_
#define SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_EXT_H_ #define SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_EXT_H_
#ifdef __cplusplus #include "transformation.h"
namespace modsecurity {
class Transaction;
namespace actions { namespace modsecurity::actions::transformations {
namespace transformations {
class Base64DecodeExt : public Transformation { class Base64DecodeExt : public Transformation {
public: public:
explicit Base64DecodeExt(const std::string &action) : Transformation(action) { } using Transformation::Transformation;
std::string evaluate(const std::string &exp, bool transform(std::string &value, const Transaction *trans) const override;
Transaction *transaction) override;
}; };
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity
#endif
#endif // SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_EXT_H_ #endif // SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_EXT_H_

View File

@ -13,33 +13,19 @@
* *
*/ */
#include "src/actions/transformations/base64_encode.h" #include "base64_encode.h"
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include "modsecurity/transaction.h"
#include "src/actions/transformations/transformation.h"
#include "src/utils/base64.h" #include "src/utils/base64.h"
namespace modsecurity { namespace modsecurity::actions::transformations {
namespace actions {
namespace transformations {
std::string Base64Encode::evaluate(const std::string &value, bool Base64Encode::transform(std::string &value, const Transaction *trans) const {
Transaction *transaction) { if (value.empty()) return false;
std::string ret = Utils::Base64::encode(value); value = Utils::Base64::encode(value);
return true;
return ret;
} }
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity

View File

@ -13,33 +13,20 @@
* *
*/ */
#include <string>
#include "modsecurity/actions/action.h"
#include "src/actions/transformations/transformation.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_BASE64_ENCODE_H_ #ifndef SRC_ACTIONS_TRANSFORMATIONS_BASE64_ENCODE_H_
#define SRC_ACTIONS_TRANSFORMATIONS_BASE64_ENCODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_BASE64_ENCODE_H_
#ifdef __cplusplus #include "transformation.h"
namespace modsecurity {
class Transaction;
namespace actions { namespace modsecurity::actions::transformations {
namespace transformations {
class Base64Encode : public Transformation { class Base64Encode : public Transformation {
public: public:
explicit Base64Encode(const std::string &action) : Transformation(action) { } using Transformation::Transformation;
std::string evaluate(const std::string &exp, bool transform(std::string &value, const Transaction *trans) const override;
Transaction *transaction) override;
}; };
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity
#endif
#endif // SRC_ACTIONS_TRANSFORMATIONS_BASE64_ENCODE_H_ #endif // SRC_ACTIONS_TRANSFORMATIONS_BASE64_ENCODE_H_

View File

@ -13,30 +13,17 @@
* *
*/ */
#include "src/actions/transformations/cmd_line.h" #include "cmd_line.h"
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include "modsecurity/transaction.h"
#include "src/actions/transformations/transformation.h"
namespace modsecurity { namespace modsecurity::actions::transformations {
namespace actions {
namespace transformations {
std::string CmdLine::evaluate(const std::string &value, bool CmdLine::transform(std::string &value, const Transaction *trans) const {
Transaction *transaction) { char *d = value.data();
std::string ret; bool space = false;
int space = 0;
for (auto& a : value) { for (const auto& a : value) {
switch (a) { switch (a) {
/* remove some characters */ /* remove some characters */
case '"': case '"':
@ -52,9 +39,9 @@ std::string CmdLine::evaluate(const std::string &value,
case '\t': case '\t':
case '\r': case '\r':
case '\n': case '\n':
if (space == 0) { if (space == false) {
ret.append(" "); *d++ = ' ';
space++; space = true;
} }
break; break;
@ -62,26 +49,27 @@ std::string CmdLine::evaluate(const std::string &value,
case '/': case '/':
case '(': case '(':
if (space) { if (space) {
ret.pop_back(); d--;
} }
space = 0; space = false;
ret.append(&a, 1); *d++ = a;
break; break;
/* copy normal characters */ /* copy normal characters */
default : default :
char b = std::tolower(a); char b = std::tolower(a);
ret.append(&b, 1); *d++ = b;
space = 0; space = false;
break; 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 modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity

View File

@ -13,35 +13,21 @@
* *
*/ */
#include <string>
#include "modsecurity/actions/action.h"
#include "src/actions/transformations/transformation.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_CMD_LINE_H_ #ifndef SRC_ACTIONS_TRANSFORMATIONS_CMD_LINE_H_
#define SRC_ACTIONS_TRANSFORMATIONS_CMD_LINE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_CMD_LINE_H_
#ifdef __cplusplus #include "transformation.h"
namespace modsecurity {
class Transaction;
namespace actions { namespace modsecurity::actions::transformations {
namespace transformations {
class CmdLine : public Transformation { class CmdLine : public Transformation {
public: public:
explicit CmdLine(const std::string &action) using Transformation::Transformation;
: Transformation(action) { }
std::string evaluate(const std::string &exp, bool transform(std::string &value, const Transaction *trans) const override;
Transaction *transaction) override;
}; };
} // namespace transformations } // modsecurity::namespace actions::transformations
} // namespace actions
} // namespace modsecurity
#endif
#endif // SRC_ACTIONS_TRANSFORMATIONS_CMD_LINE_H_ #endif // SRC_ACTIONS_TRANSFORMATIONS_CMD_LINE_H_

View File

@ -13,54 +13,36 @@
* *
*/ */
#include "src/actions/transformations/compress_whitespace.h" #include "compress_whitespace.h"
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include "modsecurity/transaction.h"
#include "src/actions/transformations/transformation.h"
namespace modsecurity { namespace modsecurity::actions::transformations {
namespace actions {
namespace transformations {
CompressWhitespace::CompressWhitespace(const std::string &action)
: Transformation(action) {
this->action_kind = 1;
}
std::string CompressWhitespace::evaluate(const std::string &value, bool CompressWhitespace::transform(std::string &value, const Transaction *trans) const {
Transaction *transaction) { bool inWhiteSpace = false;
std::string a; auto d = value.data();
int inWhiteSpace = 0;
int i = 0;
while (i < value.size()) { for(const auto c : value) {
if (isspace(value[i])) { if (isspace(c)) {
if (inWhiteSpace) { if (inWhiteSpace) {
i++;
continue; continue;
} else { } else {
inWhiteSpace = 1; inWhiteSpace = true;
a.append(" ", 1); *d++ = ' ';
} }
} else { } else {
inWhiteSpace = 0; inWhiteSpace = false;
a.append(&value.at(i), 1); *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::actions::transformations
} // namespace modsecurity

View File

@ -13,34 +13,20 @@
* *
*/ */
#include <string>
#include "modsecurity/actions/action.h"
#include "src/actions/transformations/transformation.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_COMPRESS_WHITESPACE_H_ #ifndef SRC_ACTIONS_TRANSFORMATIONS_COMPRESS_WHITESPACE_H_
#define SRC_ACTIONS_TRANSFORMATIONS_COMPRESS_WHITESPACE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_COMPRESS_WHITESPACE_H_
#ifdef __cplusplus #include "transformation.h"
namespace modsecurity {
class Transaction;
namespace actions { namespace modsecurity::actions::transformations {
namespace transformations {
class CompressWhitespace : public Transformation { class CompressWhitespace : public Transformation {
public: public:
using Transformation::Transformation;
explicit CompressWhitespace(const std::string &action) ; bool transform(std::string &value, const Transaction *trans) const override;
std::string evaluate(const std::string &exp,
Transaction *transaction) override;
}; };
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity
#endif
#endif // SRC_ACTIONS_TRANSFORMATIONS_COMPRESS_WHITESPACE_H_ #endif // SRC_ACTIONS_TRANSFORMATIONS_COMPRESS_WHITESPACE_H_

View File

@ -13,42 +13,13 @@
* *
*/ */
#include "src/actions/transformations/css_decode.h" #include "css_decode.h"
#include <string.h>
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include "modsecurity/transaction.h"
#include "src/actions/transformations/transformation.h"
#include "src/utils/string.h" #include "src/utils/string.h"
using namespace modsecurity::utils::string;
namespace modsecurity { namespace modsecurity::actions::transformations {
namespace actions {
namespace transformations {
std::string CssDecode::evaluate(const std::string &value,
Transaction *transaction) {
char *tmp = reinterpret_cast<char *>(
malloc(sizeof(char) * value.size() + 1));
memcpy(tmp, value.c_str(), value.size() + 1);
tmp[value.size()] = '\0';
CssDecode::css_decode_inplace(reinterpret_cast<unsigned char *>(tmp),
value.size());
std::string ret(tmp, 0, value.size());
free(tmp);
return ret;
}
/** /**
@ -58,15 +29,13 @@ std::string CssDecode::evaluate(const std::string &value,
* http://www.w3.org/TR/REC-CSS2/syndata.html#q4 * http://www.w3.org/TR/REC-CSS2/syndata.html#q4
* http://www.unicode.org/roadmaps/ * http://www.unicode.org/roadmaps/
*/ */
int CssDecode::css_decode_inplace(unsigned char *input, int64_t input_len) { static inline bool css_decode_inplace(std::string &val) {
unsigned char *d = (unsigned char *)input; const auto input_len = val.length();
int64_t i, j, count; auto input = reinterpret_cast<unsigned char *>(val.data());
auto d = input;
bool changed = false;
if (input == NULL) { std::string::size_type i = 0;
return -1;
}
i = count = 0;
while (i < input_len) { while (i < input_len) {
/* Is the character a backslash? */ /* Is the character a backslash? */
if (input[i] == '\\') { 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. */ i++; /* We are not going to need the backslash. */
/* Check for 1-6 hex characters following the backslash */ /* Check for 1-6 hex characters following the backslash */
j = 0; std::string::size_type j = 0;
while ((j < 6) while ((j < 6)
&& (i + j < input_len) && (i + j < input_len)
&& (VALID_HEX(input[i + j]))) { && (VALID_HEX(input[i + j]))) {
@ -157,40 +126,45 @@ int CssDecode::css_decode_inplace(unsigned char *input, int64_t input_len) {
} }
/* Move over. */ /* Move over. */
count++;
i += j; i += j;
changed = true;
} else if (input[i] == '\n') { } else if (input[i] == '\n') {
/* No hexadecimal digits after backslash */ /* No hexadecimal digits after backslash */
/* A newline character following backslash is ignored. */ /* A newline character following backslash is ignored. */
i++; i++;
changed = true;
} else { } else {
/* The character after backslash is not a hexadecimal digit, /* The character after backslash is not a hexadecimal digit,
* nor a newline. */ * nor a newline. */
/* Use one character after backslash as is. */ /* Use one character after backslash as is. */
*d++ = input[i++]; *d++ = input[i++];
count++;
} }
} else { } else {
/* No characters after backslash. */ /* No characters after backslash. */
/* Do not include backslash in output /* Do not include backslash in output
*(continuation to nothing) */ *(continuation to nothing) */
i++; i++;
changed = true;
} }
} else { } else {
/* Character is not a backslash. */ /* Character is not a backslash. */
/* Copy one normal character to output. */ /* Copy one normal character to output. */
*d++ = input[i++]; *d++ = input[i++];
count++;
} }
} }
/* Terminate output string. */ /* Terminate output string. */
*d = '\0'; *d = '\0';
return count; val.resize(d - input);
return changed;
} }
} // namespace transformations bool CssDecode::transform(std::string &value, const Transaction *trans) const {
} // namespace actions return css_decode_inplace(value);
} // namespace modsecurity }
} // namespace modsecurity::actions::transformations

View File

@ -13,37 +13,20 @@
* *
*/ */
#include <string>
#include "modsecurity/actions/action.h"
#include "src/actions/transformations/transformation.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_CSS_DECODE_H_ #ifndef SRC_ACTIONS_TRANSFORMATIONS_CSS_DECODE_H_
#define SRC_ACTIONS_TRANSFORMATIONS_CSS_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_CSS_DECODE_H_
#ifdef __cplusplus #include "transformation.h"
namespace modsecurity {
class Transaction;
namespace actions {
namespace transformations {
namespace modsecurity::actions::transformations {
class CssDecode : public Transformation { class CssDecode : public Transformation {
public: public:
explicit CssDecode(const std::string &action) using Transformation::Transformation;
: Transformation(action) { }
std::string evaluate(const std::string &exp,
Transaction *transaction) override;
static int css_decode_inplace(unsigned char *input, int64_t input_len); bool transform(std::string &value, const Transaction *trans) const override;
}; };
} // namespace modsecurity::actions::transformations
} // namespace transformations
} // namespace actions
} // namespace modsecurity
#endif
#endif // SRC_ACTIONS_TRANSFORMATIONS_CSS_DECODE_H_ #endif // SRC_ACTIONS_TRANSFORMATIONS_CSS_DECODE_H_

View File

@ -13,36 +13,22 @@
* *
*/ */
#include "src/actions/transformations/escape_seq_decode.h" #include "escape_seq_decode.h"
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include <cstring>
#include "modsecurity/transaction.h"
#include "src/actions/transformations/transformation.h"
#include "src/utils/string.h" #include "src/utils/string.h"
namespace modsecurity { using namespace modsecurity::utils::string;
namespace actions {
namespace transformations {
EscapeSeqDecode::EscapeSeqDecode(const std::string &action) namespace modsecurity::actions::transformations {
: Transformation(action) {
this->action_kind = 1;
}
int EscapeSeqDecode::ansi_c_sequences_decode_inplace(unsigned char *input, static inline int ansi_c_sequences_decode_inplace(std::string &value) {
int input_len) { auto d = reinterpret_cast<unsigned char *>(value.data());
unsigned char *d = input; const unsigned char* input = d;
int i, count; const auto input_len = value.length();
i = count = 0; bool changed = false;
std::string::size_type i = 0;
while (i < input_len) { while (i < input_len) {
if ((input[i] == '\\') && (i + 1 < input_len)) { if ((input[i] == '\\') && (i + 1 < input_len)) {
int c = -1; int c = -1;
@ -120,43 +106,29 @@ int EscapeSeqDecode::ansi_c_sequences_decode_inplace(unsigned char *input,
if (c == -1) { if (c == -1) {
/* Didn't recognise encoding, copy raw bytes. */ /* Didn't recognise encoding, copy raw bytes. */
*d++ = input[i + 1]; *d++ = input[i + 1];
count++;
i += 2; i += 2;
} else { } else {
/* Converted the encoding. */ /* Converted the encoding. */
*d++ = c; *d++ = c;
count++;
} }
changed = true;
} else { } else {
/* Input character not a backslash, copy it. */ /* Input character not a backslash, copy it. */
*d++ = input[i++]; *d++ = input[i++];
count++;
} }
} }
*d = '\0'; *d = '\0';
return count; value.resize(d - input);
return changed;
} }
std::string EscapeSeqDecode::evaluate(const std::string &value, bool EscapeSeqDecode::transform(std::string &value, const Transaction *trans) const {
Transaction *transaction) { return ansi_c_sequences_decode_inplace(value);
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<char *>(tmp), size);
free(tmp);
return ret;
} }
} // namespace transformations
} // namespace actions } // namespace modsecurity::actions::transformations
} // namespace modsecurity

View File

@ -13,35 +13,20 @@
* *
*/ */
#include <string>
#include "modsecurity/actions/action.h"
#include "src/actions/transformations/transformation.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_ESCAPE_SEQ_DECODE_H_ #ifndef SRC_ACTIONS_TRANSFORMATIONS_ESCAPE_SEQ_DECODE_H_
#define SRC_ACTIONS_TRANSFORMATIONS_ESCAPE_SEQ_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_ESCAPE_SEQ_DECODE_H_
#ifdef __cplusplus #include "transformation.h"
namespace modsecurity {
class Transaction;
namespace actions { namespace modsecurity::actions::transformations {
namespace transformations {
class EscapeSeqDecode : public Transformation { class EscapeSeqDecode : public Transformation {
public: public:
using Transformation::Transformation;
explicit EscapeSeqDecode(const std::string &action) ; bool transform(std::string &value, const Transaction *trans) const override;
std::string evaluate(const std::string &exp,
Transaction *transaction) override;
int ansi_c_sequences_decode_inplace(unsigned char *input, int input_len);
}; };
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity
#endif
#endif // SRC_ACTIONS_TRANSFORMATIONS_ESCAPE_SEQ_DECODE_H_ #endif // SRC_ACTIONS_TRANSFORMATIONS_ESCAPE_SEQ_DECODE_H_

View File

@ -13,67 +13,35 @@
* *
*/ */
#include "src/actions/transformations/hex_decode.h" #include "hex_decode.h"
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include <cstring>
#include "modsecurity/transaction.h"
#include "src/actions/transformations/transformation.h"
#include "src/utils/string.h" #include "src/utils/string.h"
namespace modsecurity {
namespace actions { namespace modsecurity::actions::transformations {
namespace transformations {
std::string HexDecode::evaluate(const std::string &value, static inline int inplace(std::string &value) {
Transaction *transaction) { if (value.empty()) return false;
std::string ret;
unsigned char *input;
int size = 0;
input = reinterpret_cast<unsigned char *> const auto len = value.length();
(malloc(sizeof(char) * value.length()+1)); auto d = reinterpret_cast<unsigned char *>(value.data());
const auto data = d;
if (input == NULL) { for (int i = 0; i <= len - 2; i += 2) {
return "";
}
memcpy(input, value.c_str(), value.length()+1);
size = inplace(input, value.length());
ret.assign(reinterpret_cast<char *>(input), size);
free(input);
return ret;
}
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]); *d++ = utils::string::x2c(&data[i]);
count++;
} }
*d = '\0'; *d = '\0';
return count; value.resize(d - data);
return true;
} }
} // namespace transformations bool HexDecode::transform(std::string &value, const Transaction *trans) const {
} // namespace actions return inplace(value);
} // namespace modsecurity }
} // namespace modsecurity::actions::transformations

View File

@ -13,35 +13,20 @@
* *
*/ */
#include <string>
#include "modsecurity/actions/action.h"
#include "src/actions/transformations/transformation.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_HEX_DECODE_H_ #ifndef SRC_ACTIONS_TRANSFORMATIONS_HEX_DECODE_H_
#define SRC_ACTIONS_TRANSFORMATIONS_HEX_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_HEX_DECODE_H_
#ifdef __cplusplus #include "transformation.h"
namespace modsecurity {
class Transaction;
namespace actions { namespace modsecurity::actions::transformations {
namespace transformations {
class HexDecode : public Transformation { class HexDecode : public Transformation {
public: public:
explicit HexDecode(const std::string &action) : Transformation(action) { } using Transformation::Transformation;
std::string evaluate(const std::string &exp, bool transform(std::string &value, const Transaction *trans) const override;
Transaction *transaction) override;
static int inplace(unsigned char *data, int len);
}; };
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity
#endif
#endif // SRC_ACTIONS_TRANSFORMATIONS_HEX_DECODE_H_ #endif // SRC_ACTIONS_TRANSFORMATIONS_HEX_DECODE_H_

View File

@ -13,41 +13,25 @@
* *
*/ */
#include "src/actions/transformations/hex_encode.h" #include "hex_encode.h"
#include <iostream> #include "modsecurity/rule_with_actions.h"
#include <string>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include <iterator>
#include "modsecurity/transaction.h"
#include "src/actions/transformations/transformation.h"
namespace modsecurity { namespace modsecurity::actions::transformations {
namespace actions {
namespace transformations {
HexEncode::HexEncode(const std::string &action)
: Transformation(action) {
this->action_kind = 1;
}
std::string HexEncode::evaluate(const std::string &value, bool HexEncode::transform(std::string &value, const Transaction *trans) const {
Transaction *transaction) { if (value.empty()) return false;
std::stringstream result; std::stringstream result;
for (std::size_t i=0; i < value.length(); i++) { for (const auto c : value) {
unsigned int ii = (unsigned char)(value[i]); unsigned int ii = (unsigned char)c;
result << std::setw(2) << std::setfill('0') << std::hex << ii; result << std::setw(2) << std::setfill('0') << std::hex << ii;
} }
return result.str(); value = result.str();
return true;
} }
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity

View File

@ -13,34 +13,20 @@
* *
*/ */
#include <string>
#include "modsecurity/actions/action.h"
#include "src/actions/transformations/transformation.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_HEX_ENCODE_H_ #ifndef SRC_ACTIONS_TRANSFORMATIONS_HEX_ENCODE_H_
#define SRC_ACTIONS_TRANSFORMATIONS_HEX_ENCODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_HEX_ENCODE_H_
#ifdef __cplusplus #include "transformation.h"
namespace modsecurity {
class Transaction;
namespace actions { namespace modsecurity::actions::transformations {
namespace transformations {
class HexEncode : public Transformation { class HexEncode : public Transformation {
public: public:
using Transformation::Transformation;
explicit HexEncode(const std::string &action); bool transform(std::string &value, const Transaction *trans) const override;
std::string evaluate(const std::string &exp,
Transaction *transaction) override;
}; };
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity
#endif
#endif // SRC_ACTIONS_TRANSFORMATIONS_HEX_ENCODE_H_ #endif // SRC_ACTIONS_TRANSFORMATIONS_HEX_ENCODE_H_

View File

@ -13,70 +13,36 @@
* *
*/ */
#include "src/actions/transformations/html_entity_decode.h" #include "html_entity_decode.h"
#include <string.h> #include <cstring>
#include <iostream> #include "src/utils/string.h"
#include <string>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include "modsecurity/transaction.h"
#include "src/actions/transformations/transformation.h"
#ifdef WIN32 #ifdef WIN32
#include "src/compat/msvc.h" #include "src/compat/msvc.h"
#endif #endif
using namespace modsecurity::utils::string;
namespace modsecurity { namespace modsecurity::actions::transformations {
namespace actions {
namespace transformations {
std::string HtmlEntityDecode::evaluate(const std::string &value, static inline bool inplace(std::string &value) {
Transaction *transaction) { const auto input_len = value.length();
std::string ret; auto d = reinterpret_cast<unsigned char*>(value.data());
unsigned char *input; const unsigned char *input = d;
const unsigned char *end = input + input_len;
input = reinterpret_cast<unsigned char *> std::string::size_type i = 0;
(malloc(sizeof(char) * value.length()+1)); while (i < input_len) {
std::string::size_type copy = 1;
if (input == NULL) {
return "";
}
memcpy(input, value.c_str(), value.length()+1);
size_t i = inplace(input, value.length());
ret.assign(reinterpret_cast<char *>(input), i);
free(input);
return ret;
}
int HtmlEntityDecode::inplace(unsigned char *input, uint64_t input_len) {
unsigned char *d = input;
int i, count;
if ((input == NULL) || (input_len == 0)) {
return 0;
}
i = count = 0;
while ((i < input_len) && (count < input_len)) {
int z, copy = 1;
/* Require an ampersand and at least one character to /* Require an ampersand and at least one character to
* start looking into the entity. * start looking into the entity.
*/ */
if ((input[i] == '&') && (i + 1 < input_len)) { if ((input[i] == '&') && (i + 1 < input_len)) {
int k, j = i + 1; auto j = i + 1;
if (input[j] == '#') { if (input[j] == '#') {
/* Numerical entity. */ /* 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. */ j++; /* j is the position of the first digit now. */
k = j; constexpr int MAX_HEX_DIGITS = 2; // supports only bytes (max value 0xff)
while ((j < input_len) && (isxdigit(input[j]))) { auto k = j;
while ((j - k < MAX_HEX_DIGITS) && (j < input_len) && (isxdigit(input[j]))) {
j++; j++;
} }
if (j > k) { /* Do we have at least one digit? */ if (j > k) { /* Do we have at least one digit? */
/* Decode the entity. */ /* Decode the entity. */
char *x; char x[MAX_HEX_DIGITS + 1];
x = reinterpret_cast<char *>(calloc(sizeof(char),
((j - k) + 1)));
memcpy(x, (const char *)&input[k], j - k); memcpy(x, (const char *)&input[k], j - k);
*d++ = (unsigned char)strtol(x, NULL, 16); x[j - k] = '\0';
free(x);
count++; *d++ = (unsigned char)strtol(x, nullptr, 16);
/* Skip over the semicolon if it's there. */ /* Skip over the semicolon if it's there. */
if ((j < input_len) && (input[j] == ';')) { if ((j < input_len) && (input[j] == ';')) {
@ -122,19 +87,18 @@ int HtmlEntityDecode::inplace(unsigned char *input, uint64_t input_len) {
} }
} else { } else {
/* Decimal entity. */ /* Decimal entity. */
k = j; constexpr int MAX_DEC_DIGITS = 3; // supports only bytes (max value 255)
while ((j < input_len) && (isdigit(input[j]))) { auto k = j;
while ((j - k < MAX_DEC_DIGITS) && (j < input_len) && (isdigit(input[j]))) {
j++; j++;
} }
if (j > k) { /* Do we have at least one digit? */ if (j > k) { /* Do we have at least one digit? */
/* Decode the entity. */ /* Decode the entity. */
char *x; char x[MAX_DEC_DIGITS + 1];
x = reinterpret_cast<char *>(calloc(sizeof(char),
((j - k) + 1)));
memcpy(x, (const char *)&input[k], j - k); memcpy(x, (const char *)&input[k], j - k);
*d++ = (unsigned char)strtol(x, NULL, 10); x[j - k] = '\0';
free(x);
count++; *d++ = (unsigned char)strtol(x, nullptr, 10);
/* Skip over the semicolon if it's there. */ /* Skip over the semicolon if it's there. */
if ((j < input_len) && (input[j] == ';')) { if ((j < input_len) && (input[j] == ';')) {
@ -149,38 +113,31 @@ int HtmlEntityDecode::inplace(unsigned char *input, uint64_t input_len) {
} }
} else { } else {
/* Text entity. */ /* Text entity. */
k = j; auto k = j;
while ((j < input_len) && (isalnum(input[j]))) { while ((j < input_len) && (isalnum(input[j]))) {
j++; j++;
} }
if (j > k) { /* Do we have at least one digit? */ if (j > k) { /* Do we have at least one digit? */
char *x; const auto x = reinterpret_cast<const char*>(&input[k]);
x = reinterpret_cast<char *>(calloc(sizeof(char),
((j - k) + 1)));
memcpy(x, (const char *)&input[k], j - k);
/* Decode the entity. */ /* Decode the entity. */
/* ENH What about others? */ /* ENH What about others? */
if (strcasecmp(x, "quot") == 0) { if (strncasecmp(x, "quot", 4) == 0) {
*d++ = '"'; *d++ = '"';
} else if (strcasecmp(x, "amp") == 0) { } else if (strncasecmp(x, "amp", 3) == 0) {
*d++ = '&'; *d++ = '&';
} else if (strcasecmp(x, "lt") == 0) { } else if (strncasecmp(x, "lt", 2) == 0) {
*d++ = '<'; *d++ = '<';
} else if (strcasecmp(x, "gt") == 0) { } else if (strncasecmp(x, "gt", 2) == 0) {
*d++ = '>'; *d++ = '>';
} else if (strcasecmp(x, "nbsp") == 0) { } else if (strncasecmp(x, "nbsp", 4) == 0) {
*d++ = NBSP; *d++ = NBSP;
} else { } else {
/* We do no want to convert this entity, /* We do no want to convert this entity,
* copy the raw data over. */ * copy the raw data over. */
copy = j - k + 1; copy = j - k + 1;
free(x);
goto HTML_ENT_OUT; goto HTML_ENT_OUT;
} }
free(x);
count++;
/* Skip over the semicolon if it's there. */ /* Skip over the semicolon if it's there. */
if ((j < input_len) && (input[j] == ';')) { if ((j < input_len) && (input[j] == ';')) {
@ -196,17 +153,21 @@ int HtmlEntityDecode::inplace(unsigned char *input, uint64_t input_len) {
HTML_ENT_OUT: HTML_ENT_OUT:
for (z = 0; ((z < copy) && (count < input_len)); z++) { for (auto z = 0; z < copy; z++) {
*d++ = input[i++]; *d++ = input[i++];
count++;
} }
} }
*d = '\0'; *d = '\0';
return count; value.resize(d - input);
return d != end;
} }
} // namespace transformations
} // namespace actions bool HtmlEntityDecode::transform(std::string &value, const Transaction *trans) const {
} // namespace modsecurity return inplace(value);
}
} // namespace modsecurity::actions::transformations

View File

@ -13,40 +13,20 @@
* *
*/ */
#include <string>
#include <unordered_map>
#include "modsecurity/actions/action.h"
#include "src/actions/transformations/transformation.h"
#include "src/utils/string.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_HTML_ENTITY_DECODE_H_ #ifndef SRC_ACTIONS_TRANSFORMATIONS_HTML_ENTITY_DECODE_H_
#define SRC_ACTIONS_TRANSFORMATIONS_HTML_ENTITY_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_HTML_ENTITY_DECODE_H_
#ifdef __cplusplus #include "transformation.h"
namespace modsecurity {
class Transaction;
namespace actions {
namespace transformations {
namespace modsecurity::actions::transformations {
class HtmlEntityDecode : public Transformation { class HtmlEntityDecode : public Transformation {
public: public:
explicit HtmlEntityDecode(const std::string &action) using Transformation::Transformation;
: Transformation(action) { }
std::string evaluate(const std::string &exp, bool transform(std::string &value, const Transaction *trans) const override;
Transaction *transaction) override;
static int inplace(unsigned char *input, uint64_t input_len);
}; };
} // namespace modsecurity::actions::transformations
} // namespace transformations
} // namespace actions
} // namespace modsecurity
#endif
#endif // SRC_ACTIONS_TRANSFORMATIONS_HTML_ENTITY_DECODE_H_ #endif // SRC_ACTIONS_TRANSFORMATIONS_HTML_ENTITY_DECODE_H_

View File

@ -13,55 +13,22 @@
* *
*/ */
#include "src/actions/transformations/js_decode.h" #include "js_decode.h"
#include <string.h>
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include "modsecurity/transaction.h"
#include "src/actions/transformations/transformation.h"
#include "src/utils/string.h" #include "src/utils/string.h"
using namespace modsecurity::utils::string;
namespace modsecurity { namespace modsecurity::actions::transformations {
namespace actions {
namespace transformations {
std::string JsDecode::evaluate(const std::string &value, static inline int inplace(std::string &value) {
Transaction *transaction) { auto d = reinterpret_cast<unsigned char*>(value.data());
std::string ret; const unsigned char *input = d;
unsigned char *input; const auto input_len = value.length();
input = reinterpret_cast<unsigned char *> bool changed = false;
(malloc(sizeof(char) * value.length()+1)); std::string::size_type i = 0;
if (input == NULL) {
return "";
}
memcpy(input, value.c_str(), value.length()+1);
size_t i = inplace(input, value.length());
ret.assign(reinterpret_cast<char *>(input), i);
free(input);
return ret;
}
int JsDecode::inplace(unsigned char *input, uint64_t input_len) {
unsigned char *d = (unsigned char *)input;
int64_t i, count;
i = count = 0;
while (i < input_len) { while (i < input_len) {
if (input[i] == '\\') { if (input[i] == '\\') {
/* Character is an escape. */ /* Character is an escape. */
@ -82,14 +49,14 @@ int JsDecode::inplace(unsigned char *input, uint64_t input_len) {
} }
d++; d++;
count++;
i += 6; i += 6;
changed = true;
} else if ((i + 3 < input_len) && (input[i + 1] == 'x') } else if ((i + 3 < input_len) && (input[i + 1] == 'x')
&& VALID_HEX(input[i + 2]) && VALID_HEX(input[i + 3])) { && VALID_HEX(input[i + 2]) && VALID_HEX(input[i + 3])) {
/* \xHH */ /* \xHH */
*d++ = utils::string::x2c(&input[i + 2]); *d++ = utils::string::x2c(&input[i + 2]);
count++;
i += 4; i += 4;
changed = true;
} else if ((i + 1 < input_len) && ISODIGIT(input[i + 1])) { } else if ((i + 1 < input_len) && ISODIGIT(input[i + 1])) {
/* \OOO (only one byte, \000 - \377) */ /* \OOO (only one byte, \000 - \377) */
char buf[4]; char buf[4];
@ -110,7 +77,7 @@ int JsDecode::inplace(unsigned char *input, uint64_t input_len) {
} }
*d++ = (unsigned char)strtol(buf, NULL, 8); *d++ = (unsigned char)strtol(buf, NULL, 8);
i += 1 + j; i += 1 + j;
count++; changed = true;
} }
} else if (i + 1 < input_len) { } else if (i + 1 < input_len) {
/* \C */ /* \C */
@ -144,25 +111,28 @@ int JsDecode::inplace(unsigned char *input, uint64_t input_len) {
*d++ = c; *d++ = c;
i += 2; i += 2;
count++; changed = true;
} else { } else {
/* Not enough bytes */ /* Not enough bytes */
while (i < input_len) { while (i < input_len) {
*d++ = input[i++]; *d++ = input[i++];
count++;
} }
} }
} else { } else {
*d++ = input[i++]; *d++ = input[i++];
count++;
} }
} }
*d = '\0'; *d = '\0';
return count; value.resize(d - input);
return changed;
} }
} // namespace transformations
} // namespace actions bool JsDecode::transform(std::string &value, const Transaction *trans) const {
} // namespace modsecurity return inplace(value);
}
} // namespace modsecurity::actions::transformations

View File

@ -13,35 +13,20 @@
* *
*/ */
#include <string>
#include "modsecurity/actions/action.h"
#include "src/actions/transformations/transformation.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_JS_DECODE_H_ #ifndef SRC_ACTIONS_TRANSFORMATIONS_JS_DECODE_H_
#define SRC_ACTIONS_TRANSFORMATIONS_JS_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_JS_DECODE_H_
#ifdef __cplusplus #include "transformation.h"
namespace modsecurity {
class Transaction;
namespace actions { namespace modsecurity::actions::transformations {
namespace transformations {
class JsDecode : public Transformation { class JsDecode : public Transformation {
public: public:
explicit JsDecode(const std::string &action) using Transformation::Transformation;
: Transformation(action) { }
std::string evaluate(const std::string &exp, bool transform(std::string &value, const Transaction *trans) const override;
Transaction *transaction) override;
static int inplace(unsigned char *input, uint64_t input_len);
}; };
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity
#endif
#endif // SRC_ACTIONS_TRANSFORMATIONS_JS_DECODE_H_ #endif // SRC_ACTIONS_TRANSFORMATIONS_JS_DECODE_H_

View File

@ -13,34 +13,16 @@
* *
*/ */
#include "src/actions/transformations/length.h" #include "length.h"
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include "modsecurity/transaction.h"
#include "src/actions/transformations/transformation.h"
namespace modsecurity { namespace modsecurity::actions::transformations {
namespace actions {
namespace transformations {
Length::Length(const std::string &action)
: Transformation(action) { bool Length::transform(std::string &value, const Transaction *trans) const {
this->action_kind = 1; 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 modsecurity::actions::transformations
}
} // namespace transformations
} // namespace actions
} // namespace modsecurity

View File

@ -13,34 +13,20 @@
* *
*/ */
#include <string>
#include "modsecurity/actions/action.h"
#include "src/actions/transformations/transformation.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_LENGTH_H_ #ifndef SRC_ACTIONS_TRANSFORMATIONS_LENGTH_H_
#define SRC_ACTIONS_TRANSFORMATIONS_LENGTH_H_ #define SRC_ACTIONS_TRANSFORMATIONS_LENGTH_H_
#ifdef __cplusplus #include "transformation.h"
namespace modsecurity {
class Transaction;
namespace actions { namespace modsecurity::actions::transformations {
namespace transformations {
class Length : public Transformation { class Length : public Transformation {
public: public:
using Transformation::Transformation;
explicit Length(const std::string &action); bool transform(std::string &value, const Transaction *trans) const override;
std::string evaluate(const std::string &exp,
Transaction *transaction) override;
}; };
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity
#endif
#endif // SRC_ACTIONS_TRANSFORMATIONS_LENGTH_H_ #endif // SRC_ACTIONS_TRANSFORMATIONS_LENGTH_H_

View File

@ -13,37 +13,19 @@
* *
*/ */
#include "src/actions/transformations/lower_case.h"
#include <algorithm> #include "lower_case.h"
#include <string>
#include <locale>
#include "modsecurity/transaction.h" #include <cctype>
#include "src/actions/transformations/transformation.h"
#include "modsecurity/actions/action.h"
namespace modsecurity {
namespace actions {
namespace transformations {
LowerCase::LowerCase(const std::string &a) namespace modsecurity::actions::transformations {
: Transformation(a) {
bool LowerCase::transform(std::string &value, const Transaction *trans) const {
return convert(value, [](auto c) {
return std::tolower(c); });
} }
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) { } // namespace modsecurity::actions::transformations
value[i] = std::tolower(value[i], loc);
}
return value;
}
} // namespace transformations
} // namespace actions
} // namespace modsecurity

View File

@ -13,34 +13,35 @@
* *
*/ */
#include <string>
#include <unordered_map>
#include "modsecurity/actions/action.h"
#include "src/actions/transformations/transformation.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_LOWER_CASE_H_ #ifndef SRC_ACTIONS_TRANSFORMATIONS_LOWER_CASE_H_
#define SRC_ACTIONS_TRANSFORMATIONS_LOWER_CASE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_LOWER_CASE_H_
#ifdef __cplusplus #include "transformation.h"
namespace modsecurity { #include <algorithm>
class Transaction;
namespace actions {
namespace transformations {
namespace modsecurity::actions::transformations {
class LowerCase : public Transformation { class LowerCase : public Transformation {
public: public:
explicit LowerCase(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;
template<typename Operation>
static bool convert(std::string &val, Operation op) {
bool changed = false;
std::transform(val.begin(), val.end(), val.data(),
[&](auto c) {
const auto nc = op(c);
if(nc != c) changed = true;
return nc; });
return changed;
}
}; };
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity
#endif
#endif // SRC_ACTIONS_TRANSFORMATIONS_LOWER_CASE_H_ #endif // SRC_ACTIONS_TRANSFORMATIONS_LOWER_CASE_H_

View File

@ -13,32 +13,17 @@
* *
*/ */
#include "src/actions/transformations/md5.h" #include "md5.h"
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include "modsecurity/transaction.h"
#include "src/actions/transformations/transformation.h"
#include "src/utils/md5.h" #include "src/utils/md5.h"
namespace modsecurity { namespace modsecurity::actions::transformations {
namespace actions {
namespace transformations {
std::string Md5::evaluate(const std::string &value, bool Md5::transform(std::string &value, const Transaction *trans) const {
Transaction *transaction) { value = Utils::Md5::digest(value);
std::string ret = Utils::Md5::digest(value); return true;
return ret;
} }
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity

View File

@ -13,33 +13,20 @@
* *
*/ */
#include <string>
#include "modsecurity/actions/action.h"
#include "src/actions/transformations/transformation.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_MD5_H_ #ifndef SRC_ACTIONS_TRANSFORMATIONS_MD5_H_
#define SRC_ACTIONS_TRANSFORMATIONS_MD5_H_ #define SRC_ACTIONS_TRANSFORMATIONS_MD5_H_
#ifdef __cplusplus #include "transformation.h"
namespace modsecurity {
class Transaction;
namespace actions { namespace modsecurity::actions::transformations {
namespace transformations {
class Md5 : public Transformation { class Md5 : public Transformation {
public: public:
explicit Md5(const std::string &action) : Transformation(action) { } using Transformation::Transformation;
std::string evaluate(const std::string &exp, bool transform(std::string &value, const Transaction *trans) const override;
Transaction *transaction) override;
}; };
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity
#endif
#endif // SRC_ACTIONS_TRANSFORMATIONS_MD5_H_ #endif // SRC_ACTIONS_TRANSFORMATIONS_MD5_H_

View File

@ -13,30 +13,15 @@
* *
*/ */
#include "src/actions/transformations/none.h" #include "none.h"
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include "modsecurity/transaction.h"
#include "src/actions/transformations/transformation.h"
namespace modsecurity { namespace modsecurity::actions::transformations {
namespace actions {
namespace transformations {
std::string None::evaluate(const std::string &value, bool None::transform(std::string &value, const Transaction *trans) const {
Transaction *transaction) { return false;
return value;
} }
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity

View File

@ -13,20 +13,12 @@
* *
*/ */
#include <string>
#include "modsecurity/actions/action.h"
#include "src/actions/transformations/transformation.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_NONE_H_ #ifndef SRC_ACTIONS_TRANSFORMATIONS_NONE_H_
#define SRC_ACTIONS_TRANSFORMATIONS_NONE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_NONE_H_
#ifdef __cplusplus #include "transformation.h"
namespace modsecurity {
class Transaction;
namespace actions { namespace modsecurity::actions::transformations {
namespace transformations {
class None : public Transformation { class None : public Transformation {
public: public:
@ -34,14 +26,9 @@ class None : public Transformation {
: Transformation(action) : Transformation(action)
{ m_isNone = true; } { m_isNone = true; }
std::string evaluate(const std::string &exp, bool transform(std::string &value, const Transaction *trans) const override;
Transaction *transaction) override;
}; };
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity
#endif
#endif // SRC_ACTIONS_TRANSFORMATIONS_NONE_H_ #endif // SRC_ACTIONS_TRANSFORMATIONS_NONE_H_

View File

@ -13,47 +13,14 @@
* *
*/ */
#include "src/actions/transformations/normalise_path.h" #include "normalise_path.h"
#include <string.h>
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include "modsecurity/transaction.h"
#include "src/actions/transformations/transformation.h"
namespace modsecurity { namespace modsecurity::actions::transformations {
namespace actions {
namespace transformations {
NormalisePath::NormalisePath(const std::string &action)
: Transformation(action) {
this->action_kind = 1;
}
std::string NormalisePath::evaluate(const std::string &value, bool NormalisePath::transform(std::string &value, const Transaction *trans) const {
Transaction *transaction) { return normalize_path_inplace(value, false);
int changed = 0;
char *tmp = reinterpret_cast<char *>(
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;
} }
@ -61,21 +28,22 @@ std::string NormalisePath::evaluate(const std::string &value,
* *
* IMP1 Assumes NUL-terminated * IMP1 Assumes NUL-terminated
*/ */
int NormalisePath::normalize_path_inplace(unsigned char *input, int input_len, bool NormalisePath::normalize_path_inplace(std::string &val, const bool win) {
int win, int *changed) {
unsigned char *src; unsigned char *src;
unsigned char *dst; unsigned char *dst;
unsigned char *end; unsigned char *end;
int ldst = 0;
int hitroot = 0; int hitroot = 0;
int done = 0; int done = 0;
int relative; int relative;
int trailing; int trailing;
*changed = 0; bool changed = false;
/* Need at least one byte to normalize */ /* Need at least one byte to normalize */
if (input_len <= 0) return 0; if(val.empty()) return false;
auto input = reinterpret_cast<unsigned char*>(val.data());
const auto input_len = val.length();
/* /*
* ENH: Deal with UNC and drive letters? * 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; src = dst = input;
end = input + (input_len - 1); end = input + (input_len - 1);
ldst = 1;
relative = ((*input == '/') || (win && (*input == '\\'))) ? 0 : 1; relative = ((*input == '/') || (win && (*input == '\\'))) ? 0 : 1;
trailing = ((*end == '/') || (win && (*end == '\\'))) ? 1 : 0; trailing = ((*end == '/') || (win && (*end == '\\'))) ? 1 : 0;
@ -94,11 +61,11 @@ int NormalisePath::normalize_path_inplace(unsigned char *input, int input_len,
if (win) { if (win) {
if (*src == '\\') { if (*src == '\\') {
*src = '/'; *src = '/';
*changed = 1; changed = true;
} }
if ((src < end) && (*(src + 1) == '\\')) { if ((src < end) && (*(src + 1) == '\\')) {
*(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? */ /* Could it be an empty path segment? */
if ((src != end) && *src == '/') { if ((src != end) && *src == '/') {
/* Ignore */ /* Ignore */
*changed = 1; changed = true;
goto copy; /* Copy will take care of this. */ goto copy; /* Copy will take care of this. */
} else if (*src == '.') { } else if (*src == '.') {
/* Could it be a back or self reference? */ /* 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++; src++;
*changed = 1; changed = true;
} else if (dst == input) { } else if (dst == input) {
/* Relative Self-reference? */ /* Relative Self-reference? */
*changed = 1; changed = true;
/* Ignore. */ /* Ignore. */
if (done) goto length; /* Skip the copy. */ if (done) goto skip_copy; /* Skip the copy. */
src++; src++;
} else if (*(dst - 1) == '/') { } else if (*(dst - 1) == '/') {
/* Self-reference? */ /* Self-reference? */
*changed = 1; changed = true;
/* Ignore. */ /* Ignore. */
if (done) goto length; /* Skip the copy. */ if (done) goto skip_copy; /* Skip the copy. */
dst--; dst--;
src++; src++;
} }
@ -191,7 +158,7 @@ copy:
&& ((*(src + 1) == '/') || (win && (*(src + 1) == '\\'))) ) { && ((*(src + 1) == '/') || (win && (*(src + 1) == '\\'))) ) {
src++; src++;
} }
if (oldsrc != src) *changed = 1; if (oldsrc != src) changed = true;
/* Do not copy the forward slash to the root /* Do not copy the forward slash to the root
* if it is not a relative path. Instead * if it is not a relative path. Instead
@ -199,30 +166,28 @@ copy:
*/ */
if (relative && (dst == input)) { if (relative && (dst == input)) {
src++; src++;
goto length; /* Skip the copy */ goto skip_copy; /* Skip the copy */
} }
} }
*(dst++) = *(src++); *(dst++) = *(src++);
length: skip_copy:
ldst = (dst - input); ; // nop for the goto label to work
} }
/* Make sure that there is not a trailing slash in the /* Make sure that there is not a trailing slash in the
* normalized form if there was not one in the original form. * normalized form if there was not one in the original form.
*/ */
if (!trailing && (dst > input) && *(dst - 1) == '/') { if (!trailing && (dst > input) && *(dst - 1) == '/') {
ldst--;
dst--; dst--;
} }
/* Always NUL terminate */ /* Always NUL terminate */
*dst = '\0'; *dst = '\0';
return ldst; val.resize(dst - input);
return changed;
} }
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity

View File

@ -13,37 +13,22 @@
* *
*/ */
#include <string>
#include "modsecurity/actions/action.h"
#include "src/actions/transformations/transformation.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_H_ #ifndef SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_H_
#define SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_H_ #define SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_H_
#ifdef __cplusplus #include "transformation.h"
namespace modsecurity {
class Transaction;
namespace actions { namespace modsecurity::actions::transformations {
namespace transformations {
class NormalisePath : public Transformation { class NormalisePath : public Transformation {
public: 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, static bool normalize_path_inplace(std::string &val, const bool win);
Transaction *transaction) override;
static int normalize_path_inplace(unsigned char *input, int input_len,
int win, int *changed);
}; };
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity
#endif
#endif // SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_H_ #endif // SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_H_

View File

@ -13,48 +13,17 @@
* *
*/ */
#include "src/actions/transformations/normalise_path_win.h" #include "normalise_path_win.h"
#include <string.h> #include "normalise_path.h"
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include "modsecurity/transaction.h"
#include "src/actions/transformations/transformation.h"
#include "src/actions/transformations/normalise_path.h"
namespace modsecurity { namespace modsecurity::actions::transformations {
namespace actions {
namespace transformations {
std::string NormalisePathWin::evaluate(const std::string &value, bool NormalisePathWin::transform(std::string &value, const Transaction *trans) const {
Transaction *transaction) { return NormalisePath::normalize_path_inplace(value, true);
int changed;
char *tmp = reinterpret_cast<char *>(
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<unsigned char *>(tmp),
value.size(), 1, &changed);
std::string ret("");
ret.assign(tmp, i);
free(tmp);
return ret;
} }
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity

View File

@ -13,33 +13,20 @@
* *
*/ */
#include <string>
#include "modsecurity/actions/action.h"
#include "src/actions/transformations/transformation.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_WIN_H_ #ifndef SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_WIN_H_
#define SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_WIN_H_ #define SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_WIN_H_
#include "transformation.h"
namespace modsecurity { namespace modsecurity::actions::transformations {
class Transaction;
namespace actions {
namespace transformations {
class NormalisePathWin : public Transformation { class NormalisePathWin : public Transformation {
public: public:
explicit NormalisePathWin(const std::string &action) using Transformation::Transformation;
: Transformation(action) { }
std::string evaluate(const std::string &exp, bool transform(std::string &value, const Transaction *trans) const override;
Transaction *transaction) override;
}; };
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity
#endif // SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_WIN_H_ #endif // SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_WIN_H_

View File

@ -13,70 +13,15 @@
* *
*/ */
#include "src/actions/transformations/parity_even_7bit.h" #include "parity_even_7bit.h"
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include <cstring>
#include "modsecurity/transaction.h"
#include "src/actions/transformations/transformation.h"
namespace modsecurity { namespace modsecurity::actions::transformations {
namespace actions {
namespace transformations {
std::string ParityEven7bit::evaluate(const std::string &value, bool ParityEven7bit::transform(std::string &value, const Transaction *trans) const {
Transaction *transaction) { return ParityEven7bit::inplace<true>(value);
std::string ret;
unsigned char *input;
input = reinterpret_cast<unsigned char *>
(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<char *>(input), value.length());
free(input);
return ret;
}
bool ParityEven7bit::inplace(unsigned char *input, uint64_t input_len) {
uint64_t i;
i = 0;
while (i < input_len) {
unsigned int x = input[i];
input[i] ^= input[i] >> 4;
input[i] &= 0xf;
if ((0x6996 >> input[i]) & 1) {
input[i] = x | 0x80;
} else {
input[i] = x & 0x7f;
}
i++;
}
return true;
} }
} // namespace modsecurity::actions::transformations
} // namespace transformations
} // namespace actions
} // namespace modsecurity

View File

@ -13,33 +13,42 @@
* *
*/ */
#include <string>
#include "modsecurity/actions/action.h"
#include "src/actions/transformations/transformation.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_PARITY_EVEN_7BIT_H_ #ifndef SRC_ACTIONS_TRANSFORMATIONS_PARITY_EVEN_7BIT_H_
#define SRC_ACTIONS_TRANSFORMATIONS_PARITY_EVEN_7BIT_H_ #define SRC_ACTIONS_TRANSFORMATIONS_PARITY_EVEN_7BIT_H_
#ifdef __cplusplus #include "transformation.h"
namespace modsecurity {
class Transaction;
namespace actions { namespace modsecurity::actions::transformations {
namespace transformations {
class ParityEven7bit : public Transformation { class ParityEven7bit : public Transformation {
public: public:
explicit ParityEven7bit(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;
static bool inplace(unsigned char *input, uint64_t input_len);
template<bool even>
static bool inplace(std::string &value) {
if (value.empty()) return false;
for(auto &c : value) {
auto &uc = reinterpret_cast<unsigned char&>(c);
unsigned int x = uc;
uc ^= uc >> 4;
uc &= 0xf;
const bool condition = (0x6996 >> uc) & 1;
if (even ? condition : !condition) {
uc = x | 0x80;
} else {
uc = x & 0x7f;
}
}
return true;
}
}; };
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity
#endif
#endif // SRC_ACTIONS_TRANSFORMATIONS_PARITY_EVEN_7BIT_H_ #endif // SRC_ACTIONS_TRANSFORMATIONS_PARITY_EVEN_7BIT_H_

View File

@ -13,69 +13,16 @@
* *
*/ */
#include "src/actions/transformations/parity_odd_7bit.h" #include "parity_odd_7bit.h"
#include "parity_even_7bit.h"
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include <cstring>
#include "modsecurity/transaction.h"
#include "src/actions/transformations/transformation.h"
namespace modsecurity { namespace modsecurity::actions::transformations {
namespace actions {
namespace transformations {
std::string ParityOdd7bit::evaluate(const std::string &value, bool ParityOdd7bit::transform(std::string &value, const Transaction *trans) const {
Transaction *transaction) { return ParityEven7bit::inplace<false>(value);
std::string ret;
unsigned char *input;
input = reinterpret_cast<unsigned char *>
(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<char *>(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;
} }
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity

View File

@ -13,33 +13,20 @@
* *
*/ */
#include <string>
#include "modsecurity/actions/action.h"
#include "src/actions/transformations/transformation.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_PARITY_ODD_7BIT_H_ #ifndef SRC_ACTIONS_TRANSFORMATIONS_PARITY_ODD_7BIT_H_
#define SRC_ACTIONS_TRANSFORMATIONS_PARITY_ODD_7BIT_H_ #define SRC_ACTIONS_TRANSFORMATIONS_PARITY_ODD_7BIT_H_
#ifdef __cplusplus #include "transformation.h"
namespace modsecurity {
class Transaction;
namespace actions { namespace modsecurity::actions::transformations {
namespace transformations {
class ParityOdd7bit : public Transformation { class ParityOdd7bit : public Transformation {
public: public:
explicit ParityOdd7bit(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;
static bool inplace(unsigned char *input, uint64_t input_len);
}; };
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity
#endif
#endif // SRC_ACTIONS_TRANSFORMATIONS_PARITY_ODD_7BIT_H_ #endif // SRC_ACTIONS_TRANSFORMATIONS_PARITY_ODD_7BIT_H_

View File

@ -13,61 +13,26 @@
* *
*/ */
#include "src/actions/transformations/parity_zero_7bit.h" #include "parity_zero_7bit.h"
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include <cstring>
#include "modsecurity/transaction.h"
#include "src/actions/transformations/transformation.h"
namespace modsecurity { namespace modsecurity::actions::transformations {
namespace actions {
namespace transformations {
std::string ParityZero7bit::evaluate(const std::string &value, static inline bool inplace(std::string &value) {
Transaction *transaction) { if (value.empty()) return false;
std::string ret;
unsigned char *input;
input = reinterpret_cast<unsigned char *> for(auto &c : value) {
(malloc(sizeof(char) * value.length()+1)); ((unsigned char&)c) &= 0x7f;
if (input == NULL) {
return "";
}
memcpy(input, value.c_str(), value.length()+1);
inplace(input, value.length());
ret.assign(reinterpret_cast<char *>(input), value.length());
free(input);
return ret;
}
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; return true;
} }
} // namespace transformations bool ParityZero7bit::transform(std::string &value, const Transaction *trans) const {
} // namespace actions return inplace(value);
} // namespace modsecurity }
} // namespace modsecurity::actions::transformations

View File

@ -13,33 +13,20 @@
* *
*/ */
#include <string>
#include "modsecurity/actions/action.h"
#include "src/actions/transformations/transformation.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_PARITY_ZERO_7BIT_H_ #ifndef SRC_ACTIONS_TRANSFORMATIONS_PARITY_ZERO_7BIT_H_
#define SRC_ACTIONS_TRANSFORMATIONS_PARITY_ZERO_7BIT_H_ #define SRC_ACTIONS_TRANSFORMATIONS_PARITY_ZERO_7BIT_H_
#ifdef __cplusplus #include "transformation.h"
namespace modsecurity {
class Transaction;
namespace actions { namespace modsecurity::actions::transformations {
namespace transformations {
class ParityZero7bit : public Transformation { class ParityZero7bit : public Transformation {
public: public:
explicit ParityZero7bit(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;
static bool inplace(unsigned char *input, uint64_t input_len);
}; };
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity
#endif
#endif // SRC_ACTIONS_TRANSFORMATIONS_PARITY_ZERO_7BIT_H_ #endif // SRC_ACTIONS_TRANSFORMATIONS_PARITY_ZERO_7BIT_H_

View File

@ -13,61 +13,40 @@
* *
*/ */
#include "src/actions/transformations/remove_comments.h" #include "remove_comments.h"
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include <cstring>
#include "modsecurity/transaction.h"
#include "src/actions/transformations/transformation.h"
namespace modsecurity { namespace modsecurity::actions::transformations {
namespace actions {
namespace transformations {
std::string RemoveComments::evaluate(const std::string &value, static inline int inplace(std::string &value) {
Transaction *transaction) { auto input = reinterpret_cast<unsigned char*>(value.data());
std::string ret; const auto input_len = value.length();
unsigned char *input; bool changed = false, incomment = false;
std::string::size_type i = 0, j = 0;
input = reinterpret_cast<unsigned char *>
(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) { while (i < input_len) {
if (incomment == 0) { if (!incomment) {
if ((input[i] == '/') && (i + 1 < input_len) if ((input[i] == '/') && (i + 1 < input_len)
&& (input[i + 1] == '*')) { && (input[i + 1] == '*')) {
incomment = 1; incomment = true;
changed = true;
i += 2; i += 2;
} else if ((input[i] == '<') && (i + 1 < input_len) } else if ((input[i] == '<') && (i + 1 < input_len)
&& (input[i + 1] == '!') && (i + 2 < input_len) && (input[i + 1] == '!') && (i + 2 < input_len)
&& (input[i+2] == '-') && (i + 3 < input_len) && (input[i+2] == '-') && (i + 3 < input_len)
&& (input[i + 3] == '-')) { && (input[i + 3] == '-')) {
incomment = 1; incomment = true;
changed = true;
i += 4; i += 4;
} else if ((input[i] == '-') && (i + 1 < input_len) } else if ((input[i] == '-') && (i + 1 < input_len)
&& (input[i + 1] == '-')) { && (input[i + 1] == '-')) {
input[i] = ' '; input[i] = ' ';
changed = true;
break; break;
} else if (input[i] == '#') { } else if (input[i] == '#') {
input[i] = ' '; input[i] = ' ';
changed = true;
break; break;
} else { } else {
input[j] = input[i]; input[j] = input[i];
@ -77,7 +56,7 @@ std::string RemoveComments::evaluate(const std::string &value,
} else { } else {
if ((input[i] == '*') && (i + 1 < input_len) if ((input[i] == '*') && (i + 1 < input_len)
&& (input[i + 1] == '/')) { && (input[i + 1] == '/')) {
incomment = 0; incomment = false;
i += 2; i += 2;
input[j] = input[i]; input[j] = input[i];
i++; i++;
@ -85,7 +64,7 @@ std::string RemoveComments::evaluate(const std::string &value,
} else if ((input[i] == '-') && (i + 1 < input_len) } else if ((input[i] == '-') && (i + 1 < input_len)
&& (input[i + 1] == '-') && (i + 2 < input_len) && (input[i + 1] == '-') && (i + 2 < input_len)
&& (input[i+2] == '>')) { && (input[i+2] == '>')) {
incomment = 0; incomment = false;
i += 3; i += 3;
input[j] = input[i]; input[j] = input[i];
i++; i++;
@ -100,13 +79,14 @@ std::string RemoveComments::evaluate(const std::string &value,
input[j++] = ' '; input[j++] = ' ';
} }
ret.assign(reinterpret_cast<char *>(input), j); value.resize(j);
free(input); return changed;
return ret;
} }
} // namespace transformations bool RemoveComments::transform(std::string &value, const Transaction *trans) const {
} // namespace actions return inplace(value);
} // namespace modsecurity }
} // namespace modsecurity::actions::transformations

View File

@ -13,35 +13,20 @@
* *
*/ */
#include <string>
#include "modsecurity/actions/action.h"
#include "src/actions/transformations/transformation.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_H_ #ifndef SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_H_
#define SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_H_ #define SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_H_
#ifdef __cplusplus #include "transformation.h"
namespace modsecurity {
class Transaction;
namespace actions {
namespace transformations {
namespace modsecurity::actions::transformations {
class RemoveComments : public Transformation { class RemoveComments : public Transformation {
public: public:
explicit RemoveComments(const std::string &action) : Transformation(action) { } using Transformation::Transformation;
std::string evaluate(const std::string &exp, bool transform(std::string &value, const Transaction *trans) const override;
Transaction *transaction) override;
}; };
} // namespace modsecurity::actions::transformations
} // namespace transformations
} // namespace actions
} // namespace modsecurity
#endif
#endif // SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_H_ #endif // SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_H_

View File

@ -13,62 +13,51 @@
* *
*/ */
#include "src/actions/transformations/remove_comments_char.h" #include "remove_comments_char.h"
#include <string>
#include "modsecurity/transaction.h"
#include "src/actions/transformations/transformation.h"
namespace modsecurity { namespace modsecurity::actions::transformations {
namespace actions {
namespace transformations {
RemoveCommentsChar::RemoveCommentsChar(const std::string &action)
: Transformation(action) {
this->action_kind = 1;
}
std::string RemoveCommentsChar::evaluate(const std::string &val, bool RemoveCommentsChar::transform(std::string &value, const Transaction *trans) const {
Transaction *transaction) { char *d = value.data();
size_t i = 0; const char *s = d;
std::string transformed_value; const char *e = s + value.size();
transformed_value.reserve(val.size());
while (i < val.size()) { while (s < e) {
if (val.at(i) == '/' if (*s == '/'
&& (i+1 < val.size()) && val.at(i+1) == '*') { && (s+1 < e) && *(s+1) == '*') {
i += 2; s += 2;
} else if (val.at(i) == '*' } else if (*s == '*'
&& (i+1 < val.size()) && val.at(i+1) == '/') { && (s+1 < e) && *(s+1) == '/') {
i += 2; s += 2;
} else if (val.at(i) == '<' } else if (*s == '<'
&& (i+1 < val.size()) && (s+1 < e)
&& val.at(i+1) == '!' && *(s+1) == '!'
&& (i+2 < val.size()) && (s+2 < e)
&& val.at(i+2) == '-' && *(s+2) == '-'
&& (i+3 < val.size()) && (s+3 < e)
&& val.at(i+3) == '-') { && *(s+3) == '-') {
i += 4; s += 4;
} else if (val.at(i) == '-' } else if (*s == '-'
&& (i+1 < val.size()) && val.at(i+1) == '-' && (s+1 < e) && *(s+1) == '-'
&& (i+2 < val.size()) && val.at(i+2) == '>') { && (s+2 < e) && *(s+2) == '>') {
i += 3; s += 3;
} else if (val.at(i) == '-' } else if (*s == '-'
&& (i+1 < val.size()) && val.at(i+1) == '-') { && (s+1 < e) && *(s+1) == '-') {
i += 2; s += 2;
} else if (val.at(i) == '#') { } else if (*s == '#') {
i += 1; s += 1;
} else { } else {
transformed_value += val.at(i); *d++ = *s++;
i++;
} }
} }
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 modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity

View File

@ -13,33 +13,20 @@
* *
*/ */
#include <string>
#include "modsecurity/actions/action.h"
#include "src/actions/transformations/transformation.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_CHAR_H_ #ifndef SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_CHAR_H_
#define SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_CHAR_H_ #define SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_CHAR_H_
#ifdef __cplusplus #include "transformation.h"
namespace modsecurity {
class Transaction;
namespace actions { namespace modsecurity::actions::transformations {
namespace transformations {
class RemoveCommentsChar : public Transformation { class RemoveCommentsChar : public Transformation {
public: public:
explicit RemoveCommentsChar(const std::string &action); using Transformation::Transformation;
std::string evaluate(const std::string &exp, bool transform(std::string &value, const Transaction *trans) const override;
Transaction *transaction) override;
}; };
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity
#endif
#endif // SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_CHAR_H_ #endif // SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_CHAR_H_

View File

@ -13,40 +13,15 @@
* *
*/ */
#include "src/actions/transformations/remove_nulls.h" #include "remove_nulls.h"
#include <string.h>
#include <string>
#include "modsecurity/transaction.h"
#include "src/actions/transformations/transformation.h"
namespace modsecurity { namespace modsecurity::actions::transformations {
namespace actions {
namespace transformations {
std::string RemoveNulls::evaluate(const std::string &val, bool RemoveNulls::transform(std::string &value, const Transaction *trans) const {
Transaction *transaction) { return remove_if(value, [](const auto c) { return c == '\0'; });
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;
} }
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity

View File

@ -13,34 +13,34 @@
* *
*/ */
#include <string>
#include "modsecurity/actions/action.h"
#include "src/actions/transformations/transformation.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_REMOVE_NULLS_H_ #ifndef SRC_ACTIONS_TRANSFORMATIONS_REMOVE_NULLS_H_
#define SRC_ACTIONS_TRANSFORMATIONS_REMOVE_NULLS_H_ #define SRC_ACTIONS_TRANSFORMATIONS_REMOVE_NULLS_H_
#ifdef __cplusplus #include "transformation.h"
namespace modsecurity {
class Transaction;
namespace actions { #include <algorithm>
namespace transformations {
namespace modsecurity::actions::transformations {
class RemoveNulls : public Transformation { class RemoveNulls : public Transformation {
public: public:
explicit RemoveNulls(const std::string &action) using Transformation::Transformation;
: Transformation(action) { }
std::string evaluate(const std::string &exp, bool transform(std::string &value, const Transaction *trans) const override;
Transaction *transaction) override;
template<typename Pred>
static bool remove_if(std::string &val, Pred pred) {
const auto old_size = val.size();
val.erase(
std::remove_if(
val.begin(), val.end(), pred),
val.end());
return val.size() != old_size;
}
}; };
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity
#endif
#endif // SRC_ACTIONS_TRANSFORMATIONS_REMOVE_NULLS_H_ #endif // SRC_ACTIONS_TRANSFORMATIONS_REMOVE_NULLS_H_

View File

@ -13,49 +13,27 @@
* *
*/ */
#include "src/actions/transformations/remove_whitespace.h" #include "remove_whitespace.h"
#include <string> #include "remove_nulls.h"
#include "modsecurity/transaction.h" namespace modsecurity::actions::transformations {
#include "src/actions/transformations/transformation.h"
namespace modsecurity { bool RemoveWhitespace::transform(std::string &value, const Transaction *trans) const {
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;
const char nonBreakingSpaces = 0xa0; const char nonBreakingSpaces = 0xa0;
const char nonBreakingSpaces2 = 0xc2; const char nonBreakingSpaces2 = 0xc2;
// loop through all the chars auto pred = [](const auto c) {
while (i < val.size()) {
// remove whitespaces and non breaking spaces (NBSP) // remove whitespaces and non breaking spaces (NBSP)
if (std::isspace(static_cast<unsigned char>(val[i])) return std::isspace(static_cast<unsigned char>(c))
|| (val[i] == nonBreakingSpaces) || c == nonBreakingSpaces
|| val[i] == nonBreakingSpaces2) { || c == nonBreakingSpaces2;
// don't copy; continue on to next char in original val };
} else {
transformed_value += val.at(i);
}
i++;
}
return transformed_value; return RemoveNulls::remove_if(value, pred);
} }
} // namespace transformations
} // namespace actions } // namespace modsecurity::actions::transformations
} // namespace modsecurity

View File

@ -13,33 +13,20 @@
* *
*/ */
#include <string>
#include "modsecurity/actions/action.h"
#include "src/actions/transformations/transformation.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_REMOVE_WHITESPACE_H_ #ifndef SRC_ACTIONS_TRANSFORMATIONS_REMOVE_WHITESPACE_H_
#define SRC_ACTIONS_TRANSFORMATIONS_REMOVE_WHITESPACE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_REMOVE_WHITESPACE_H_
#ifdef __cplusplus #include "transformation.h"
namespace modsecurity {
class Transaction;
namespace actions { namespace modsecurity::actions::transformations {
namespace transformations {
class RemoveWhitespace : public Transformation { class RemoveWhitespace : public Transformation {
public: public:
explicit RemoveWhitespace(const std::string &action); using Transformation::Transformation;
std::string evaluate(const std::string &exp, bool transform(std::string &value, const Transaction *trans) const override;
Transaction *transaction) override;
}; };
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity
#endif
#endif // SRC_ACTIONS_TRANSFORMATIONS_REMOVE_WHITESPACE_H_ #endif // SRC_ACTIONS_TRANSFORMATIONS_REMOVE_WHITESPACE_H_

View File

@ -13,54 +13,34 @@
* *
*/ */
#include "src/actions/transformations/replace_comments.h" #include "replace_comments.h"
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include <cstring>
#include "modsecurity/transaction.h"
#include "src/actions/transformations/transformation.h"
namespace modsecurity { namespace modsecurity::actions::transformations {
namespace actions {
namespace transformations {
ReplaceComments::ReplaceComments(const std::string &action)
: Transformation(action) {
this->action_kind = 1;
}
std::string ReplaceComments::evaluate(const std::string &value, static inline bool inplace(std::string &value) {
Transaction *transaction) { auto input = reinterpret_cast<unsigned char*>(value.data());
uint64_t i, j, incomment; const auto input_len = value.length();
bool changed = false, incomment = false;
std::string::size_type i = 0, j = 0;
char *input = reinterpret_cast<char *>( while (i < input_len) {
malloc(sizeof(char) * value.size() + 1)); if (!incomment) {
memcpy(input, value.c_str(), value.size() + 1); if ((input[i] == '/') && (i + 1 < input_len)
input[value.size()] = '\0';
i = j = incomment = 0;
while (i < value.size()) {
if (incomment == 0) {
if ((input[i] == '/') && (i + 1 < value.size())
&& (input[i + 1] == '*')) { && (input[i + 1] == '*')) {
incomment = 1; incomment = true;
i += 2; i += 2;
changed = true;
} else { } else {
input[j] = input[i]; input[j] = input[i];
i++; i++;
j++; j++;
} }
} else { } else {
if ((input[i] == '*') && (i + 1 < value.size()) if ((input[i] == '*') && (i + 1 < input_len)
&& (input[i + 1] == '/')) { && (input[i + 1] == '/')) {
incomment = 0; incomment = false;
i += 2; i += 2;
input[j] = ' '; input[j] = ' ';
j++; j++;
@ -74,15 +54,14 @@ std::string ReplaceComments::evaluate(const std::string &value,
input[j++] = ' '; input[j++] = ' ';
} }
value.resize(j);
std::string resp; return changed;
resp.append(reinterpret_cast<char *>(input), j);
free(input);
return resp;
} }
} // namespace transformations
} // namespace actions bool ReplaceComments::transform(std::string &value, const Transaction *trans) const {
} // namespace modsecurity return inplace(value);
}
} // namespace modsecurity::actions::transformations

View File

@ -13,34 +13,20 @@
* *
*/ */
#include <string>
#include "modsecurity/actions/action.h"
#include "src/actions/transformations/transformation.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_REPLACE_COMMENTS_H_ #ifndef SRC_ACTIONS_TRANSFORMATIONS_REPLACE_COMMENTS_H_
#define SRC_ACTIONS_TRANSFORMATIONS_REPLACE_COMMENTS_H_ #define SRC_ACTIONS_TRANSFORMATIONS_REPLACE_COMMENTS_H_
#ifdef __cplusplus #include "transformation.h"
namespace modsecurity {
class Transaction;
namespace actions { namespace modsecurity::actions::transformations {
namespace transformations {
class ReplaceComments : public Transformation { class ReplaceComments : public Transformation {
public: public:
using Transformation::Transformation;
explicit ReplaceComments(const std::string &action) ; bool transform(std::string &value, const Transaction *trans) const override;
std::string evaluate(const std::string &exp,
Transaction *transaction) override;
}; };
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity
#endif
#endif // SRC_ACTIONS_TRANSFORMATIONS_REPLACE_COMMENTS_H_ #endif // SRC_ACTIONS_TRANSFORMATIONS_REPLACE_COMMENTS_H_

View File

@ -13,40 +13,23 @@
* *
*/ */
#include "src/actions/transformations/replace_nulls.h" #include "replace_nulls.h"
#include <string>
#include "modsecurity/transaction.h"
#include "src/actions/transformations/transformation.h"
namespace modsecurity { namespace modsecurity::actions::transformations {
namespace actions {
namespace transformations {
ReplaceNulls::ReplaceNulls(const std::string &action)
: Transformation(action) {
this->action_kind = 1;
}
std::string ReplaceNulls::evaluate(const std::string &val, bool ReplaceNulls::transform(std::string &value, const Transaction *trans) const {
Transaction *transaction) { bool changed = false;
int64_t i;
std::string value(val);
i = 0; for(auto &c : value) {
while (i < value.size()) { if (c == '\0') {
if (value.at(i) == '\0') { c = ' ';
value[i] = ' '; changed = true;
} else {
i++;
} }
} }
return value; return changed;
} }
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity

View File

@ -13,34 +13,20 @@
* *
*/ */
#include <string>
#include "modsecurity/actions/action.h"
#include "src/actions/transformations/transformation.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_REPLACE_NULLS_H_ #ifndef SRC_ACTIONS_TRANSFORMATIONS_REPLACE_NULLS_H_
#define SRC_ACTIONS_TRANSFORMATIONS_REPLACE_NULLS_H_ #define SRC_ACTIONS_TRANSFORMATIONS_REPLACE_NULLS_H_
#ifdef __cplusplus #include "transformation.h"
namespace modsecurity {
class Transaction;
namespace actions { namespace modsecurity::actions::transformations {
namespace transformations {
class ReplaceNulls : public Transformation { class ReplaceNulls : public Transformation {
public: public:
using Transformation::Transformation;
explicit ReplaceNulls(const std::string &action) ; bool transform(std::string &value, const Transaction *trans) const override;
std::string evaluate(const std::string &exp,
Transaction *transaction) override;
}; };
} // namespace transformations } // namespace modsecurity::actions::transformations
} // namespace actions
} // namespace modsecurity
#endif
#endif // SRC_ACTIONS_TRANSFORMATIONS_REPLACE_NULLS_H_ #endif // SRC_ACTIONS_TRANSFORMATIONS_REPLACE_NULLS_H_

Some files were not shown because too many files have changed in this diff Show More