aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorinnokentii <innokentii@yandex-team.com>2023-03-23 17:02:27 +0300
committerinnokentii <innokentii@yandex-team.com>2023-03-23 17:02:27 +0300
commit1b63dc868aaa1066fd2f723f739ea086a2a49601 (patch)
treef317d82984b0facf4a5d81720e5bb54cf9a124d4
parent8007028c9d3043fe9909990721048e49127eeeec (diff)
downloadydb-1b63dc868aaa1066fd2f723f739ea086a2a49601.tar.gz
Fix leaks on fyamlcpp misuse
fix possible leaks on misuse
-rw-r--r--library/cpp/yaml/fyamlcpp/fyamlcpp.cpp22
-rw-r--r--library/cpp/yaml/fyamlcpp/fyamlcpp.h8
-rw-r--r--library/cpp/yaml/fyamlcpp/fyamlcpp_ut.cpp67
3 files changed, 81 insertions, 16 deletions
diff --git a/library/cpp/yaml/fyamlcpp/fyamlcpp.cpp b/library/cpp/yaml/fyamlcpp/fyamlcpp.cpp
index 9ab1465dfe..b8d8b17596 100644
--- a/library/cpp/yaml/fyamlcpp/fyamlcpp.cpp
+++ b/library/cpp/yaml/fyamlcpp/fyamlcpp.cpp
@@ -11,14 +11,6 @@ namespace NFyaml {
const char* zstr = "";
-struct TStringHashT {
- size_t operator()(const TString& str) const {
- auto* ptr = str.empty() ? zstr : &str[0];
- return MurmurHash<size_t>(reinterpret_cast<char*>(&ptr), sizeof(ptr));
- }
-};
-
-
enum class EErrorType {
Debug = FYET_DEBUG,
Info = FYET_INFO,
@@ -295,8 +287,8 @@ TNode TNodeRef::Copy() const {
TNode TNodeRef::Copy(TDocument& to) const {
ENSURE_NODE_NOT_EMPTY(Node_);
auto* fromDoc = fy_node_document(Node_);
- auto& fromUserdata = *reinterpret_cast<THashSet<TString, TStringHashT>*>(fy_document_get_userdata(fromDoc));
- auto& toUserdata = *reinterpret_cast<THashSet<TString, TStringHashT>*>(fy_document_get_userdata(to.Document_.get()));
+ auto& fromUserdata = *reinterpret_cast<THashSet<TSimpleSharedPtr<TString>, TStringPtrHashT>*>(fy_document_get_userdata(fromDoc));
+ auto& toUserdata = *reinterpret_cast<THashSet<TSimpleSharedPtr<TString>, TStringPtrHashT>*>(fy_document_get_userdata(to.Document_.get()));
toUserdata.insert(fromUserdata.begin(), fromUserdata.end());
return TNode(fy_node_copy(to.Document_.get(), Node_));
}
@@ -714,7 +706,7 @@ TDocument::TDocument(TString str, fy_document* doc, fy_diag* diag)
: Document_(doc, fy_document_destroy)
, Diag_(diag, fy_diag_destroy)
{
- auto* userdata = new THashSet<TString, TStringHashT>({str});
+ auto* userdata = new THashSet<TSimpleSharedPtr<TString>, TStringPtrHashT>({MakeSimpleShared<TString>(std::move(str))});
fy_document_set_userdata(doc, userdata);
fy_document_register_on_destroy(doc, &DestroyDocumentStrings);
RegisterUserDataCleanup();
@@ -729,7 +721,7 @@ TDocument::TDocument(fy_document* doc, fy_diag* diag)
TDocument TDocument::Parse(TString str) {
- auto* cstr = str.empty() ? zstr : &str[0];
+ const char* cstr = str.empty() ? zstr : str.cbegin();
fy_diag_cfg dcfg;
fy_diag_cfg_default(&dcfg);
std::unique_ptr<fy_diag, void(*)(fy_diag*)> diag(fy_diag_create(&dcfg), fy_diag_destroy);
@@ -757,8 +749,8 @@ TDocument TDocument::Clone() const {
fy_document* doc = fy_document_clone(Document_.get());
fy_document_set_userdata(
doc,
- new THashSet<TString, TStringHashT>(
- *reinterpret_cast<THashSet<TString, TStringHashT>*>(fy_document_get_userdata(Document_.get()))
+ new THashSet<TSimpleSharedPtr<TString>, TStringPtrHashT>(
+ *reinterpret_cast<THashSet<TSimpleSharedPtr<TString>, TStringPtrHashT>*>(fy_document_get_userdata(Document_.get()))
)
);
fy_document_register_on_destroy(doc, &DestroyDocumentStrings);
@@ -879,7 +871,7 @@ TParser::TParser(TString rawStream, fy_parser* parser, fy_diag* diag)
TParser TParser::Create(TString str)
{
- auto* stream = str.empty() ? zstr : &str[0];
+ const char* stream = str.empty() ? zstr : str.cbegin();
fy_diag_cfg dcfg;
fy_diag_cfg_default(&dcfg);
std::unique_ptr<fy_diag, void(*)(fy_diag*)> diag(fy_diag_create(&dcfg), fy_diag_destroy);
diff --git a/library/cpp/yaml/fyamlcpp/fyamlcpp.h b/library/cpp/yaml/fyamlcpp/fyamlcpp.h
index c1ec03d25f..bcf9362d73 100644
--- a/library/cpp/yaml/fyamlcpp/fyamlcpp.h
+++ b/library/cpp/yaml/fyamlcpp/fyamlcpp.h
@@ -18,6 +18,12 @@ struct fy_node_pair;
namespace NFyaml {
+struct TStringPtrHashT {
+ size_t operator()(const TSimpleSharedPtr<TString>& str) const {
+ return (size_t)str.Get();
+ }
+};
+
struct TFyamlEx : public yexception {};
enum class ENodeType {
@@ -589,7 +595,7 @@ private:
static void DestroyDocumentStrings(fy_document *fyd, void *user) {
Y_UNUSED(fyd);
if (user) {
- auto* data = reinterpret_cast<THashSet<TString>*>(user);
+ auto* data = reinterpret_cast<THashSet<TSimpleSharedPtr<TString>, TStringPtrHashT>*>(user);
delete data;
}
}
diff --git a/library/cpp/yaml/fyamlcpp/fyamlcpp_ut.cpp b/library/cpp/yaml/fyamlcpp/fyamlcpp_ut.cpp
index 94093c4157..ffe1d4368c 100644
--- a/library/cpp/yaml/fyamlcpp/fyamlcpp_ut.cpp
+++ b/library/cpp/yaml/fyamlcpp/fyamlcpp_ut.cpp
@@ -86,4 +86,71 @@ test: b
auto docOpt3 = parser.NextDocument();
UNIT_ASSERT(!docOpt3);
}
+
+ Y_UNIT_TEST(Leak) {
+ std::optional<NFyaml::TDocument> doc;
+
+ {
+ std::optional<NFyaml::TDocument> item1;
+ std::optional<NFyaml::TDocument> item2;
+ {
+ const TString items = R"(
+item:
+ x: 1
+ y: 2
+---
+test:
+ a: noop
+ b:
+ - 1
+ - 2
+ - 3
+---
+x: b
+)";
+ auto parser = NFyaml::TParser::Create(items);
+
+ item1.emplace(*parser.NextDocument());
+ item2.emplace(*parser.NextDocument());
+ parser.NextDocument();
+ parser.NextDocument();
+ }
+
+ {
+ const TString config = R"(
+test: a
+---
+test: []
+---
+x: b
+)";
+ auto parser = NFyaml::TParser::Create(config);
+
+ parser.NextDocument();
+ doc.emplace(*parser.NextDocument());
+ parser.NextDocument();
+ parser.NextDocument();
+ }
+
+ {
+ auto item1NodeRef = item1->Root().Map().at("item");
+ auto item2NodeRef = item2->Root().Map().at("test");
+ auto docNodeRef = doc->Root().Map().at("test");
+ auto node1 = item1NodeRef.Copy(*doc);
+ auto node2 = item2NodeRef.Copy(*doc);
+ docNodeRef.Sequence().Append(node1.Ref());
+ docNodeRef.Sequence().Append(node2.Ref());
+ item1.reset();
+ item2.reset();
+ }
+ }
+
+ auto seq = doc->Root().Map().at("test").Sequence();
+ UNIT_ASSERT_VALUES_EQUAL(seq[0].Map().at("x").Scalar(), "1");
+ UNIT_ASSERT_VALUES_EQUAL(seq[0].Map().at("y").Scalar(), "2");
+ UNIT_ASSERT_VALUES_EQUAL(seq[1].Map().at("a").Scalar(), "noop");
+ UNIT_ASSERT_VALUES_EQUAL(seq[1].Map().at("b").Sequence().at(0).Scalar(), "1");
+ UNIT_ASSERT_VALUES_EQUAL(seq[1].Map().at("b").Sequence().at(1).Scalar(), "2");
+ UNIT_ASSERT_VALUES_EQUAL(seq[1].Map().at("b").Sequence().at(2).Scalar(), "3");
+ }
}