Codeinwp / Codeinwp/otter-blocks
Single-quoted postContent dynamic tags can exhaust PHP memory
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 198
- Forks
- 36
- Avg merge
- 3d 4h
- Merged PRs (30d)
- 30
Description
Summary
A nested Dynamic Content tag using a single-quoted postContent type can recursively render page content until PHP exhausts its memory limit.
Expected behavior: Nested postContent Dynamic Content tags are detected and resolved safely without recursive rendering.
Actual behavior: The frontend request can repeatedly render the same content and terminate with an allowed-memory-size fatal error.
Impact: Affected pages can fail to render for visitors under the configured PHP memory limit.
Customer context
- Product / area: Otter Blocks Dynamic Content, frontend rendering
- Version: Telemetry observed versions 3.2.2 and 3.2.3
- Environment: WordPress 7.1; PHP 8.3.33; 128 MB PHP memory limit
- Reported error / symptom:
Allowed memory size of 134217728 bytes exhausted (tried to allocate 32768 bytes) - Impact: 2 fatal-error occurrences across 2 distinct production sites from 2026-08-19 through 2026-08-21.
Reproduction notes
- Create or filter post content so it contains a nested Dynamic Content tag with
data-type='postContent'. - Render a frontend page that resolves that Dynamic Content value.
- The current guard does not recognize the single-quoted nested tag, and repeated content rendering can continue until the PHP memory limit is exhausted.
The exact production markup is unavailable; this reproduction follows the parser-accepted syntax and inspected frontend call path.
Diagnosis
Conclusion
The production fatal points to Dynamic_Content::get_exception_key() while dynamic content is being evaluated. Source inspection confirms a parser/guard mismatch: Dynamic_Content::dynamic_content_regex() accepts both single- and double-quoted data-type values, but Dynamic_Content::mark_exceptions() looks only for the literal double-quoted data-type="postContent". A nested parser-valid single-quoted postContent tag therefore remains unmarked, after which Dynamic_Content::get_content() applies the_content to that post content again. This is a concrete recursive-rendering path consistent with the shutdown-detected memory exhaustion.
Where this likely occurs
inc/plugins/class-dynamic-content.php—Dynamic_Content::dynamic_content_regex()lines 93-107 acceptsdata-typevalues delimited by either quote style.inc/plugins/class-dynamic-content.php—Dynamic_Content::get_data()lines 443-472 routespostContenttags toDynamic_Content::get_content().inc/plugins/class-dynamic-content.php—Dynamic_Content::get_content()lines 540-550 builds the exception key, then appliesthe_contentto retrieved post content.inc/plugins/class-dynamic-content.php—Dynamic_Content::mark_exceptions()lines 898-912 detects nested tags through the double-quote-specific literaldata-type="postContent".inc/plugins/class-dynamic-content.php—Dynamic_Content::get_exception_key()lines 943-952 is the telemetry location; it is repeatedly reached during the inferred recursive path.v3.2.3contains commitf6a47092eca8a8b3e83c98220b90c507341ebf1b(release: fixes), which corrected context selection for this feature but retained the quote-specific guard condition. Telemetry includes 3.2.3 after that release.
Engineering notes
The inspected path is frontend render_block processing: Dynamic_Content::init() registers apply_dynamic_content() on that filter at inc/plugins/class-dynamic-content.php lines 25-32. The loop guard is intended to identify a postContent tag inside the source post before the_content triggers nested block rendering. The failure depends on markup reaching this parser with single-quoted attributes; the report does not include the affected page content, so this exact markup is an evidence-backed reproduction path rather than a confirmed production payload.
The crash is in Otter code, not the bundled Themeisle SDK, and no companion repository is implicated by the supplied telemetry.
Test coverage status
tests/test-dynamic-content.php lines 1171-1221 includes TestDynamicContent::test_post_content_guard_detects_nested_tag_in_context_post, covering the intended recursion guard with a double-quoted tag. No relevant coverage for single-quoted postContent markup was found during inspection. The existing long-content test at lines 710-720 exercises repeated replacements but not recursive postContent rendering.
What to verify or explore next
- Reproduce frontend rendering of a post whose content contains a nested
<o-dynamic data-type='postContent'>…</o-dynamic>tag. - Run the Dynamic Content PHPUnit suite with a single-quoted nested-tag case under a bounded PHP memory limit.
- Check whether block serialization, content migrations, or third-party content filters can emit the single-quoted form in supported editor workflows.
Unknowns / follow-up
- No structured stack trace or affected post markup was captured by telemetry.
- The available evidence does not establish how the two affected sites produced the parser-valid single-quoted markup or whether additional malformed/nested markup variants reach the same recursive path.
Confidence
Confidence: 88/100
The fatal occurs in Otter's recursion-guard path, and source inspection shows that the dynamic-content parser accepts single-quoted attributes while the guard only recognizes a double-quoted postContent attribute. This leaves a parser-valid nested tag unguarded and permits recursive frontend rendering.
Crash telemetry
| Occurrences | 2 |
| Distinct sites | 2 |
| First seen | 2026-08-19 23:38 UTC |
| Last seen | 2026-08-21 05:12 UTC |
| Crash location | product:inc/plugins/class-dynamic-content.php:951 |
| Request context | frontend |
| Inside Themeisle SDK | no |
| Product versions | 3.2.2, 3.2.3 |
| WP versions | 7.1 |
| PHP versions | 8.3.33 |
| SDK versions | 3.3.58, 3.3.59 |
Source: automated crash report — otter-blocks, fingerprint 0c1564bd69f5bbc3066bb86c49a064fe
Generated by bug-report-triage (ID: bug-report-triage_6a8a8c91010fb7.64532230)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in inc/plugins/class-dynamic-content.php, tracing dynamic_content_regex(), mark_exceptions(), get_data(), and get_content(). Run the Dynamic Content PHPUnit tests, especially tests/test-dynamic-content.php around test_post_content_guard_detects_nested_tag_in_context_post, then add coverage for single-quoted postContent markup. Done means nested tags in either supported quote style are detected without recursive rendering or memory exhaustion.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php, wordpress
- Domain
- frontend, testing
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100