Skip to content

perf: linear nested [quote] and nested brackets (was O(n^2) DoS) - #261

Merged
dereuromark merged 1 commit into
masterfrom
fix/bbcode-and-bracket-dos
Jul 8, 2026
Merged

perf: linear nested [quote] and nested brackets (was O(n^2) DoS)#261
dereuromark merged 1 commit into
masterfrom
fix/bbcode-and-bracket-dos

Conversation

@dereuromark

@dereuromark dereuromark commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Two quadratic blowups found by a security audit:

  • BbcodeToDjot::parseQuotesWithDepth recursed on each closed quote's inner content and used an unanchored preg_match per position, so deeply nested [quote] was O(n²) (~19s for 90KB). Now a single stack-based pass, O(n) (~0.05s).
  • Inline parser ran the char-by-char bracket-depth scan for every [ even when the text has no link/span trigger, so a balanced nested run like [[[[x]]]] was O(n²) (~33s at 20k). parseLink now short-circuits on a memoized trigger-presence check (matching carve-php), O(n) (~0.1s).

Output unchanged for well-formed input; regression tests added. Full suite (2699), phpstan, phpcs green.

Two converter/parser quadratic blowups found by a security audit:

- BbcodeToDjot::parseQuotesWithDepth recursed on each closed quote's inner
  content and used unanchored preg_match per position, so deeply nested
  [quote] was O(n^2) (~19s for 90KB). Now a single stack-based pass, O(n).
- The inline parser ran the char-by-char bracket-depth scan for every
  even when the text has no link/span trigger (, , ), so a
  balanced nested run like [[[[x]]]] was O(n^2) (~33s at 20k). parseLink now
  short-circuits on a memoized trigger-presence check (matching carve-php),
  O(n).

Output unchanged; regression tests added.
@dereuromark
dereuromark merged commit f70cf58 into master Jul 8, 2026
4 checks passed
@dereuromark
dereuromark deleted the fix/bbcode-and-bracket-dos branch July 8, 2026 15:41
@codecov

codecov Bot commented Jul 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.37500% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.36%. Comparing base (a50957f) to head (05c1cec).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
src/Converter/BbcodeToDjot.php 80.00% 5 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master     #261      +/-   ##
============================================
- Coverage     92.37%   92.36%   -0.02%     
  Complexity     3637     3637              
============================================
  Files           109      109              
  Lines         10287    10292       +5     
============================================
+ Hits           9503     9506       +3     
- Misses          784      786       +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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