| 97 | } |
| 98 | |
| 99 | bool HasTooManySubFrag(std::span<const uint8_t> buff, const int max_subs, const size_t max_nested_subs) |
| 100 | { |
| 101 | // We use a stack because there may be many nested sub-frags. |
| 102 | std::stack<int> counts; |
| 103 | for (const auto& ch: buff) { |
| 104 | // The fuzzer may generate an input with a ton of parentheses. Rule out pathological cases. |
| 105 | if (counts.size() > max_nested_subs) return true; |
| 106 | |
| 107 | if (ch == '(') { |
| 108 | // A new fragment was opened, create a new sub-count for it and start as one since any fragment with |
| 109 | // parentheses has at least one sub. |
| 110 | counts.push(1); |
| 111 | } else if (ch == ',' && !counts.empty()) { |
| 112 | // When encountering a comma, account for an additional sub in the last opened fragment. If it exceeds the |
| 113 | // limit, bail. |
| 114 | if (++counts.top() > max_subs) return true; |
| 115 | } else if (ch == ')' && !counts.empty()) { |
| 116 | // Fragment closed! Drop its sub count and resume to counting the number of subs for its parent. |
| 117 | counts.pop(); |
| 118 | } |
| 119 | } |
| 120 | return false; |
| 121 | } |
| 122 | |
| 123 | bool HasTooManyWrappers(std::span<const uint8_t> buff, const int max_wrappers) |
| 124 | { |
no test coverage detected