fix: Complete memory leak fix with shortcode context tracking
All checks were successful
Create Release Package / build-release (push) Successful in 57s

The v0.4.1 fix was incomplete - shortcodes called get_*_data() methods
directly, bypassing the recursion tracking in get_post_data().

Changes:
- Added $in_shortcode_context flag to TemplateLoader
- Added enter/exit_shortcode_context() methods
- All shortcode render methods now enter context before data loading
- When in shortcode context, the_content filter is always skipped

This fully prevents infinite recursion when post content contains
FediStream shortcodes that would otherwise recursively render.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-02 16:44:51 +01:00
parent eaefcff9c9
commit fedab21c2a
4 changed files with 93 additions and 7 deletions

View File

@@ -81,6 +81,9 @@ class Shortcodes {
* @return string
*/
public function render_artist( array $atts ): string {
// Enter shortcode context to prevent recursive shortcode processing during data loading.
TemplateLoader::enter_shortcode_context();
$atts = shortcode_atts(
array(
'id' => 0,
@@ -95,6 +98,7 @@ class Shortcodes {
$post = $this->get_post( $atts, 'fedistream_artist' );
if ( ! $post ) {
TemplateLoader::exit_shortcode_context();
return '';
}
@@ -119,6 +123,9 @@ class Shortcodes {
* @return string
*/
public function render_album( array $atts ): string {
// Enter shortcode context to prevent recursive shortcode processing during data loading.
TemplateLoader::enter_shortcode_context();
$atts = shortcode_atts(
array(
'id' => 0,
@@ -132,6 +139,7 @@ class Shortcodes {
$post = $this->get_post( $atts, 'fedistream_album' );
if ( ! $post ) {
TemplateLoader::exit_shortcode_context();
return '';
}
@@ -155,6 +163,9 @@ class Shortcodes {
* @return string
*/
public function render_track( array $atts ): string {
// Enter shortcode context to prevent recursive shortcode processing during data loading.
TemplateLoader::enter_shortcode_context();
$atts = shortcode_atts(
array(
'id' => 0,
@@ -168,6 +179,7 @@ class Shortcodes {
$post = $this->get_post( $atts, 'fedistream_track' );
if ( ! $post ) {
TemplateLoader::exit_shortcode_context();
return '';
}
@@ -191,6 +203,9 @@ class Shortcodes {
* @return string
*/
public function render_playlist( array $atts ): string {
// Enter shortcode context to prevent recursive shortcode processing during data loading.
TemplateLoader::enter_shortcode_context();
$atts = shortcode_atts(
array(
'id' => 0,
@@ -204,6 +219,7 @@ class Shortcodes {
$post = $this->get_post( $atts, 'fedistream_playlist' );
if ( ! $post ) {
TemplateLoader::exit_shortcode_context();
return '';
}
@@ -227,6 +243,9 @@ class Shortcodes {
* @return string
*/
public function render_latest_releases( array $atts ): string {
// Enter shortcode context to prevent recursive shortcode processing during data loading.
TemplateLoader::enter_shortcode_context();
$atts = shortcode_atts(
array(
'count' => 6,
@@ -292,6 +311,9 @@ class Shortcodes {
* @return string
*/
public function render_popular_tracks( array $atts ): string {
// Enter shortcode context to prevent recursive shortcode processing during data loading.
TemplateLoader::enter_shortcode_context();
$atts = shortcode_atts(
array(
'count' => 10,
@@ -359,6 +381,9 @@ class Shortcodes {
* @return string
*/
public function render_artists_grid( array $atts ): string {
// Enter shortcode context to prevent recursive shortcode processing during data loading.
TemplateLoader::enter_shortcode_context();
$atts = shortcode_atts(
array(
'count' => 12,
@@ -426,6 +451,9 @@ class Shortcodes {
* @return string
*/
public function render_player( array $atts ): string {
// Enter shortcode context to prevent recursive shortcode processing during data loading.
TemplateLoader::enter_shortcode_context();
$atts = shortcode_atts(
array(
'track' => 0,
@@ -471,6 +499,7 @@ class Shortcodes {
}
if ( empty( $tracks ) ) {
TemplateLoader::exit_shortcode_context();
return '';
}
@@ -528,13 +557,20 @@ class Shortcodes {
return $this->get_unlicensed_message();
}
// Enter shortcode context to prevent recursive shortcode processing.
TemplateLoader::enter_shortcode_context();
try {
return $this->plugin->render( $template, $context );
$result = $this->plugin->render( $template, $context );
} catch ( \Exception $e ) {
TemplateLoader::exit_shortcode_context();
if ( WP_DEBUG ) {
return '<p class="fedistream-error">' . esc_html( $e->getMessage() ) . '</p>';
}
return '';
}
TemplateLoader::exit_shortcode_context();
return $result;
}
}