Skip to content

A optional depth-limit when parsing policies #2383

Open
john-h-kastner-aws wants to merge 1 commit into
mainfrom
cst-depth-guard
Open

A optional depth-limit when parsing policies #2383
john-h-kastner-aws wants to merge 1 commit into
mainfrom
cst-depth-guard

Conversation

@john-h-kastner-aws

Copy link
Copy Markdown
Contributor

Description of changes

Adds new functions to the public API to configure an optional depth limit for policies when parsing. These function will return an error result for any policy that exceeds the limit, avoiding any possible stack overflow.

As an additional complication, I also had to add a Drop implementation for the CST so that we would not stackoverflow when dropping that structure after returning an error. The drop impl is from Claude. IIUC, Rust will always full free the structure regardless of what we do in our Drop, so there's no risk of memory leaks.

Issue #, if available

Checklist for requesting a review

The change in this PR is (choose one, and delete the other options):

  • A breaking change requiring a major version bump to cedar-policy (e.g., changes to the signature of an existing API).
  • A backwards-compatible change requiring a minor version bump to cedar-policy (e.g., addition of a new API).
  • A bug fix or other functionality change requiring a patch to cedar-policy.
  • A change "invisible" to users (e.g., documentation, changes to "internal" crates like cedar-policy-core, cedar-validator, etc.)
  • A change (breaking or otherwise) that only impacts unreleased or experimental code.

I confirm that this PR (choose one, and delete the other options):

  • Updates the "Unreleased" section of the CHANGELOG with a description of my change (required for major/minor version bumps).
  • Does not update the CHANGELOG because my change does not significantly impact released code.

I confirm that cedar-spec (choose one, and delete the other options):

  • Does not require updates because my change does not impact the Cedar formal model or DRT infrastructure.
  • Requires updates, and I have made / will make these updates myself. (Please include in your description a timeline or link to the relevant PR in cedar-spec, and how you have tested that your updates are correct.)
  • Requires updates, but I do not plan to make them in the near future. (Make sure that your changes are hidden behind a feature flag to mark them as experimental.)
  • I'm not sure how my change impacts cedar-spec. (Post your PR anyways, and we'll discuss in the comments.)

I confirm that docs.cedarpolicy.com (choose one, and delete the other options):

  • Does not require updates because my change does not impact the Cedar language specification.
  • Requires updates, and I have made / will make these updates myself. (Please include in your description a timeline or link to the relevant PR in cedar-docs. PRs should be targeted at a staging-X.Y branch, not main.)
  • I'm not sure how my change impacts the documentation. (Post your PR anyways, and we'll discuss in the comments.)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds depth-limited parsing entry points to the cedar-policy public API to reject policies/expressions that exceed a caller-provided maximum expression depth, reducing the risk of stack overflow from deeply nested inputs. It also introduces iterative CST depth computation and an iterative Drop implementation for CST expressions to avoid stack overflow during cleanup after parse failures.

Changes:

  • Add *_with_depth_limit parsing functions for PolicySet, Policy, Template, and Expression in cedar-policy.
  • Add CST-based “effective depth” computation + depth-limit enforcement in cedar-policy-core parser.
  • Add iterative Drop for CST Expr and add new tests for depth limit + “no stack overflow” scenarios; update changelog.

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
cedar-policy/src/test/test.rs Adds public-API tests covering depth-limit behavior and deep-input stack overflow regression tests
cedar-policy/src/api.rs Exposes new depth-limited parse APIs and refactors PolicySet construction to reuse a helper
cedar-policy/CHANGELOG.md Documents the new depth-limited parsing APIs
cedar-policy-core/src/parser/err.rs Adds a new error kind for “expression too deep”
cedar-policy-core/src/parser/depth.rs Implements iterative CST effective-depth computation + checks (new module)
cedar-policy-core/src/parser/cst.rs Adds Default for CST Node and iterative Drop for CST Expr
cedar-policy-core/src/parser.rs Wires depth-limit checks into new parser entry points and refactors policy-text extraction
cedar-policy-core/Cargo.toml Adds rstest dev-dependency for new parser depth tests
Cargo.lock Updates lockfile for the added dev-dependency version(s)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread cedar-policy/src/api.rs Outdated
Comment thread cedar-policy-core/src/parser/depth.rs
Comment thread cedar-policy-core/Cargo.toml Outdated
Comment thread cedar-policy-core/src/parser.rs Outdated
Comment thread cedar-policy-core/src/parser/cst.rs Outdated
@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown

Coverage Report

Head Commit: 29381cd30124e1f6a7ba297536b856e6b8f2f838

Base Commit: 9fad59997642810634edf0dcfc2fb0e7b1673dac

Download the full coverage report.

Coverage of Added or Modified Lines of Rust Code

Required coverage: 80.00%

Actual coverage: 93.74%

Status: PASSED ✅

Details
File Status Covered Coverage Missed Lines
cedar-policy-core/src/parser.rs 🟢 58/58 100.00%
cedar-policy-core/src/parser/cst.rs 🟢 101/109 92.66% 464, 474, 507, 517, 527, 534, 539, 551
cedar-policy-core/src/parser/depth.rs 🟢 261/286 91.26% 51-53, 62, 76, 81, 85, 88-92, 160, 165, 194, 207, 220, 280, 293, 306, 310, 321, 331, 357, 383
cedar-policy/src/api.rs 🟢 74/74 100.00%

Coverage of All Lines of Rust Code

Required coverage: 80.00%

Actual coverage: 87.90%

Status: PASSED ✅

Details
Package Status Covered Coverage Base Coverage
cedar-language-server 🟢 4722/5102 92.55% 92.55%
cedar-policy 🟢 4541/5665 80.16% 79.93%
cedar-policy-cli 🟡 1230/1621 75.88% 75.88%
cedar-policy-core 🟢 24861/28193 88.18% 88.10%
cedar-policy-formatter 🟢 914/1088 84.01% 84.01%
cedar-policy-symcc 🟢 6777/7274 93.17% 93.17%
cedar-wasm 🔴 0/28 0.00% 0.00%

@cedar-policy cedar-policy deleted a comment from github-actions Bot Jun 4, 2026
Comment thread cedar-policy/src/api.rs
pub fn from_str_with_depth_limit(
policies: &str,
depth_limit: usize,
) -> Result<Self, ParseErrors> {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would users also want to know the depth of the policies they parsed? I guess it's not really useful and we expect them to test parsing with enough depth that it accepts their policies, but doesn't stack overflow.
In terms of API, what does backwards compatibility mean, does it imply if parsing X with depth D suceeds in one version, then it should succeed in a non-breaking version?

@github-actions

Copy link
Copy Markdown

Coverage Report

Head Commit: 2323620cabd6fa682d67fe366f00af63e3fd576a

Base Commit: 1b05ecfc34a9a2405045248971c2f601a92b7478

Download the full coverage report.

Coverage of Added or Modified Lines of Rust Code

Required coverage: 80.00%

Actual coverage: 93.74%

Status: PASSED ✅

Details
File Status Covered Coverage Missed Lines
cedar-policy-core/src/parser.rs 🟢 58/58 100.00%
cedar-policy-core/src/parser/cst.rs 🟢 101/109 92.66% 464, 474, 507, 517, 527, 534, 539, 551
cedar-policy-core/src/parser/depth.rs 🟢 261/286 91.26% 51-53, 62, 76, 81, 85, 88-92, 160, 165, 194, 207, 220, 280, 293, 306, 310, 321, 331, 357, 383
cedar-policy/src/api.rs 🟢 74/74 100.00%

Coverage of All Lines of Rust Code

Required coverage: 80.00%

Actual coverage: 88.02%

Status: PASSED ✅

Details
Package Status Covered Coverage Base Coverage
cedar-language-server 🟢 4722/5102 92.55% --
cedar-policy 🟢 4638/5752 80.63% --
cedar-policy-cli 🟡 1257/1649 76.23% --
cedar-policy-core 🟢 25150/28505 88.23% --
cedar-policy-formatter 🟢 914/1088 84.01% --
cedar-policy-symcc 🟢 6834/7315 93.42% --
cedar-wasm 🔴 0/28 0.00% --

Iteratively compute the depth of the CST prior to converting to AST.
Depth measure accounts for CST nodes Which yield deeper ASTs.  Add
depth-limited variants of the policy/template parsing functions that
reject expressions exceeding a configured limit.

Signed-off-by: John Kastner <jkastner@amazon.com>
@github-actions

Copy link
Copy Markdown

Coverage Report

Head Commit: 87d5d44b7c551bea6c06be9e05f6cd83f4ffddf2

Base Commit: 19b6273cf45bc13c9e3878dd5dca8d5eb63fc42d

Download the full coverage report.

Coverage of Added or Modified Lines of Rust Code

Required coverage: 80.00%

Actual coverage: 93.74%

Status: PASSED ✅

Details
File Status Covered Coverage Missed Lines
cedar-policy-core/src/parser.rs 🟢 58/58 100.00%
cedar-policy-core/src/parser/cst.rs 🟢 101/109 92.66% 464, 474, 507, 517, 527, 534, 539, 551
cedar-policy-core/src/parser/depth.rs 🟢 261/286 91.26% 51-53, 62, 76, 81, 85, 88-92, 160, 165, 194, 207, 220, 280, 293, 306, 310, 321, 331, 357, 383
cedar-policy/src/api.rs 🟢 74/74 100.00%

Coverage of All Lines of Rust Code

Required coverage: 80.00%

Actual coverage: 88.03%

Status: PASSED ✅

Details
Package Status Covered Coverage Base Coverage
cedar-language-server 🟢 4722/5102 92.55% --
cedar-policy 🟢 4645/5752 80.75% --
cedar-policy-cli 🟡 1257/1649 76.23% --
cedar-policy-core 🟢 25148/28503 88.23% --
cedar-policy-formatter 🟢 914/1088 84.01% --
cedar-policy-symcc 🟢 6834/7315 93.42% --
cedar-wasm 🔴 0/28 0.00% --

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants