Fix seg fault on shutdown
Use unique_ptr correctly to avoid seg faults from double freed objects.
Fixes the seg fault on shutdown that we've been seeing for a while.
Change-Id: I4372c3bf727d5cdd870805b3ecba7f446c9a1985
diff --git a/crow/include/crow/routing.h b/crow/include/crow/routing.h
index 32a580d..30bb845 100644
--- a/crow/include/crow/routing.h
+++ b/crow/include/crow/routing.h
@@ -237,8 +237,8 @@
handler_, params, req, res});
}
};
-}
-}
+} // namespace routing_handler_call_helper
+} // namespace detail
class WebSocketRule : public BaseRule {
using self_t = WebSocketRule;
@@ -792,11 +792,12 @@
Router() : rules_(2) {}
DynamicRule& new_rule_dynamic(const std::string& rule) {
- auto ruleObject = new DynamicRule(rule);
+ std::unique_ptr<DynamicRule> ruleObject =
+ std::make_unique<DynamicRule>(rule);
+ DynamicRule* ptr = ruleObject.get();
+ internal_add_rule_object(rule, std::move(ruleObject));
- internal_add_rule_object(rule, ruleObject);
-
- return *ruleObject;
+ return *ptr;
}
template <uint64_t N>
@@ -804,25 +805,22 @@
new_rule_tagged(const std::string& rule) {
using RuleT =
typename black_magic::arguments<N>::type::template rebind<TaggedRule>;
- auto ruleObject = new RuleT(rule);
+ std::unique_ptr<RuleT> ruleObject = std::make_unique<RuleT>(rule);
+ RuleT* ptr = ruleObject.get();
+ internal_add_rule_object(rule, std::move(ruleObject));
- internal_add_rule_object(rule, ruleObject);
-
- return *ruleObject;
+ return *ptr;
}
- void internal_add_rule_object(const std::string& rule, BaseRule* ruleObject) {
- rules_.emplace_back(ruleObject);
+ void internal_add_rule_object(const std::string& rule,
+ std::unique_ptr<BaseRule> ruleObject) {
+ rules_.emplace_back(std::move(ruleObject));
trie_.add(rule, rules_.size() - 1);
// directory case:
// request to `/about' url matches `/about/' rule
- if (rule.size() > 1 && rule.back() == '/') {
- std::string rule_without_trailing_slash = rule;
- rule_without_trailing_slash.pop_back();
- rules_.emplace_back(ruleObject);
- trie_.add(rule_without_trailing_slash, rules_.size() - 1);
- // trie_.add(rule_without_trailing_slash, RULE_SPECIAL_REDIRECT_SLASH);
+ if (rule.size() > 2 && rule.back() == '/') {
+ trie_.add(rule.substr(0, rule.size() - 1), rules_.size() - 1);
}
}
@@ -924,9 +922,9 @@
if (req.get_header_value("Host").empty()) {
res.add_header("Location", req.url + "/");
} else {
- res.add_header("Location",
- (req.is_secure ? "https://" : "http://") +
- req.get_header_value("Host") + req.url + "/");
+ res.add_header("Location", (req.is_secure ? "https://" : "http://") +
+ req.get_header_value("Host") + req.url +
+ "/");
}
res.end();
return;
@@ -980,4 +978,4 @@
std::vector<std::unique_ptr<BaseRule>> rules_;
Trie trie_;
};
-}
+} // namespace crow