From 820396f784515abf8bc1a01246f4b53c36d5bb80 Mon Sep 17 00:00:00 2001 From: Felipe Zimmerle Date: Thu, 17 Sep 2020 19:51:34 -0300 Subject: [PATCH] Reduce the workload on VariableValue Last compute at the last minute, if needed. --- headers/modsecurity/anchored_set_variable.h | 14 +- headers/modsecurity/transaction.h | 11 - headers/modsecurity/variable_value.h | 204 +++++++++++++++--- src/anchored_set_variable.cc | 35 +-- src/anchored_variable.cc | 3 +- .../backend/in_memory-per_process.cc | 3 +- src/rule_with_operator.cc | 10 +- src/transaction.cc | 22 -- src/variables/duration.cc | 6 +- src/variables/env.cc | 26 +-- src/variables/env.h | 7 +- src/variables/highest_severity.cc | 6 +- src/variables/remote_user.cc | 2 +- src/variables/rule.h | 15 +- src/variables/time.cc | 5 +- src/variables/time_day.cc | 6 +- src/variables/time_epoch.cc | 7 +- src/variables/time_hour.cc | 6 +- src/variables/time_min.cc | 6 +- src/variables/time_mon.cc | 10 +- src/variables/time_sec.cc | 6 +- src/variables/time_wday.cc | 6 +- src/variables/time_year.cc | 6 +- src/variables/variable.h | 5 +- 24 files changed, 255 insertions(+), 172 deletions(-) diff --git a/headers/modsecurity/anchored_set_variable.h b/headers/modsecurity/anchored_set_variable.h index 63f3cc7c..0584cb7d 100644 --- a/headers/modsecurity/anchored_set_variable.h +++ b/headers/modsecurity/anchored_set_variable.h @@ -78,19 +78,15 @@ class AnchoredSetVariable : public std::unordered_multimap m_variableEnvs; - std::string m_variableHighestSeverityAction; std::string m_variableRemoteUser; - std::string m_variableTime; - std::string m_variableTimeDay; - std::string m_variableTimeEpoch; - std::string m_variableTimeHour; - std::string m_variableTimeMin; - std::string m_variableTimeSec; - std::string m_variableTimeWDay; - std::string m_variableTimeYear; std::vector> m_multipartPartTmpFiles; diff --git a/headers/modsecurity/variable_value.h b/headers/modsecurity/variable_value.h index 5251c156..6d875dc7 100644 --- a/headers/modsecurity/variable_value.h +++ b/headers/modsecurity/variable_value.h @@ -20,9 +20,13 @@ #include #include #include +#include #endif #include "modsecurity/variable_origin.h" +#ifdef __cplusplus +#include "modsecurity/string_view.hpp" +#endif #ifndef HEADERS_MODSECURITY_VARIABLE_VALUE_H_ #define HEADERS_MODSECURITY_VARIABLE_VALUE_H_ @@ -38,70 +42,208 @@ class VariableValue; using VariableValues = std::vector>; using Origins = std::vector; - class Collection; class VariableValue { public: + /** + * + * + * Use cases for VariableValue creation: + * + * AnchoredSet - Use case A (eg. ARGS). - Collection + Key + * Anchored - Use case B (eg. REQUEST_URI). - Key + * Custom - Use case C (eg. WEBAPP_ID). - Key + * CustomSet + * Fixed - Use case D (eg. TX). - Collection + Key + * Dynamic - Use case E (eg. ENV). - Collection + Key + * + * + * | Key | Collec. | Key + Collec. | Value | Full Name + * A | & | & | * | & | * + * B | x | & | * | & | & + * C | x | & | * | & | & + * D | & | & | * | & | * + * E | & | & | * | * | * + * + * + * + * Currently big picture of getName and getKey: + * + * getName() + * - Lua Engine - RuleWithOperator - Transaction + * - UpdateMatchedVar - logging (audit) + * - ExecuteOperatorAt + * - ResolveMatchMsg + * - RulesExceptions (key and value) + * + * + * getKey() + * - Transaction - Variable + * - LogGen - Contains + * - Regexp + * + * + * Performance strategy: Delay the name resolution till is really necessary. + * + * + */ - explicit VariableValue(const std::string *key, + + /** + * + * Use case C + VariableModificatorCount + * + * + **/ + explicit VariableValue(const std::string *collection, const std::string *value = nullptr) - : m_collection(""), - m_key(*key), - m_keyWithCollection(*key), - m_value(value != nullptr?*value:"") - { } + : m_origin(), + m_value(), + m_valueHolder(new std::string(value != nullptr?*value:"")), // FIXME: do we really need a copy here? + m_key(nullptr), + m_keyHolder(nullptr), + m_collection(collection) + { + m_value = m_valueHolder.get(); + }; + + /* Use case D.1. - ARGS */ + VariableValue(const std::string *collection, + std::unique_ptr key, + std::unique_ptr value) + : m_origin(), + m_value(nullptr), + m_valueHolder(std::move(value)), + m_key(nullptr), + m_keyHolder(std::move(key)), + m_collection(collection) + { + m_value = m_valueHolder.get(); + m_key = m_keyHolder.get(); + }; + + + /* Use case D.2. - RULE */ + VariableValue(const std::string *collection, + const std::string *key, + std::unique_ptr value) + : m_origin(), + m_value(nullptr), + m_valueHolder(std::move(value)), + m_key(key), + m_keyHolder(nullptr), + m_collection(collection) + { + m_value = m_valueHolder.get(); + }; + + + /* Use case D.3. - TX */ VariableValue(const std::string *collection, const std::string *key, const std::string *value) - : m_collection(*collection), - m_key(*key), - m_keyWithCollection(*collection + ":" + *key), - m_value(*value) - { } + : m_origin(), + m_value(value), + m_valueHolder(nullptr), + m_key(key), + m_keyHolder(nullptr), + m_collection(collection) + { }; + + + // FIXME: It maybe the case for VariableValue to use string_view for everything. + /* Use case D.4. - MATCHED_VARS */ + VariableValue(const std::string *collection, + const std::string *key, + const bpstd::string_view *value) + : m_origin(), + m_value(), + m_valueHolder(std::unique_ptr(new std::string(value->c_str()))), + m_key(key), + m_keyHolder(nullptr), + m_collection(collection) + { + m_value = m_valueHolder.get(); + }; + + + /* Use case E.1. - Env */ + VariableValue(std::unique_ptr value, + std::unique_ptr key, + std::shared_ptr collection) + : m_origin(), + m_value(nullptr), + m_valueHolder(std::move(value)), + m_key(nullptr), + m_keyHolder(std::move(key)), + m_collection(collection.get()) + { + m_value = m_valueHolder.get(); + m_key = m_keyHolder.get(); + }; + + + /* Use case E.2. - DURATION */ + VariableValue(std::unique_ptr value, + const std::string *collection) + : m_origin(), + m_value(nullptr), + m_valueHolder(std::move(value)), + m_key(nullptr), + m_keyHolder(nullptr), + m_collection(collection) + { + m_value = m_valueHolder.get(); + }; + VariableValue(const VariableValue &o) = delete; - - const std::string& getName() const noexcept { - return m_keyWithCollection; - } + VariableValue operator=(const VariableValue &o) = delete; const std::string& getValue() const noexcept { - return m_value; + return *m_value; } - - - const std::string& getKey() const { - return m_key; + const std::string& getKey() const noexcept { + return *m_key; } - const std::string& getCollection() const { - return m_collection; + + inline const std::string getName() const noexcept { + if (m_key == nullptr || m_key->empty()) { + return *m_collection; + } + return *m_collection + ":" + *m_key; } + void setValue(const std::string &value) { - m_value = value; + m_value = &value; } void addOrigin(VariableOrigin origin) { - m_orign.push_back(std::move(origin)); + m_origin.push_back(std::move(origin)); } const Origins& getOrigin() const { - return m_orign; + return m_origin; } private: - Origins m_orign; - std::string m_collection; - std::string m_key; - std::string m_keyWithCollection; - std::string m_value; + Origins m_origin; + + const std::string *m_value; + std::unique_ptr m_valueHolder; + + const std::string *m_key; + std::unique_ptr m_keyHolder; + + const std::string *m_collection; }; } // namespace modsecurity diff --git a/src/anchored_set_variable.cc b/src/anchored_set_variable.cc index c7c9609f..367ca668 100644 --- a/src/anchored_set_variable.cc +++ b/src/anchored_set_variable.cc @@ -41,9 +41,12 @@ void AnchoredSetVariable::unset() { } +// FIXME: It may not be necessary to copy the content of void AnchoredSetVariable::set(const std::string &key, const std::string &value, size_t offset, size_t len) { - auto var = std::make_shared(&m_name, &key, &value); + auto var = std::make_shared(&m_name, + std::unique_ptr(new std::string(key)), + std::unique_ptr(new std::string(value))); VariableOrigin origin; origin.m_offset = offset; @@ -55,41 +58,13 @@ void AnchoredSetVariable::set(const std::string &key, void AnchoredSetVariable::set(const std::string &key, - const std::string &value, size_t offset) { + const bpstd::string_view &value, size_t offset) { auto var = std::make_shared(&m_name, &key, &value); VariableOrigin origin; origin.m_offset = offset; origin.m_length = value.size(); - var->addOrigin(std::move(origin)); - emplace(key, std::move(var)); -} - - -void AnchoredSetVariable::set(const std::string &key, - const bpstd::string_view &value, size_t offset) { - std::string v(value.c_str()); - auto var = std::make_shared(&m_name, &key, &v); - - VariableOrigin origin; - origin.m_offset = offset; - origin.m_length = value.size(); - - var->addOrigin(std::move(origin)); - emplace(key, var); -} - - -void AnchoredSetVariable::set(const std::string &key, - const char *value, size_t offset) { - std::string v(value); - auto var = std::make_shared(&m_name, &key, &v); - - VariableOrigin origin; - origin.m_offset = offset; - origin.m_length = strlen(value); - var->addOrigin(std::move(origin)); emplace(key, var); } diff --git a/src/anchored_variable.cc b/src/anchored_variable.cc index e9f43c2d..c700c8e0 100644 --- a/src/anchored_variable.cc +++ b/src/anchored_variable.cc @@ -34,7 +34,8 @@ AnchoredVariable::AnchoredVariable(Transaction *t, m_offset(0), m_name(name), m_value(""), - m_var(std::make_shared(&name)) { + m_var() { + m_var = std::make_shared(&m_name); } void AnchoredVariable::unset() { diff --git a/src/collection/backend/in_memory-per_process.cc b/src/collection/backend/in_memory-per_process.cc index eb15fa5b..9ff9278d 100644 --- a/src/collection/backend/in_memory-per_process.cc +++ b/src/collection/backend/in_memory-per_process.cc @@ -113,7 +113,8 @@ void InMemoryPerProcess::resolveMultiMatches(const std::string& var, if (ke.toOmit(var)) { continue; } - l->insert(l->begin(), std::make_shared(&m_name, &var, &it->second)); + l->insert(l->begin(), std::make_shared(&m_name, &it->first, &it->second)); + } } } diff --git a/src/rule_with_operator.cc b/src/rule_with_operator.cc index e5798318..a1150e68 100644 --- a/src/rule_with_operator.cc +++ b/src/rule_with_operator.cc @@ -81,13 +81,15 @@ RuleWithOperator::~RuleWithOperator() { void RuleWithOperator::updateMatchedVars(Transaction *trans, const VariableValue *v, const bpstd::string_view &value) { - const std::string &key = v->getName(); + // FIXME: Memory leak. + const std::string *key = new std::string(v->getName()); + ms_dbg_a(trans, 9, "Matched vars updated."); trans->m_variableMatchedVar.set(value, trans->m_variableOffset); - trans->m_variableMatchedVarName.set(key, trans->m_variableOffset); + trans->m_variableMatchedVarName.set(*key, trans->m_variableOffset); - trans->m_variableMatchedVars.set(key, value, trans->m_variableOffset); - trans->m_variableMatchedVarsNames.set(key, key, trans->m_variableOffset); + trans->m_variableMatchedVars.set(*key, value, trans->m_variableOffset); + trans->m_variableMatchedVarsNames.set(*key, *key, trans->m_variableOffset); } diff --git a/src/transaction.cc b/src/transaction.cc index af6f3d77..9e768809 100644 --- a/src/transaction.cc +++ b/src/transaction.cc @@ -186,18 +186,7 @@ Transaction::Transaction(ModSecurity *ms, RulesSet *rules, void *logCbData) m_json(NULL), #endif m_secRuleEngine(RulesSetProperties::PropertyNotSetRuleEngine), - m_variableDuration(""), - m_variableEnvs(), - m_variableHighestSeverityAction(""), m_variableRemoteUser(""), - m_variableTime(""), - m_variableTimeDay(""), - m_variableTimeEpoch(""), - m_variableTimeHour(""), - m_variableTimeMin(""), - m_variableTimeSec(""), - m_variableTimeWDay(""), - m_variableTimeYear(""), m_logCbData(logCbData), TransactionAnchoredVariables(this), TransactionRuleMessageManagement(this) { @@ -263,18 +252,7 @@ Transaction::Transaction(ModSecurity *ms, RulesSet *rules, char *id, void *logCb m_json(NULL), #endif m_secRuleEngine(RulesSetProperties::PropertyNotSetRuleEngine), - m_variableDuration(""), - m_variableEnvs(), - m_variableHighestSeverityAction(""), m_variableRemoteUser(""), - m_variableTime(""), - m_variableTimeDay(""), - m_variableTimeEpoch(""), - m_variableTimeHour(""), - m_variableTimeMin(""), - m_variableTimeSec(""), - m_variableTimeWDay(""), - m_variableTimeYear(""), m_logCbData(logCbData), TransactionAnchoredVariables(this), TransactionRuleMessageManagement(this) { diff --git a/src/variables/duration.cc b/src/variables/duration.cc index 8726b6bf..2dd9e1bf 100644 --- a/src/variables/duration.cc +++ b/src/variables/duration.cc @@ -31,9 +31,9 @@ void Duration::evaluate(Transaction *transaction, VariableValues *l) { double e = utils::cpu_seconds() - transaction->m_creationTimeStamp; - transaction->m_variableDuration.assign(std::to_string(e)); - - l->push_back(std::make_shared(&m_retName, &transaction->m_variableDuration)); + l->push_back(std::make_shared( + std::unique_ptr(new std::string(std::to_string(e))), + &m_retName)); } diff --git a/src/variables/env.cc b/src/variables/env.cc index d27d6df8..6ee885c9 100644 --- a/src/variables/env.cc +++ b/src/variables/env.cc @@ -32,28 +32,30 @@ extern char **environ; namespace modsecurity { namespace variables { -void Env::evaluate(Transaction *transaction, - VariableValues *l) { +void Env::evaluate(Transaction *transaction, VariableValues *l) { + bool checkForKey = getVariableKey()->length() > 0; + for (char **current = environ; *current; current++) { std::string env = std::string(*current); size_t pos = env.find_first_of("="); if (pos == std::string::npos) { continue; } - std::string key = std::string(env, 0, pos); - std::string value = std::string(env, pos+1, env.length() - (pos + 1)); - std::pair a(key, value); - transaction->m_variableEnvs.insert(a); - } + std::unique_ptr key(new std::string(env, 0, pos)); + std::unique_ptr value(new std::string(env, pos+1, env.length() - (pos + 1))); - for (auto& x : transaction->m_variableEnvs) { - if (x.first != *getVariableKey() && getVariableKey()->length() > 0) { + if (checkForKey && *key != *getVariableKey()) { continue; } - if (!m_keyExclusion.toOmit(x.first)) { - l->emplace_back(std::make_shared(getVariableKeyWithCollection().get(), - &x.first, &x.second)); + if (m_keyExclusion.toOmit(*key)) { + continue; } + + l->emplace_back(std::make_shared( + std::move(value), + std::move(key), + getVariableKeyWithCollection() + )); } } diff --git a/src/variables/env.h b/src/variables/env.h index ea19fdfc..dc16517a 100644 --- a/src/variables/env.h +++ b/src/variables/env.h @@ -30,11 +30,10 @@ namespace variables { class Env : public Variable { public: - explicit Env(const std::string &_name) - : Variable(_name) { } + explicit Env(const std::string &name) + : Variable(name) { } - void evaluate(Transaction *transaction, - VariableValues *l) override; + void evaluate(Transaction *transaction, VariableValues *l) override; }; } // namespace variables diff --git a/src/variables/highest_severity.cc b/src/variables/highest_severity.cc index f4c9cba6..d1b1c1bd 100644 --- a/src/variables/highest_severity.cc +++ b/src/variables/highest_severity.cc @@ -28,9 +28,9 @@ namespace variables { void HighestSeverity::evaluate(Transaction *transaction, VariableValues *l) { - transaction->m_variableHighestSeverityAction.assign( - std::to_string(transaction->m_highestSeverityAction)); - l->push_back(std::make_shared(getVariableKeyWithCollection().get(), &transaction->m_variableHighestSeverityAction)); + l->push_back(std::make_shared( + std::unique_ptr(new std::string(std::to_string(transaction->m_highestSeverityAction))), + getVariableKeyWithCollection().get())); } diff --git a/src/variables/remote_user.cc b/src/variables/remote_user.cc index bc2b46a2..5a9b9f91 100644 --- a/src/variables/remote_user.cc +++ b/src/variables/remote_user.cc @@ -63,7 +63,7 @@ void RemoteUser::evaluate(Transaction *transaction, } transaction->m_variableRemoteUser.assign(std::string(base64, 0, pos)); - auto var = std::make_shared(&l2[0]->getName(), &transaction->m_variableRemoteUser); + auto var = std::make_shared(&m_retName, &transaction->m_variableRemoteUser); for (auto &i : l2[0]->getOrigin()) { var->addOrigin(i); diff --git a/src/variables/rule.h b/src/variables/rule.h index 78fe5b08..d0384df3 100644 --- a/src/variables/rule.h +++ b/src/variables/rule.h @@ -57,8 +57,7 @@ class Rule_DictElement : public RuleVariable, public VariableDictElement { static void id(Transaction *t, const RuleWithActions *rule, VariableValues *l) { - std::string a = std::to_string(rule->getId()); - auto var = std::make_shared(&m_rule, &m_rule_id, &a); + auto var = std::make_shared(&m_rule, &m_rule_id, std::unique_ptr(new std::string(std::to_string(rule->getId())))); VariableOrigin origin; origin.m_offset = 0; origin.m_length = 0; @@ -73,8 +72,7 @@ class Rule_DictElement : public RuleVariable, public VariableDictElement { VariableValues *l) { if (rule->hasRevisionAction()) { - std::string a(rule->getRevision()); - auto var = std::make_shared(&m_rule, &m_rule_rev, &a); + auto var = std::make_shared(&m_rule, &m_rule_rev, std::unique_ptr(new std::string(rule->getRevision()))); VariableOrigin origin; origin.m_offset = 0; origin.m_length = 0; @@ -90,8 +88,7 @@ class Rule_DictElement : public RuleVariable, public VariableDictElement { VariableValues *l) { if (rule->hasSeverityAction()) { - std::string a(std::to_string(rule->getSeverity())); - auto var = std::make_shared(&m_rule, &m_rule_severity, &a); + auto var = std::make_shared(&m_rule, &m_rule_severity, std::unique_ptr(new std::string(std::to_string(rule->getSeverity())))); VariableOrigin origin; origin.m_offset = 0; origin.m_length = 0; @@ -106,8 +103,7 @@ class Rule_DictElement : public RuleVariable, public VariableDictElement { VariableValues *l) { if (rule->hasLogDataAction()) { - std::string a(rule->getLogData(t)); - auto var = std::make_shared(&m_rule, &m_rule_logdata, &a); + auto var = std::make_shared(&m_rule, &m_rule_logdata, std::unique_ptr(new std::string(rule->getLogData(t)))); VariableOrigin origin; origin.m_offset = 0; origin.m_length = 0; @@ -121,8 +117,7 @@ class Rule_DictElement : public RuleVariable, public VariableDictElement { VariableValues *l) { if (rule->hasMessageAction()) { - std::string a(rule->getMessage(t)); - auto var = std::make_shared(&m_rule, &m_rule_msg, &a); + auto var = std::make_shared(&m_rule, &m_rule_msg, std::unique_ptr(new std::string(rule->getMessage(t)))); VariableOrigin origin; origin.m_offset = 0; origin.m_length = 0; diff --git a/src/variables/time.cc b/src/variables/time.cc index cc11f342..97a75f6d 100644 --- a/src/variables/time.cc +++ b/src/variables/time.cc @@ -46,8 +46,9 @@ void Time::evaluate(Transaction *transaction, localtime_r(&timer, &timeinfo); strftime(tstr, 200, "%H:%M:%S", &timeinfo); - transaction->m_variableTime.assign(tstr); - l->push_back(std::make_shared(&m_retName, &transaction->m_variableTime)); + l->push_back(std::make_shared( + std::unique_ptr(new std::string(tstr)), + &m_retName)); } diff --git a/src/variables/time_day.cc b/src/variables/time_day.cc index 1bc24c27..83271d0c 100644 --- a/src/variables/time_day.cc +++ b/src/variables/time_day.cc @@ -45,9 +45,9 @@ void TimeDay::evaluate(Transaction *transaction, localtime_r(&timer, &timeinfo); strftime(tstr, 200, "%d", &timeinfo); - transaction->m_variableTimeDay.assign(tstr); - - l->push_back(std::make_shared(&m_retName, &transaction->m_variableTimeDay)); + l->push_back(std::make_shared( + std::unique_ptr(new std::string(tstr)), + &m_retName)); } diff --git a/src/variables/time_epoch.cc b/src/variables/time_epoch.cc index 3895b9bf..f8715b9b 100644 --- a/src/variables/time_epoch.cc +++ b/src/variables/time_epoch.cc @@ -35,9 +35,10 @@ namespace variables { void TimeEpoch::evaluate(Transaction *transaction, VariableValues *l) { - transaction->m_variableTimeEpoch.assign( - std::to_string(std::time(nullptr))); - l->push_back(std::make_shared(&m_retName, &transaction->m_variableTimeEpoch)); + + l->push_back(std::make_shared( + std::unique_ptr(new std::string(std::to_string(std::time(nullptr)))), + &m_retName)); } diff --git a/src/variables/time_hour.cc b/src/variables/time_hour.cc index a44ce2a4..61b718cc 100644 --- a/src/variables/time_hour.cc +++ b/src/variables/time_hour.cc @@ -45,9 +45,9 @@ void TimeHour::evaluate(Transaction *transaction, localtime_r(&timer, &timeinfo); strftime(tstr, 200, "%H", &timeinfo); - transaction->m_variableTimeHour.assign(tstr); - - l->push_back(std::make_shared(&m_retName, &transaction->m_variableTimeHour)); + l->push_back(std::make_shared( + std::unique_ptr(new std::string(tstr)), + &m_retName)); } diff --git a/src/variables/time_min.cc b/src/variables/time_min.cc index 67473acb..c6dc12e8 100644 --- a/src/variables/time_min.cc +++ b/src/variables/time_min.cc @@ -45,9 +45,9 @@ void TimeMin::evaluate(Transaction *transaction, localtime_r(&timer, &timeinfo); strftime(tstr, 200, "%M", &timeinfo); - transaction->m_variableTimeMin.assign(tstr); - - l->push_back(std::make_shared(&m_retName, &transaction->m_variableTimeMin)); + l->push_back(std::make_shared( + std::unique_ptr(new std::string(tstr)), + &m_retName)); } diff --git a/src/variables/time_mon.cc b/src/variables/time_mon.cc index 333a9e91..ad222578 100644 --- a/src/variables/time_mon.cc +++ b/src/variables/time_mon.cc @@ -44,12 +44,12 @@ void TimeMon::evaluate(Transaction *transaction, localtime_r(&timer, &timeinfo); strftime(tstr, 200, "%m", &timeinfo); - int a = atoi(tstr); - a--; + //int a = atoi(tstr); + //a--; - transaction->m_variableTimeMin.assign(std::to_string(a)); - - l->push_back(std::make_shared(&m_retName, &transaction->m_variableTimeMin)); + l->push_back(std::make_shared( + std::unique_ptr(new std::string(tstr)), + &m_retName)); } diff --git a/src/variables/time_sec.cc b/src/variables/time_sec.cc index fc37ff01..b944ab94 100644 --- a/src/variables/time_sec.cc +++ b/src/variables/time_sec.cc @@ -45,9 +45,9 @@ void TimeSec::evaluate(Transaction *transaction, localtime_r(&timer, &timeinfo); strftime(tstr, 200, "%S", &timeinfo); - transaction->m_variableTimeSec.assign(tstr); - - l->push_back(std::make_shared(&m_retName, &transaction->m_variableTimeSec)); + l->push_back(std::make_shared( + std::unique_ptr(new std::string(tstr)), + &m_retName)); } diff --git a/src/variables/time_wday.cc b/src/variables/time_wday.cc index 83034598..8ee36a20 100644 --- a/src/variables/time_wday.cc +++ b/src/variables/time_wday.cc @@ -45,9 +45,9 @@ void TimeWDay::evaluate(Transaction *transaction, localtime_r(&timer, &timeinfo); strftime(tstr, 200, "%u", &timeinfo); - transaction->m_variableTimeWDay.assign(tstr); - - l->push_back(std::make_shared(&m_retName, &transaction->m_variableTimeWDay)); + l->push_back(std::make_shared( + std::unique_ptr(new std::string(tstr)), + &m_retName)); } diff --git a/src/variables/time_year.cc b/src/variables/time_year.cc index d1c11597..ed918ba8 100644 --- a/src/variables/time_year.cc +++ b/src/variables/time_year.cc @@ -45,9 +45,9 @@ void TimeYear::evaluate(Transaction *transaction, localtime_r(&timer, &timeinfo); strftime(tstr, 200, "%Y", &timeinfo); - transaction->m_variableTimeYear.assign(tstr); - - l->push_back(std::make_shared(&m_retName, &transaction->m_variableTimeYear)); + l->push_back(std::make_shared( + std::unique_ptr(new std::string(tstr)), + &m_retName)); } diff --git a/src/variables/variable.h b/src/variables/variable.h index 62d49a2f..d4eddc60 100644 --- a/src/variables/variable.h +++ b/src/variables/variable.h @@ -772,8 +772,9 @@ class VariableModificatorCount : public Variable { m_base->evaluate(t, &reslIn); auto count = reslIn.size(); - std::string res(std::to_string(count)); - l->push_back(std::make_shared(getVariableKeyWithCollection().get(), &res)); + l->push_back(std::make_shared( + std::unique_ptr(new std::string(std::to_string(count))), + getVariableKeyWithCollection().get())); return; }