Iteratively count the tokens in the first datum of toks[], rejecting * anything nested deeper than JSON_MAX_NESTING. On success sets *len to the * token count (as json_next(toks) - toks would) and returns true; returns * false without recursing on over-nested, attacker-controlled input. */
| 213 | * token count (as json_next(toks) - toks would) and returns true; returns |
| 214 | * false without recursing on over-nested, attacker-controlled input. */ |
| 215 | static bool bounded_datum_len(const jsmntok_t *toks, size_t *len) |
| 216 | { |
| 217 | /* remaining[d] = child datums still to visit at nesting level d; |
| 218 | * level 0 holds the single root datum. */ |
| 219 | size_t remaining[JSON_MAX_NESTING + 1]; |
| 220 | size_t depth = 0, i = 0; |
| 221 | |
| 222 | remaining[0] = 1; |
| 223 | for (;;) { |
| 224 | /* Ascend out of every level we have finished. */ |
| 225 | while (remaining[depth] == 0) { |
| 226 | if (depth == 0) { |
| 227 | *len = i; |
| 228 | return true; |
| 229 | } |
| 230 | depth--; |
| 231 | } |
| 232 | remaining[depth]--; |
| 233 | |
| 234 | /* Descend into this token's children, if it has any. */ |
| 235 | if (toks[i].size != 0) { |
| 236 | if (depth == JSON_MAX_NESTING) |
| 237 | return false; |
| 238 | remaining[++depth] = toks[i].size; |
| 239 | } |
| 240 | i++; |
| 241 | } |
| 242 | } |
| 243 | |
| 244 | const jsmntok_t *json_get_membern(const char *buffer, |
| 245 | const jsmntok_t tok[], |