#ifndef DEPTH_GUARD_H_00000000000000000000000000000000000000000000000000000000 #define DEPTH_GUARD_H_00000000000000000000000000000000000000000000000000000000 #if defined(_MSC_VER) || \ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #pragma once #endif #include "exceptions.h" namespace YAML { /** * @brief The DeepRecursion class * An exception class which is thrown by DepthGuard. Ideally it should be * a member of DepthGuard. However, DepthGuard is a templated class which means * that any catch points would then need to know the template parameters. It is * simpler for clients to not have to know at the catch point what was the * maximum depth. */ class DeepRecursion : public ParserException { public: virtual ~DeepRecursion() = default; DeepRecursion(int depth, const Mark& mark_, const std::string& msg_); // Returns the recursion depth when the exception was thrown int depth() const { return m_depth; } private: int m_depth = 0; }; /** * @brief The DepthGuard class * DepthGuard takes a reference to an integer. It increments the integer upon * construction of DepthGuard and decrements the integer upon destruction. * * If the integer would be incremented past max_depth, then an exception is * thrown. This is ideally geared toward guarding against deep recursion. * * @param max_depth * compile-time configurable maximum depth. */ template class DepthGuard final { public: DepthGuard(int & depth_, const Mark& mark_, const std::string& msg_) : m_depth(depth_) { ++m_depth; if ( max_depth <= m_depth ) { throw DeepRecursion{m_depth, mark_, msg_}; } } DepthGuard(const DepthGuard & copy_ctor) = delete; DepthGuard(DepthGuard && move_ctor) = delete; DepthGuard & operator=(const DepthGuard & copy_assign) = delete; DepthGuard & operator=(DepthGuard && move_assign) = delete; ~DepthGuard() { --m_depth; } int current_depth() const { return m_depth; } private: int & m_depth; }; } // namespace YAML #endif // DEPTH_GUARD_H_00000000000000000000000000000000000000000000000000000000