1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- #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 <int max_depth = 2000>
- 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
|