| 121 | } |
| 122 | |
| 123 | bool HasTooManyWrappers(std::span<const uint8_t> buff, const int max_wrappers) |
| 124 | { |
| 125 | // The number of nested wrappers. Nested wrappers are always characters which follow each other so we don't have to |
| 126 | // use a stack as we do above when counting the number of sub-fragments. |
| 127 | std::optional<int> count; |
| 128 | |
| 129 | // We want to detect nested wrappers. A wrapper is a character prepended to a fragment, separated by a colon. There |
| 130 | // may be more than one wrapper, in which case the colon is not repeated. For instance `jjjjj:pk()`. To count |
| 131 | // wrappers we iterate in reverse and use the colon to detect the end of a wrapper expression and count how many |
| 132 | // characters there are since the beginning of the expression. We stop counting when we encounter a character |
| 133 | // indicating the beginning of a new expression. |
| 134 | for (const auto ch: buff | std::views::reverse) { |
| 135 | // A colon, start counting. |
| 136 | if (ch == ':') { |
| 137 | // The colon itself is not a wrapper so we start at 0. |
| 138 | count = 0; |
| 139 | } else if (count) { |
| 140 | // If we are counting wrappers, stop when we crossed the beginning of the wrapper expression. Otherwise keep |
| 141 | // counting and bail if we reached the limit. |
| 142 | // A wrapper may only ever occur as the first sub of a descriptor/miniscript expression ('('), as the |
| 143 | // first Taproot leaf in a pair ('{') or as the nth sub in each case (','). |
| 144 | if (ch == ',' || ch == '(' || ch == '{') { |
| 145 | count.reset(); |
| 146 | } else if (++*count > max_wrappers) { |
| 147 | return true; |
| 148 | } |
| 149 | } |
| 150 | } |
| 151 | |
| 152 | return false; |
| 153 | } |
| 154 | |
| 155 | bool HasTooLargeLeafSize(std::span<const uint8_t> buff, const uint32_t max_leaf_size) |
| 156 | { |
no test coverage detected