scan_depth_complexity

Function scan_depth_complexity 

Source
pub fn scan_depth_complexity(
    query: &str,
    _depth_limit: usize,
    cost_per_field: &HashMap<String, u64>,
    complexity_coefficient: u64,
) -> (usize, u64)
Expand description

Scan a GraphQL query string for depth and complexity. This is a bounded hand-rolled scanner – it does NOT fully parse GraphQL. It counts:

  • Depth: the maximum brace-nesting level. { and ( increase depth; } and ) decrease it. The top-level operation body is depth 1 (the first {). Strings and comments are skipped so braces inside string literals or descriptions do not affect the count.
  • Complexity: the sum of per-field costs. A “field” is an identifier that appears in a selection position – heuristically, an identifier followed by optional arguments (...) and/or a sub-selection {...}. Each field’s cost is cost_per_field[name] if present, else complexity_coefficient.

The scanner is bounded by PARSE_DEPTH_CAP: if the brace nesting exceeds it, the scan aborts and returns a depth of PARSE_DEPTH_CAP + 1 (which will exceed any reasonable depth_limit, failing the check closed).

This is intentionally conservative: it may over-count fields in edge cases (e.g. fragments, directives, aliases) but never under-count depth. Over-counting complexity fails closed (a legitimate query slightly over the limit is denied, which the operator can fix by raising the limit); under-counting would fail open (an abusive query slips through), which is the worse failure mode for a security control.