Skip to content

release 0.3.4: cleanup round 1+2 (audit-driven)#25

Merged
siy merged 12 commits into
mainfrom
release-0.3.4
Apr 22, 2026
Merged

release 0.3.4: cleanup round 1+2 (audit-driven)#25
siy merged 12 commits into
mainfrom
release-0.3.4

Conversation

@siy

@siy siy commented Apr 22, 2026

Copy link
Copy Markdown
Owner

Summary

Post-roadmap cleanup release. Two rounds of parallel JBCT review (10 focus-area reviewers + docs-backreference + test-coverage audit, run twice) produced ~150 findings. This release lands the P0 (correctness + security) and P1 (highest-leverage mechanical) fixes. Architectural refactors remain tracked as P3 items in docs/AUDIT-REPORTS/CONSOLIDATED-BACKLOG.md.

Highlights

Fixed (P0)

  • Thread-safety data race in PegEngine — failure caches now ConcurrentHashMap + computeIfAbsent; honors IncrementalParser's documented thread-safety contract.
  • Playground hardening — path-traversal allowlist, 1 MiB body cap, security headers (X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Cache-Control), Locale.ROOT on case conversions.
  • CHANGELOG drift fixes for 0.2.7 / 0.3.2 / 0.3.3 usage snippets.

Changed (P1)

  • Actions#get(String) and Actions#get(Class<? extends RuleId>) now return Option<Action> / Option<Function<...>>. Minor API break — consumer sites migrated.
  • NodeIndex#smallestContaining(int), smallestContainingFrom(...), parentOf(...) return Option<CstNode>.
  • SessionImpl#reparseAt(...) propagates Option<CstNode>; no more fold(cause -> null, ...).
  • Result.failure(cause)cause.result() across ~50 main-source sites.
  • PlaygroundEngine.parseWithRecovery rewritten to use Option directly.
  • Defensive null-checks removed from JsonEncoder + ParseTracer (dead code — sealed hierarchy + by-construction non-null children).

Added (P2)

  • Left-associativity CST shape proof test in LeftRecursionTest.
  • %recover smoke test in RuleRecoveryTest with follow-up note (directive needs deeper wiring audit — P3).
  • docs/AUDIT-REPORTS/ directory with 5 artefacts including CONSOLIDATED-BACKLOG.md enumerating remaining P3 items.

Tests

874 passing + 1 skipped (pre-existing RoundTripTest), 0 failures.

  • peglib-core: 676 (+2)
  • peglib-incremental: 100
  • peglib-formatter: 66
  • peglib-maven-plugin: 5
  • peglib-playground: 27 (+5 adversarial smoke)

Breaking changes

Minor: Actions#get return types shifted to Option. Consumer updates are one-line. Primary public API (PegParser, ParserConfig, Grammar, CstNode, IncrementalParser.initialize/edit) unchanged.

Test plan

  • mvn test at root — 874/874 + 1 skipped
  • mvn install -DskipTests — all modules install
  • Adversarial smoke: path-traversal /.. rejected with 400; 2 MB POST rejected with 413

Summary by CodeRabbit

  • Security Enhancements

    • Playground server now rejects oversized parse requests (1 MiB), blocks path-traversal, and adds security headers; locale handling hardened.
  • API Improvements

    • Public lookup/navigation methods now return an explicit Option wrapper instead of nullable values.
  • Bug Fixes

    • Fixed concurrency issue in parser caches; standardized error/result propagation.
  • Testing & Documentation

    • Added tests for left-recursive parsing, recovery, and playground behavior; new audit and coverage reports.

@coderabbitai

coderabbitai Bot commented Apr 22, 2026

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 87c4bd36-272b-491a-83c9-16f6e7dee4ec

📥 Commits

Reviewing files that changed from the base of the PR and between e2d0f0e and 4c83e9f.

📒 Files selected for processing (4)
  • peglib-core/src/main/java/org/pragmatica/peg/action/ActionCompiler.java
  • peglib-core/src/main/java/org/pragmatica/peg/grammar/GrammarParser.java
  • peglib-core/src/main/java/org/pragmatica/peg/grammar/GrammarResolver.java
  • peglib-core/src/main/java/org/pragmatica/peg/parser/ParsingContext.java

📝 Walkthrough

Walkthrough

Release 0.3.4 is a cleanup build that standardizes APIs from null/Optional to Pragmatica Option, fixes cache concurrency by switching PegEngine's failure-message caches to ConcurrentHashMap, hardens the playground server against path traversal and oversized requests, replaces Result.failure(...) patterns with cause.result(), and adds targeted tests plus comprehensive audit documentation.

Changes

Cohort / File(s) Summary
API Migration to Pragmatica Option
peglib-core/.../Actions.java, peglib-core/.../ParsingContext.java, peglib-core/.../FirstCharAnalysis.java, peglib-core/.../ParserGenerator.java, peglib-incremental/.../NodeIndex.java, peglib-incremental/.../SessionImpl.java
Public/internal methods refactored to return Option<T> instead of nullable T or java.util.Optional<T>. Callers updated to use .isPresent(), .unwrap() and combinators (.map(), .or(), .filter()).
Error Handling Standardization
peglib-core/.../ActionCompiler.java, peglib-core/.../Grammar.java, peglib-core/.../GrammarParser.java, peglib-core/.../GrammarResolver.java, peglib-core/.../PegEngine.java
Replaced Result.failure(new ParseError(...)) with new ParseError(...).result() and replaced Result.failure(f.cause()) with f.cause().result() to unify error-result construction/propagation.
Playground Server Security Hardening
peglib-playground/.../PlaygroundServer.java, peglib-playground/.../internal/JsonEncoder.java, peglib-playground/.../PlaygroundRepl.java, peglib-playground/.../PlaygroundEngine.java, peglib-playground/.../test/PlaygroundServerTest.java
Added path normalization/sanitization for static assets (sanitizeStaticPath), capped POST /parse request body to 1 MiB with HTTP 413 rejection, applied security headers to responses, replaced locale-sensitive case ops with Locale.ROOT, and removed null-guards in JSON/tracer relying on non-null CSTs; tests added for sanitization, headers, and body-size enforcement.
Concurrency & Cache Improvements
peglib-core/.../PegEngine.java
Switched per-engine failure-message caches (literalFailureMessageCache, charClassFailureMessageCache) from HashMap to ConcurrentHashMap and use computeIfAbsent(...) for atomic population; adjusted whitespace-first-char cache to Option.
Tests & Parser Proofs
peglib-core/.../test/ActionsImmutabilityTest.java, peglib-core/.../test/RuleRecoveryTest.java, peglib-core/.../test/LeftRecursionTest.java
Updated tests to match Option-returning APIs; added left-recursion CST shape test and a recovery-scope test (with TODO noting expected diagnostic differences).
Generator / First-Char Analysis
peglib-core/.../FirstCharAnalysis.java, peglib-core/.../ParserGenerator.java
Switched whitespaceFirstChars(...) from Optional to Option, updated generated whitespace fast-path code to use Option APIs.
Build & Docs Version Bumps
pom.xml, peglib-core/pom.xml, peglib-incremental/pom.xml, peglib-formatter/pom.xml, peglib-maven-plugin/pom.xml, peglib-playground/pom.xml, README.md
Bumped parent/module versions from 0.3.3→0.3.4 and updated README Maven snippets.
Audit & Documentation
CHANGELOG.md, docs/AUDIT-REPORTS/CONSOLIDATED-BACKLOG.md, docs/AUDIT-REPORTS/docs-backreference.md, docs/AUDIT-REPORTS/docs-fixups-needed.md, docs/AUDIT-REPORTS/test-coverage-proof.md, docs/AUDIT-REPORTS/tests-fixups-needed.md
Added changelog entry for 0.3.4 and multiple audit reports documenting applied fixes, gaps, test-proof recommendations, and a deferred backlog.
Minor refactors / formatting
peglib-core/.../ActionCompiler.java, other internal files
Small refactors: simplified action/compiler error returns, removed defensive null-checks where invariants guarantee non-null, and formatting tweaks.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant PlaygroundServer
  participant Parser
  participant StaticAssets

  Client->>PlaygroundServer: POST /parse (body <= 1MiB?)
  alt body > 1MiB
    PlaygroundServer-->>Client: 413 Payload Too Large + JSON error (with security headers)
  else body <= 1MiB
    PlaygroundServer->>Parser: parseCstWithDiagnostics(input, startRule?)
    Parser-->>PlaygroundServer: ParseResult (CST or diagnostics)
    PlaygroundServer-->>Client: 200/4xx JSON response (with security headers)
  end

  Client->>PlaygroundServer: GET /{path}
  PlaygroundServer->>PlaygroundServer: sanitizeStaticPath(path)
  alt path invalid or traversal
    PlaygroundServer-->>Client: 400/404 (with security headers)
  else valid
    PlaygroundServer->>StaticAssets: load resource
    StaticAssets-->>PlaygroundServer: resource bytes / 404
    PlaygroundServer-->>Client: 200/404 response (with security headers)
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 A hop through Option's sunny glade,
null's shadow chased, caches strong and staid.
Servers vet the path and trim the byte,
Parsers hum left-leaning trees at night—
0.3.4 hops in, tidy and well-played. 🌷

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main objective: a cleanup release (0.3.4) addressing audit findings from two rounds of review. It accurately reflects the significant refactoring and fixes documented in the PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch release-0.3.4

Comment @coderabbitai help to get the list of available commands and usage tips.

@siy siy merged commit 74de0d9 into main Apr 22, 2026
1 check passed
@siy siy deleted the release-0.3.4 branch April 22, 2026 06:52
This was referenced May 8, 2026
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.

1 participant