Problem/Motivation

While working on #3222797: Upgrade path from CKEditor 4's StylesCombo to CKEditor 5's Style, I noticed that, given $a = HTMLRestrictions::fromString('<tag attr="A B">'); and $b = HTMLRestrictions::fromString('<tag attr>');, this happens:

  1. $b->diff($a) results in ['tag' => ['attr' => TRUE]], which is correct: $a does not allow everything $b allows
  2. $a->diff($b)->getAllowedElements() results in ['tag' => ['attr' => ['A', 'B']], but should be [] — since $b allows a superset of $a

Steps to reproduce

See above.

Proposed resolution

Fix this.

Remaining tasks

N/A

User interface changes

N/A

API changes

None.

Data model changes

None.

Release notes snippet

N/A

Issue fork drupal-3278394

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Wim Leers created an issue. See original summary.

Wim Leers’s picture

Status: Active » Needs review

For test coverage: I could add a test to HTMLRestrictionsTest like:

  public function test3278394(): void {
    $a = HTMLRestrictions::fromString('<tag attr="A B">');
    $b = HTMLRestrictions::fromString('<tag attr>');
    $this->assertSame([], $a->diff($b)->getAllowedElements());
    $this->assertSame(['tag' => ['attr' => TRUE]], $b->diff($a)->getAllowedElements());
  }

… but that would be silly because we already have the massive \Drupal\Tests\ckeditor5\Unit\HTMLRestrictionsTest::testOperations() with an enormous data provider.

Turns out there's a wrong expectation in the expectations, and that's how we missed this bug! Fixed test expectation in ed4a73cd3fea1b2b0598803d0be4ae895239b22a.

Wim Leers’s picture

Now ready for review!

Wim Leers’s picture

Assigned: Unassigned » Wim Leers
Status: Needs review » Needs work

Uh oh — I fixed \Drupal\Tests\ckeditor5\Unit\HTMLRestrictionsTest::testOperations() but broke two other tests 😅

Wim Leers’s picture

Assigned: Wim Leers » Unassigned
Status: Needs work » Needs review

Now the only remaining failure is this:

Testing Drupal\Tests\ckeditor5\Unit\SmartDefaultSettingsTest
..........F.                                                      12 / 12 (100%)

Time: 00:00.039, Memory: 4.00 MB

There was 1 failure:

1) Drupal\Tests\ckeditor5\Unit\SmartDefaultSettingsTest::testCandidates with data set "Attribute needed, multiple matches" 
Failed asserting that two arrays are identical.
--- Expected
+++ Actual
@@ @@
             )
             'a' => Array &4 (
                 1 => Array &5 (
-                    'test_attr_values' => 1002
-                    'test_tags_and_attr_values' => 2002102
+                    'test_attr_values' => 0
+                    'test_tags_and_attr_values' => 2001100
                 )
             )
             'b' => Array &6 (
                 1 => Array &7 (
-                    'test_attr_values' => 1002
-                    'test_tags_and_attr_values' => 2002102
+                    'test_attr_values' => 0
+                    'test_tags_and_attr_values' => 2001100
                 )
             )
         )
@@ @@
         '-attributes-none-' => Array &8 (
             'test_all_attrs' => 100000
             'test_attrs' => 1100
-            'test_attr_values' => 1002
+            'test_attr_values' => 0
             'test_tags_and_attrs' => 2001100
-            'test_tags_and_attr_values' => 2002102
+            'test_tags_and_attr_values' => 2001100
         )
     )
 )

Mysterious, right? 🤓🙈

Let's unravel it. 🕵️

  1. The meaning of those integers: a "surplus score" — see #3231328-43: SmartDefaultSettings should select the CKE5 plugin that minimizes creation of HTML restriction supersets for a handy overview.
  2. We can see that all of the failures are because the expected surplus scores are higher than the ones actually being computed. In other words: the surplus scores became lower in a few cases. Why?
  3. … because diff() now correctly handles an extra case. In the failing test, the desire is to support <foo bar> (meaning ANY value on the bar attribute on the foo tag), but test_attr_values only supports <foo bar="a b">. In other words: there is no surplus at all here. With the fix in this issue, that changes the score to 0 instead of 1002. The score used to be 1002 (meaning "two surplus attribute values" and "one surplus attribute") because <foo bar="a b"> DIFF <foo bar> === <foo bar="a b"> in HEAD, but we're fixing that to be <foo bar="a b"> DIFF <foo bar> = ∅, which completely explains that difference in score.

In other words: this is another example of something that was wrong in the test expectations!

Fixed in 3af97b37934a63f4f29bf0fd8acd4bb2c115995e.

Wim Leers’s picture

6aa08d5fc as patch, to test against all 3 4 branches.

bnjmnm’s picture

Status: Needs review » Reviewed & tested by the community

This is basically RTBC but a committer would need to make a small change on commit. If the committer reading this would prefer to not take on that responsibility, feel free to switch back to NW.

The small change that is needed:

+++ b/core/modules/ckeditor5/src/HTMLRestrictions.php
@@ -476,17 +477,22 @@ function ($value, string $tag) use ($other) {
+      // - suffix wildcard, f.e. `foo-*`

Suffix would be `*-bar` 🤓

Wim Leers’s picture

#8 OMG 🤣 🙈

Fixed! 😁 (This is a pre-existing bug, but totally reasonable to fix here IMHO. Which is why the patch size grew a bit: there were three places within the same file which contained this comment bug.)

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 9: 3278394-9.patch, failed testing. View results

Wim Leers’s picture

Status: Needs work » Reviewed & tested by the community

Random unrelated Layout Builder test fail. Re-testing.

  • lauriii committed ce0ec61 on 10.0.x
    Issue #3278394 by Wim Leers, bnjmnm: HTMLRestrictions' diff operation...

  • lauriii committed b077d55 on 9.5.x
    Issue #3278394 by Wim Leers, bnjmnm: HTMLRestrictions' diff operation...
lauriii’s picture

Version: 10.0.x-dev » 9.3.x-dev

Committed ce0ec61 and pushed to 10.0.x. Cherry-picked to 9.5.x and 9.4.x. Thanks!

Leaving open for backport to 9.3.x once freeze is over.

  • lauriii committed cc5e384 on 9.4.x
    Issue #3278394 by Wim Leers, bnjmnm: HTMLRestrictions' diff operation...
larowlan’s picture

Status: Reviewed & tested by the community » Fixed

Updating status

Wim Leers’s picture

Status: Fixed » Reviewed & tested by the community

Not yet backported 😅

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Backported to 9.3.x as this is experimental there and there is no harm

  • alexpott committed f791317 on 9.3.x authored by lauriii
    Issue #3278394 by Wim Leers, bnjmnm: HTMLRestrictions' diff operation...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.