diff --git a/include/yaml-cpp/depthguard.h b/include/yaml-cpp/depthguard.h index 6aac81a..152cf78 100644 --- a/include/yaml-cpp/depthguard.h +++ b/include/yaml-cpp/depthguard.h @@ -20,16 +20,18 @@ namespace YAML { * maximum depth. */ class DeepRecursion : public ParserException { - int m_atDepth = 0; public: - // no custom dtor needed, but virtual dtor necessary to prevent slicing virtual ~DeepRecursion() = default; - // construct an exception explaining how deep you were DeepRecursion(int at_depth, const Mark& mark_, const std::string& msg_); - // query how deep you were when the exception was thrown - int AtDepth() const; + // Returns the recursion depth when the exception was thrown + int depth() const { + return m_depth; + } + +private: + int m_depth = 0; }; /** @@ -45,7 +47,6 @@ public: */ template class DepthGuard final /* final because non-virtual dtor */ { - int & m_depth; public: DepthGuard(int & depth_, const Mark& mark_, const std::string& msg_) : m_depth(depth_) { ++m_depth; @@ -54,7 +55,6 @@ public: } } - // DepthGuard is neither copyable nor moveable. DepthGuard(const DepthGuard & copy_ctor) = delete; DepthGuard(DepthGuard && move_ctor) = delete; DepthGuard & operator=(const DepthGuard & copy_assign) = delete; @@ -67,6 +67,9 @@ public: int current_depth() const { return m_depth; } + +private: + int & m_depth; }; } // namespace YAML diff --git a/src/depthguard.cpp b/src/depthguard.cpp index 6d47eba..4cfa280 100644 --- a/src/depthguard.cpp +++ b/src/depthguard.cpp @@ -4,11 +4,7 @@ namespace YAML { DeepRecursion::DeepRecursion(int at_depth, const Mark& mark_, const std::string& msg_) : ParserException(mark_, msg_), - m_atDepth(at_depth) { -} - -int DeepRecursion::AtDepth() const { - return m_atDepth; + m_depth(at_depth) { } } // namespace YAML diff --git a/src/singledocparser.cpp b/src/singledocparser.cpp index a433469..3e5638b 100644 --- a/src/singledocparser.cpp +++ b/src/singledocparser.cpp @@ -48,7 +48,7 @@ void SingleDocParser::HandleDocument(EventHandler& eventHandler) { } void SingleDocParser::HandleNode(EventHandler& eventHandler) { - DepthGuard depthguard(depth, m_scanner.mark(), ErrorMsg::BAD_FILE); + DepthGuard<2000> depthguard(depth, m_scanner.mark(), ErrorMsg::BAD_FILE); // an empty node *is* a possibility if (m_scanner.empty()) { diff --git a/src/singledocparser.h b/src/singledocparser.h index 2e1f303..f484eb1 100644 --- a/src/singledocparser.h +++ b/src/singledocparser.h @@ -16,7 +16,6 @@ namespace YAML { class CollectionStack; template class DepthGuard; // depthguard.h -class DeepRecursion; // an exception which may be thrown from excessive call stack recursion, see depthguard.h class EventHandler; class Node; class Scanner; @@ -57,7 +56,6 @@ class SingleDocParser { anchor_t LookupAnchor(const Mark& mark, const std::string& name) const; private: - using DepthGuard = YAML::DepthGuard<2000>; int depth = 0; Scanner& m_scanner; const Directives& m_directives; diff --git a/test/parser_test.cpp b/test/parser_test.cpp index 5f1a090..e5002a4 100644 --- a/test/parser_test.cpp +++ b/test/parser_test.cpp @@ -1,3 +1,4 @@ +#include #include "yaml-cpp/parser.h" #include "yaml-cpp/exceptions.h" #include "mock_event_handler.h" @@ -25,7 +26,7 @@ TEST(ParserTest, CVE_2017_5950) { Parser parser{input}; NiceMock handler; - EXPECT_THROW(parser.HandleNextDocument(handler), YAML::ParserException); + EXPECT_THROW(parser.HandleNextDocument(handler), YAML::DeepRecursion); } TEST(ParserTest, CVE_2018_20573) { @@ -36,7 +37,7 @@ TEST(ParserTest, CVE_2018_20573) { Parser parser{input}; NiceMock handler; - EXPECT_THROW(parser.HandleNextDocument(handler), YAML::ParserException); + EXPECT_THROW(parser.HandleNextDocument(handler), YAML::DeepRecursion); } TEST(ParserTest, CVE_2018_20574) { @@ -47,7 +48,7 @@ TEST(ParserTest, CVE_2018_20574) { Parser parser{input}; NiceMock handler; - EXPECT_THROW(parser.HandleNextDocument(handler), YAML::ParserException); + EXPECT_THROW(parser.HandleNextDocument(handler), YAML::DeepRecursion); } TEST(ParserTest, CVE_2019_6285) { @@ -59,5 +60,5 @@ TEST(ParserTest, CVE_2019_6285) { Parser parser{input}; NiceMock handler; - EXPECT_THROW(parser.HandleNextDocument(handler), YAML::ParserException); + EXPECT_THROW(parser.HandleNextDocument(handler), YAML::DeepRecursion); }