Skip to content

Circular CSS custom properties cause a process-fatal stack overflow during computed style resolution #241

Description

@sebastienros

Summary

Computing a style that references circular CSS custom properties causes an uncatchable native stack overflow and terminates the host process. This reproduces using AngleSharp only, without a JavaScript engine or browser adapter.

Confirmed with AngleSharp 1.7.2, AngleSharp.Css 1.0.2, .NET 10.0.11, macOS arm64. The standalone program below exits with code 134.

Duplicate search

I searched open and closed issues for circular references, cycles, recursion, stack overflow, custom properties, and var. Related closed reports are #62 (adding variable resolution), #171 (variables in shorthand properties), and #184 (inheritance); their descriptions and comments do not cover cycle-induced process termination.

Reproduction

Create a console project:

dotnet new console -n CssCycleRepro -f net10.0
cd CssCycleRepro
dotnet add package AngleSharp --version 1.7.2
dotnet add package AngleSharp.Css --version 1.0.2

Replace Program.cs with:

using AngleSharp;
using AngleSharp.Css;
using AngleSharp.Dom;

using var context = BrowsingContext.New(Configuration.Default.WithCss());
using var document = await context.OpenAsync(response => response.Content(
    """
    <!doctype html>
    <style>
      :root { --a: var(--b); --b: var(--a); }
      button { color: var(--a); }
    </style>
    <button>Save</button>
    """));

Console.WriteLine(document.QuerySelector("button")!.ComputeCurrentStyle().GetPropertyValue("color"));

Run in a separate process, because the failure terminates it:

dotnet run -c Release

Actual result

Stack overflow. followed by repeating frames:

AngleSharp.Css.Values.CssComputeContext.Resolve(System.String)
AngleSharp.Css.Dom.CssProperty+PropertyComputeContext.Resolve(System.String)
AngleSharp.Css.Values.CssVarValue.Compute(ICssComputeContext)
AngleSharp.Css.Values.CssReferenceValue.ICssValue.Compute(ICssComputeContext)
AngleSharp.Css.Values.CssVarValue.Compute(ICssComputeContext)
AngleSharp.Css.Values.CssReferenceValue.ICssValue.Compute(ICssComputeContext)
...

The process exits with code 134 rather than returning a computed style or a catchable exception.

Expected result

Per CSS Variables §2.3: Resolving Dependency Cycles, each custom property in the cycle becomes guaranteed-invalid. A consuming var(--a, red) should use its fallback; without a fallback the consuming declaration is invalid at computed-value time. Neither should terminate the host.

Relevant regression cases include --a:var(--a), multi-variable cycles, cycles with internal fallback values, edges in unused fallbacks such as --a:var(--present,var(--a)), and inheritance of already-resolved custom properties. A dependent property outside a cycle may recover with its own fallback, so marking all dependencies invalid is not sufficient.

Impact / downstream context

Found while embedding AngleSharp.Css in Jint.Browser: sebastienros/jint#3851. A page's computed style, geometry, or accessibility query can terminate the entire shared browser process. try/catch is not a workaround for StackOverflowException; cycle handling has to occur before recursive value computation.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions