From d9b11354bcc6ad033cf4dda92c145eadfb251d66 Mon Sep 17 00:00:00 2001 From: Richard Porter <34412-rbp@users.noreply.drupalcode.org> Date: Tue, 21 Feb 2023 08:54:27 +0100 Subject: [PATCH] Issue #3098733 by richardbporter, firass.ziedan, dasginganinja, gngn, Oscaner, drupal-son, marcoscano, John Cook: Fatal error after saving the page not have a reuse entity --- .../EntityUsage/Track/CkeditorImage.php | 7 +++ src/Plugin/EntityUsage/Track/EntityEmbed.php | 6 ++ src/Plugin/EntityUsage/Track/LinkIt.php | 7 +++ src/Plugin/EntityUsage/Track/MediaEmbed.php | 4 ++ .../EmbeddedContentTest.php | 63 +++++++++++++++++++ 5 files changed, 87 insertions(+) diff --git a/src/Plugin/EntityUsage/Track/CkeditorImage.php b/src/Plugin/EntityUsage/Track/CkeditorImage.php index e75a5b4..0c47397 100644 --- a/src/Plugin/EntityUsage/Track/CkeditorImage.php +++ b/src/Plugin/EntityUsage/Track/CkeditorImage.php @@ -24,6 +24,13 @@ class CkeditorImage extends TextFieldEmbedBase { $xpath = new \DOMXPath($dom); $entities = []; foreach ($xpath->query('//img[@data-entity-type and @data-entity-uuid]') as $node) { + // Skip elements with empty data-entity-uuid/type attributes. + if (empty($node->getAttribute('data-entity-uuid')) + || empty($node->getAttribute('data-entity-type')) + ) { + continue; + } + // Note that this does not cover 100% of the situations. In the (unlikely // but possible) use case where the user embeds the same entity twice in // the same field, we are just recording 1 usage for this target entity, diff --git a/src/Plugin/EntityUsage/Track/EntityEmbed.php b/src/Plugin/EntityUsage/Track/EntityEmbed.php index b721f21..a3f0bc5 100644 --- a/src/Plugin/EntityUsage/Track/EntityEmbed.php +++ b/src/Plugin/EntityUsage/Track/EntityEmbed.php @@ -24,6 +24,12 @@ class EntityEmbed extends TextFieldEmbedBase { $xpath = new \DOMXPath($dom); $entities = []; foreach ($xpath->query('//drupal-entity[@data-entity-type and @data-entity-uuid]') as $node) { + // Skip elements with empty data-entity-uuid/type attributes. + if (empty($node->getAttribute('data-entity-uuid')) + || empty($node->getAttribute('data-entity-type')) + ) { + continue; + } // Note that this does not cover 100% of the situations. In the (unlikely // but possible) use case where the user embeds the same entity twice in // the same field, we are just recording 1 usage for this target entity, diff --git a/src/Plugin/EntityUsage/Track/LinkIt.php b/src/Plugin/EntityUsage/Track/LinkIt.php index 6bff6e3..49b32fc 100644 --- a/src/Plugin/EntityUsage/Track/LinkIt.php +++ b/src/Plugin/EntityUsage/Track/LinkIt.php @@ -24,6 +24,13 @@ class LinkIt extends TextFieldEmbedBase { $xpath = new \DOMXPath($dom); $entities = []; foreach ($xpath->query('//a[@data-entity-type and @data-entity-uuid]') as $node) { + // Skip elements with empty data-entity-uuid/type attributes. + if (empty($node->getAttribute('data-entity-uuid')) + || empty($node->getAttribute('data-entity-type')) + ) { + continue; + } + // Note that this does not cover 100% of the situations. In the (unlikely // but possible) use case where the user embeds the same entity twice in // the same field, we are just recording 1 usage for this target entity, diff --git a/src/Plugin/EntityUsage/Track/MediaEmbed.php b/src/Plugin/EntityUsage/Track/MediaEmbed.php index 22540bf..d04bd67 100644 --- a/src/Plugin/EntityUsage/Track/MediaEmbed.php +++ b/src/Plugin/EntityUsage/Track/MediaEmbed.php @@ -24,6 +24,10 @@ class MediaEmbed extends TextFieldEmbedBase { $xpath = new \DOMXPath($dom); $entities = []; foreach ($xpath->query('//drupal-media[@data-entity-type="media" and @data-entity-uuid]') as $node) { + // Skip elements with empty data-entity-uuid attributes. + if (empty($node->getAttribute('data-entity-uuid'))) { + continue; + } // Note that this does not cover 100% of the situations. In the (unlikely // but possible) use case where the user embeds the same entity twice in // the same field, we are just recording 1 usage for this target entity, diff --git a/tests/src/FunctionalJavascript/EmbeddedContentTest.php b/tests/src/FunctionalJavascript/EmbeddedContentTest.php index f6992e9..50f84f1 100644 --- a/tests/src/FunctionalJavascript/EmbeddedContentTest.php +++ b/tests/src/FunctionalJavascript/EmbeddedContentTest.php @@ -112,6 +112,27 @@ class EmbeddedContentTest extends EntityUsageJavascriptTestBase { $this->assertEquals($expected, $usage); } + /** + * Tests the Entity Embed plugin parsing does not error with malformed HTML. + */ + public function testEntityEmbedWithMalformedHtml() { + $embedded_text = '<drupal-entity data-embed-button="node" data-entity-embed-display="entity_reference:entity_reference_label" data-entity-embed-display-settings="{"link":1}" data-entity-type="" data-entity-uuid=""></drupal-entity>'; + + $node = Node::create([ + 'type' => 'eu_test_ct', + 'title' => 'This is a node with malformed EntityEmbed HTML', + 'field_eu_test_rich_text' => [ + 'value' => $embedded_text, + 'format' => 'eu_test_text_format', + ], + ]); + + $node->save(); + + $this->drupalGet('/node/' . $node->id()); + $this->assertSession()->pageTextContains('This is a node with malformed EntityEmbed HTML'); + } + /** * Tests the LinkIt parsing. */ @@ -214,6 +235,27 @@ class EmbeddedContentTest extends EntityUsageJavascriptTestBase { $this->assertEquals([], $usage); } + /** + * Tests the LinkIt plugin parsing does not error with malformed HTML. + */ + public function testLinkItdWithMalformedHtml() { + $embedded_text = '<p>foo <a data-entity-substitution="canonical" data-entity-type="" data-entity-uuid="">linked text</a> bar</p>'; + + $node = Node::create([ + 'type' => 'eu_test_ct', + 'title' => 'This is a node with malformed LinkIt HTML', + 'field_eu_test_rich_text' => [ + 'value' => $embedded_text, + 'format' => 'eu_test_text_format', + ], + ]); + + $node->save(); + + $this->drupalGet('/node/' . $node->id()); + $this->assertSession()->pageTextContains('This is a node with malformed LinkIt HTML'); + } + /** * Tests the HtmlLink parsing. */ @@ -505,4 +547,25 @@ class EmbeddedContentTest extends EntityUsageJavascriptTestBase { $this->assertEquals($expected, $usage); } + /** + * Tests the MediaEmbed plugin parsing does not error with malformed HTML. + */ + public function testMediaEmbeddWithMalformedHtml() { + $embedded_text = '<drupal-media data-entity-type="media" data-entity-uuid=""></drupal-media>'; + + $node = Node::create([ + 'type' => 'eu_test_ct', + 'title' => 'This is a node with malformed MediaEmbed HTML', + 'field_eu_test_rich_text' => [ + 'value' => $embedded_text, + 'format' => 'eu_test_text_format', + ], + ]); + + $node->save(); + + $this->drupalGet('/node/' . $node->id()); + $this->assertSession()->pageTextContains('This is a node with malformed MediaEmbed HTML'); + } + } -- GitLab