jbeder / yaml-cpp

A YAML parser and emitter in C++
MIT License
5.16k stars 1.86k forks source link

Crash when constructing nodes #688

Open peterchen-cp opened 5 years ago

peterchen-cp commented 5 years ago

I get a crash (access to already-freed memory) in the following sequence:

   Node root(NodeType::Null);
   Node next;
   next.push_back(root);
   Node el = next[0];

   {
      Node assignTo;
      assignTo.push_back(el["a"]);
      assignTo[0] = Node(std::string("1"));
   }

   {
      Node assignTo;
      assignTo.push_back(el["b"]);
      assignTo[0] = Node(std::string("2"));
   }

   Node nb = root["b"];       // doesn't crash, can be omitted

   next.reset();
   el.reset();

   Node nbA = root["a"];      // doesn't crash, can be omitted
   Node nbB = root["b"];      // crashes

(The code as such makes no sense, I get this crash when generating YAML from external data, and this is the smallest sequence I could reduce it to)

Happens with b87c76a2ef and eca9cfd under msvc 15.9.8. I don't have another platform at hand to try.

The call stack for the crash is

>   yaml-path.exe!std::_Ptr_base<YAML::detail::node_data>::get() Zeile 1059 C++
    yaml-path.exe!std::shared_ptr<YAML::detail::node_data>::operator-><YAML::detail::node_data,0>() Zeile 1494  C++
    yaml-path.exe!YAML::detail::node_ref::type() Zeile 25   C++
    yaml-path.exe!YAML::detail::node::type() Zeile 30   C++
    yaml-path.exe!YAML::Node::Type() Zeile 79   C++
    yaml-path.exe!YAML::Node::IsScalar() Zeile 56   C++
    yaml-path.exe!YAML::convert<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >::decode(const YAML::Node & node, std::basic_string<char,std::char_traits<char>,std::allocator<char> > & rhs) Zeile 64    C++
    yaml-path.exe!YAML::detail::node::equals<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & rhs, std::shared_ptr<YAML::detail::memory_holder> pMemory) Zeile 93    C++
    yaml-path.exe!YAML::detail::node_data::get<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & key, std::shared_ptr<YAML::detail::memory_holder> pMemory) Zeile 150 C++
    yaml-path.exe!YAML::detail::node_ref::get<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & key, std::shared_ptr<YAML::detail::memory_holder> pMemory) Zeile 68   C++
    yaml-path.exe!YAML::detail::node::get<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & key, std::shared_ptr<YAML::detail::memory_holder> pMemory) Zeile 129  C++
    yaml-path.exe!YAML::Node::operator[]<char [2]>(const char[2] & key) Zeile 390   C++

node::equals already has an invalid this pointer

jbeder commented 5 years ago

Thanks for the report.