33
33
34
34
namespace modsecurity {
35
35
36
- class RunTimeElementHolder {
37
- public:
38
- RunTimeElementHolder ()
39
- : m_string(" " ),
40
- m_variable (nullptr )
41
- { };
42
-
43
-
44
- RunTimeElementHolder (const RunTimeElementHolder &other)
45
- : m_string(other.m_string),
46
- m_variable(other.m_variable) {
47
- variables::RuleVariable *rv = dynamic_cast <variables::RuleVariable *>(m_variable.get ());
48
- if (rv != nullptr ) {
49
- auto nrv = rv->clone ();
50
- rv = dynamic_cast <variables::RuleVariable *>(nrv);
51
- rv->populate (nullptr );
52
- m_variable = std::unique_ptr<variables::Variable>(nrv);
53
- }
54
- };
55
-
56
- /* protected: */
57
- std::string m_string;
58
- std::shared_ptr<variables::Variable> m_variable;
59
- };
60
-
61
36
class RunTimeString {
62
37
public:
38
+ using Variable = variables::Variable;
39
+ using RuleVariable = variables::RuleVariable;
40
+
63
41
RunTimeString ()
64
42
: m_containsMacro(false ),
65
43
m_elements ()
@@ -71,37 +49,124 @@ class RunTimeString {
71
49
m_elements()
72
50
{
73
51
for (auto &m : other.m_elements ) {
74
- m_elements.push_back (std::unique_ptr<RunTimeElementHolder>( new RunTimeElementHolder (*m.get () )));
52
+ m_elements.emplace_back ( new ElementHolder (*m.get ()));
75
53
}
76
54
};
77
55
56
+ RunTimeString& operator =(RunTimeString other)
57
+ {
58
+ m_containsMacro = other.m_containsMacro ;
59
+ for (auto &m : other.m_elements ) {
60
+ m_elements.emplace_back (new ElementHolder (*m.get ()));
61
+ }
62
+ return *this ;
63
+ }
78
64
79
- void appendText (const std::string &text);
80
- void appendVar (std::unique_ptr<modsecurity::variables::Variable> var);
81
65
66
+ void append (const std::string &text);
67
+ void append (std::unique_ptr<Variable> var);
82
68
83
- std::string evaluate (Transaction *t);
84
69
85
- inline std::string evaluate () {
86
- return evaluate (NULL );
87
- }
70
+ /*
71
+ *
72
+ * FIXME: Transaction should be const here. Variables resolution does
73
+ * not change anything on transaction instance.
74
+ *
75
+ */
76
+ std::string evaluate (/* const */ Transaction *t = nullptr ) const noexcept ;
88
77
89
78
90
- inline bool containsMacro () const { return m_containsMacro; }
79
+ inline bool containsMacro () const noexcept {
80
+ return m_containsMacro;
81
+ }
91
82
92
83
93
- void populate (RuleWithActions *rule) {
84
+ void populate (RuleWithActions *rule) noexcept {
94
85
for (auto &a : m_elements) {
95
- modsecurity::variables::RuleVariable *vrule = dynamic_cast <variables::RuleVariable *>(a->m_variable .get ());
86
+ a->populate (rule);
87
+ }
88
+ }
89
+
90
+
91
+ class ElementHolder {
92
+ public:
93
+ ElementHolder ()
94
+ : m_string(" " ),
95
+ m_variable (nullptr )
96
+ { };
97
+
98
+ explicit ElementHolder (std::unique_ptr<Variable> variable)
99
+ : m_string(" " ),
100
+ m_variable(std::move(variable))
101
+ { };
102
+
103
+ explicit ElementHolder (const std::string &str)
104
+ : m_string(str),
105
+ m_variable(nullptr )
106
+ { };
107
+
108
+ ElementHolder (const ElementHolder &other)
109
+ : m_string(other.m_string),
110
+ m_variable(nullptr ) {
111
+ RuleVariable *rv = dynamic_cast <RuleVariable *>(other.m_variable .get ());
112
+ if (rv != nullptr ) {
113
+ auto nrv = rv->clone ();
114
+ rv = dynamic_cast <RuleVariable *>(nrv);
115
+ rv->populate (nullptr );
116
+ m_variable = std::unique_ptr<Variable>(nrv);
117
+ /* m_variable = nullptr; */
118
+ } else {
119
+ m_variable = other.m_variable ;
120
+ }
121
+
122
+ };
123
+
124
+
125
+ void appendValueTo (/* const */ Transaction *transaction, std::string &v) const noexcept {
126
+ if (m_variable && transaction) {
127
+ std::vector<const VariableValue *> l;
128
+ m_variable->evaluate (transaction, &l);
129
+ if (!l.empty ()) {
130
+ v.append (l[0 ]->getValue ());
131
+ }
132
+ for (auto &i : l) {
133
+ delete i;
134
+ }
135
+
136
+ return ;
137
+ }
138
+
139
+ v.append (m_string);
140
+ }
141
+
142
+
143
+ void populate (RuleWithActions *rule) noexcept {
144
+ if (!m_variable) {
145
+ return ;
146
+ }
147
+
148
+ RuleVariable *vrule = dynamic_cast <RuleVariable *>(m_variable.get ());
96
149
if (vrule != nullptr ) {
97
150
vrule->populate (rule);
98
151
}
99
152
}
100
- }
101
153
154
+ private:
155
+ std::string m_string;
156
+ /*
157
+ *
158
+ * FIXME: In the current state m_variable should be a unique_ptr. There
159
+ * is no copy for variables, thus having a shared pointer here.
160
+ * As an optimization we can have it as a shared_ptr to reduce the
161
+ * memory footprint in anchored variables.
162
+ *
163
+ */
164
+ std::shared_ptr<Variable> m_variable;
165
+ };
166
+
102
167
private:
103
- bool m_containsMacro;
104
- std::list <std::unique_ptr<RunTimeElementHolder >> m_elements;
168
+ bool m_containsMacro: 1 ;
169
+ std::vector <std::unique_ptr<ElementHolder >> m_elements;
105
170
};
106
171
107
172
0 commit comments