/src/trafficserver/lib/yamlcpp/include/yaml-cpp/depthguard.h
Line | Count | Source |
1 | | #ifndef DEPTH_GUARD_H_00000000000000000000000000000000000000000000000000000000 |
2 | | #define DEPTH_GUARD_H_00000000000000000000000000000000000000000000000000000000 |
3 | | |
4 | | #if defined(_MSC_VER) || \ |
5 | | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ |
6 | | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 |
7 | | #pragma once |
8 | | #endif |
9 | | |
10 | | #include "exceptions.h" |
11 | | |
12 | | namespace YAML { |
13 | | |
14 | | /** |
15 | | * @brief The DeepRecursion class |
16 | | * An exception class which is thrown by DepthGuard. Ideally it should be |
17 | | * a member of DepthGuard. However, DepthGuard is a templated class which means |
18 | | * that any catch points would then need to know the template parameters. It is |
19 | | * simpler for clients to not have to know at the catch point what was the |
20 | | * maximum depth. |
21 | | */ |
22 | | class DeepRecursion : public ParserException { |
23 | | public: |
24 | | virtual ~DeepRecursion() = default; |
25 | | |
26 | | DeepRecursion(int depth, const Mark& mark_, const std::string& msg_); |
27 | | |
28 | | // Returns the recursion depth when the exception was thrown |
29 | 0 | int depth() const { |
30 | 0 | return m_depth; |
31 | 0 | } |
32 | | |
33 | | private: |
34 | | int m_depth = 0; |
35 | | }; |
36 | | |
37 | | /** |
38 | | * @brief The DepthGuard class |
39 | | * DepthGuard takes a reference to an integer. It increments the integer upon |
40 | | * construction of DepthGuard and decrements the integer upon destruction. |
41 | | * |
42 | | * If the integer would be incremented past max_depth, then an exception is |
43 | | * thrown. This is ideally geared toward guarding against deep recursion. |
44 | | * |
45 | | * @param max_depth |
46 | | * compile-time configurable maximum depth. |
47 | | */ |
48 | | template <int max_depth = 2000> |
49 | | class DepthGuard final { |
50 | | public: |
51 | 244k | DepthGuard(int & depth_, const Mark& mark_, const std::string& msg_) : m_depth(depth_) { |
52 | 244k | ++m_depth; |
53 | 244k | if ( max_depth <= m_depth ) { |
54 | 68 | throw DeepRecursion{m_depth, mark_, msg_}; |
55 | 68 | } |
56 | 244k | } |
57 | | |
58 | | DepthGuard(const DepthGuard & copy_ctor) = delete; |
59 | | DepthGuard(DepthGuard && move_ctor) = delete; |
60 | | DepthGuard & operator=(const DepthGuard & copy_assign) = delete; |
61 | | DepthGuard & operator=(DepthGuard && move_assign) = delete; |
62 | | |
63 | 244k | ~DepthGuard() { |
64 | 244k | --m_depth; |
65 | 244k | } |
66 | | |
67 | | int current_depth() const { |
68 | | return m_depth; |
69 | | } |
70 | | |
71 | | private: |
72 | | int & m_depth; |
73 | | }; |
74 | | |
75 | | } // namespace YAML |
76 | | |
77 | | #endif // DEPTH_GUARD_H_00000000000000000000000000000000000000000000000000000000 |