From 95bd775238dd834ec5f293a726beb64de10e3708 Mon Sep 17 00:00:00 2001 From: antoshkka Date: Fri, 29 Nov 2024 10:36:24 +0300 Subject: [PATCH] feat core: make sure that labels are not used with integers, leading to memory corruption MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this patch a code like `writer["metric"].ValueWithLabels(value, {{"label_name2", 2}, {"label_name3", "value3"}});` was attempting to create a `LabelView{std::string_view{"label_name2", 2}, std::string_view{"label_name3", "value3"}}`. The second string_view constructor was corrupting memory as it treated "label_name3" and "value3" as two iterators. Tests: протестировано локально commit_hash:e16d3d45a6d3f768611762a4b2fca596aba8d6c8 --- .../userver/utils/statistics/labels.hpp | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/core/include/userver/utils/statistics/labels.hpp b/core/include/userver/utils/statistics/labels.hpp index 23b540eb00ae..893f7dafe44e 100644 --- a/core/include/userver/utils/statistics/labels.hpp +++ b/core/include/userver/utils/statistics/labels.hpp @@ -19,16 +19,21 @@ class LabelView final { LabelView() = default; LabelView(Label&& label) = delete; explicit LabelView(const Label& label) noexcept; - LabelView(std::string_view name, std::string_view value) noexcept : name_(name), value_(value) {} + constexpr LabelView(std::string_view name, std::string_view value) noexcept : name_(name), value_(value) {} - explicit operator bool() const { return !name_.empty(); } + template >* = nullptr> + constexpr LabelView(std::string_view, T) { + static_assert(sizeof(T) && false, "Labels should not be arithmetic values, only strings!"); + } + + constexpr explicit operator bool() const { return !name_.empty(); } - std::string_view Name() const { return name_; } - std::string_view Value() const { return value_; } + constexpr std::string_view Name() const { return name_; } + constexpr std::string_view Value() const { return value_; } private: - std::string_view name_; - std::string_view value_; + std::string_view name_{}; + std::string_view value_{}; }; bool operator<(const LabelView& x, const LabelView& y) noexcept; @@ -41,6 +46,11 @@ class Label final { explicit Label(LabelView view); Label(std::string name, std::string value); + template >* = nullptr> + Label(std::string, T) { + static_assert(sizeof(T) && false, "Labels should not be arithmetic values, only strings!"); + } + explicit operator bool() const { return !name_.empty(); } explicit operator LabelView() const { return {name_, value_}; }