Skip to content

Protect against stack overflow in parser #284

@SirNickolas

Description

@SirNickolas

At the moment, most (if not all) Fluent parsers are implemented with recursive descent. Therefore, they are vulnerable to stack overflow. If a Fluent file comes from an untrusted source, a malicious user can bring the parser down with such resource as a = {{{{{…500 times…{{{{{ (0.5 KB!). The impact varies between different environments: in some, a runtime raises an exception that can be recovered from; in others, the whole process is terminated.

I think, parsing such extremely deeply nested constructs as Junk (even if they are otherwise well-formed) fits Fluent’s recovery strategy well.

Non-recursive parsers are unaffected by this issue, but it seems a good idea if they would impose similiar limits. Although they are able to construct an AST in such pathological cases, it cannot be processed recursively by other parts of the program.

I spotted these cycles in the grammar that need to be taken care of:

  1. inline_placeable → InlineExpression → inline_placeable,
  2. inline_placeable → SelectExpression → InlineExpression → inline_placeable,
  3. InlineExpression → (FunctionReference | TermReference) → CallArguments → argument_list → Argument → InlineExpression,
  4. Pattern → PatternElement → inline_placeable → SelectExpression → variant_list → (Variant | DefaultVariant) → Pattern.

There is also block_placeable, but it’s defined in terms of inline_placeable, so it likely won’t need special handling. Worth mentioning, anyway.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions