Make WordPress Core

Opened 3 years ago

Last modified 5 months ago

#55027 new defect (bug)

force_balance_tags function breaks nested G tabs in SVG

Reported by: svitlana41319's profile svitlana41319 Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 5.9
Component: General Keywords: has-patch
Focuses: Cc:

Description

How to re-create:

  1. Enable 'WordPress should correct invalidly nested XHTML automatically' option.
  2. Save this svg code (in a Custom HTML block, for an example)
<svg viewBox="0 0 46.3 62.73" class="chicken-maxi-svg__10"><g stroke-width="2" stroke-linejoin="round" stroke="var(--maxi-light-icon-line,rgba(var(--maxi-light-color-7,8,18,25),1))" data-stroke=""><path fill="var(--maxi-light-icon-fill,rgba(var(--maxi-light-color-4,255,74,23),1))" data-fill="" d="M25.9 35.93c.3-.7.9-2.9-3-2.9s-3.2 2.1-2.9 2.9 2.3 3.6 3.1 3.6 2.2-2.3 2.8-3.6z"></path><g fill="none"><path stroke-linecap="round" d="M2.2 36.53v-5.1a18.82 18.82 0 0 1 .7-5.3 20 20 0 0 1 1.9-4.8 15.64 15.64 0 0 1 1.7-2.5 20.84 20.84 0 0 1 4.5-4.4 19.89 19.89 0 0 1 5.6-2.9l1-.3m26.2 43.8a.9.9 0 0 0-.1.5 4.13 4.13 0 0 1-.7 1.1 5.17 5.17 0 0 1-3.8 1.7c-.7 0-30.2.6-33.9-.3-1.2-.3-2.1-1.6-2.8-2.5a.76.76 0 0 0-.2-.4M28 11.03l1.6.4a21.91 21.91 0 0 1 5.7 2.9 20.84 20.84 0 0 1 4.5 4.4 22 22 0 0 1 1.7 2.5 20 20 0 0 1 1.9 4.8 23.28 23.28 0 0 1 .6 5.3v5"></path><path d="M18.8 48.83h1.8m1.6 0H24m1.8 0h1.7"></path></g><g stroke-linecap="round" fill="var(--maxi-light-icon-fill,rgba(var(--maxi-light-color-4,255,74,23),1))" data-fill=""><use xlink:href="#chicken_B"></use><use x="16.5" xlink:href="#chicken_B"></use><path d="M2.2 36.53H1v19a5.78 5.78 0 0 0 1.4-.5c1.8-1 3.3-3.2 4.5-6.5a40.92 40.92 0 0 0 2.1-9.8l.2-2.8-7 .6m43.1 0c0-.3-8.2-.5-8.2-.5.1.7.1 1.6.2 2.8a40.92 40.92 0 0 0 2.1 9.8c1.1 3.3 2.6 5.4 4.4 6.4a4.42 4.42 0 0 0 1.5.5v-19M30.6 6.03c.2-1.3-.8-4.8-1.3-5-1.1-.4-4.9 3.5-5.9 3.4-.2 0-2.6-3.7-3.2-3.3-1.7.9-2.8 3.6-3.2 4.8a7.51 7.51 0 0 0 .5 5.2c.4.7 8.9 1.6 10.2.3a10.3 10.3 0 0 0 2.9-5.4"></path></g><g fill="none"><circle r="3.7" cy="26.23" cx="15.8"></circle><circle r=".9" cy="27.93" cx="17.7"></circle><circle r="3.7" cy="26.23" cx="30.2"></circle><circle r=".9" cy="27.93" cx="32.2"></circle></g></g><defs><path d="M16 54.53a2 2 0 0 0-.8.1c-.6.1-4.1 4.3-3.5 5.3.1.2 1.9-1 2.5-.6s.7 2.4 1.4 2.4c.2 0 1.2-1.6 1.5-1.9.8-.2 2.6.8 2.7.6.7-1.9-3.1-5.9-3.8-5.9" id="chicken_B"></path></defs></svg>

The svg code that force_balance_tags() returns:

<svg viewBox="0 0 46.3 62.73" class="chicken-maxi-svg__10"><g stroke-width="2" stroke-linejoin="round" stroke="var(--maxi-light-icon-line,rgba(var(--maxi-light-color-7,8,18,25),1))" data-stroke=""><path fill="var(--maxi-light-icon-fill,rgba(var(--maxi-light-color-4,255,74,23),1))" data-fill="" d="M25.9 35.93c.3-.7.9-2.9-3-2.9s-3.2 2.1-2.9 2.9 2.3 3.6 3.1 3.6 2.2-2.3 2.8-3.6z"></path></g><g fill="none"><path stroke-linecap="round" d="M2.2 36.53v-5.1a18.82 18.82 0 0 1 .7-5.3 20 20 0 0 1 1.9-4.8 15.64 15.64 0 0 1 1.7-2.5 20.84 20.84 0 0 1 4.5-4.4 19.89 19.89 0 0 1 5.6-2.9l1-.3m26.2 43.8a.9.9 0 0 0-.1.5 4.13 4.13 0 0 1-.7 1.1 5.17 5.17 0 0 1-3.8 1.7c-.7 0-30.2.6-33.9-.3-1.2-.3-2.1-1.6-2.8-2.5a.76.76 0 0 0-.2-.4M28 11.03l1.6.4a21.91 21.91 0 0 1 5.7 2.9 20.84 20.84 0 0 1 4.5 4.4 22 22 0 0 1 1.7 2.5 20 20 0 0 1 1.9 4.8 23.28 23.28 0 0 1 .6 5.3v5"></path><path d="M18.8 48.83h1.8m1.6 0H24m1.8 0h1.7"></path></g><g stroke-linecap="round" fill="var(--maxi-light-icon-fill,rgba(var(--maxi-light-color-4,255,74,23),1))" data-fill=""><use xlink:href="#chicken_B"></use><use x="16.5" xlink:href="#chicken_B"></use><path d="M2.2 36.53H1v19a5.78 5.78 0 0 0 1.4-.5c1.8-1 3.3-3.2 4.5-6.5a40.92 40.92 0 0 0 2.1-9.8l.2-2.8-7 .6m43.1 0c0-.3-8.2-.5-8.2-.5.1.7.1 1.6.2 2.8a40.92 40.92 0 0 0 2.1 9.8c1.1 3.3 2.6 5.4 4.4 6.4a4.42 4.42 0 0 0 1.5.5v-19M30.6 6.03c.2-1.3-.8-4.8-1.3-5-1.1-.4-4.9 3.5-5.9 3.4-.2 0-2.6-3.7-3.2-3.3-1.7.9-2.8 3.6-3.2 4.8a7.51 7.51 0 0 0 .5 5.2c.4.7 8.9 1.6 10.2.3a10.3 10.3 0 0 0 2.9-5.4"></path></g><g fill="none"><circle r="3.7" cy="26.23" cx="15.8"></circle><circle r=".9" cy="27.93" cx="17.7"></circle><circle r="3.7" cy="26.23" cx="30.2"></circle><circle r=".9" cy="27.93" cx="32.2"></circle></g><defs><path d="M16 54.53a2 2 0 0 0-.8.1c-.6.1-4.1 4.3-3.5 5.3.1.2 1.9-1 2.5-.6s.7 2.4 1.4 2.4c.2 0 1.2-1.6 1.5-1.9.8-.2 2.6.8 2.7.6.7-1.9-3.1-5.9-3.8-5.9" id="chicken_B"></path></defs></svg>

And the image is broken because of the <g> tags. Here is a video of the bug if you want to see it https://drive.google.com/file/d/1ojdWZsy8oHxuVTAtwms7l6K9xBhPIYvv/view?usp=sharing

So, can you please add the <g> tag to $nestable_tags here? https://core.trac.wordpress.org/changeset/52188

Thanks!

Change History (5)

#1 @SerifKonjevic
3 years ago

Oh, I was wondering about this too. Happens on my site as well.

#2 @igorradovanov
3 years ago

I'd like to work on this ticket once approved.

#3 @naaaaiix
3 years ago

Please, fix it! Had to change lots of icons of my clients sites. Been a nightmare until I discovered what it was. Here's an example:
Expected code and result:

<svg width="1200" height="1200">
	<g fill="white" stroke="green" stroke-width="10">
		<circle cx="40" cy="40" r="25" />
		<g fill="red" stroke="blue" stroke-width="20">
			<circle cx="80" cy="40" r="25" />
			<circle cx="120" cy="40" r="25" />
		</g>
		<circle cx="160" cy="40" r="25" />
	</g>
</svg>

https://i.ibb.co/LpqwY52/Captura-de-pantalla-2022-02-08-a-las-10-21-12.png

Received code and result:

<svg width="1200" height="1200">
	<g fill="white" stroke="green" stroke-width="10">
		<circle cx="40" cy="40" r="25"></circle>
	</g>
	<g fill="red" stroke="blue" stroke-width="20">
		<circle cx="80" cy="40" r="25"></circle>
		<circle cx="120" cy="40" r="25"></circle>
	</g>
	<circle cx="160" cy="40" r="25"></circle>
</svg>

https://i.ibb.co/dbHHq04/Captura-de-pantalla-2022-02-08-a-las-10-29-04.png

This ticket was mentioned in PR #7409 on WordPress/wordpress-develop by @dmsnell.


5 months ago
#4

  • Keywords has-patch added

Trac ticket: Core-55027

The concept of force_balance_tags() is tricky at best. It's purpose, however is clear: clean up HTML input no matter how "bad" it appears.

The HTML API introduces a new tool based on a systematic approach to normalizing by serializing. WP_HTML_Processor::normalize() produces clear and consistent output HTML regardless of the input and without any special-casing for "edge cases." As a spec-compliant parser, everything is a basic case of applying the parsing rules.

Since there are still documents that the HTML API cannot parse, this is an optimistic refactor. For the cases of unsupported HTML, the behavior falls back to the legacy code. When the HTML API finished supporting all content it may be possible to eliminate the legacy code, but until then, most inputs will be handled by the HTML API.

#5 @dmsnell
5 months ago

Reported error with WP_HTML_Processor::normalize() becomes this

<svg viewBox="0 0 46.3 62.73" class="chicken-maxi-svg__10"><g stroke-width="2" stroke-linejoin="round" stroke="var(--maxi-light-icon-line,rgba(var(--maxi-light-color-7,8,18,25),1))" data-stroke=""><path fill="var(--maxi-light-icon-fill,rgba(var(--maxi-light-color-4,255,74,23),1))" data-fill="" d="M25.9 35.93c.3-.7.9-2.9-3-2.9s-3.2 2.1-2.9 2.9 2.3 3.6 3.1 3.6 2.2-2.3 2.8-3.6z"></path><g fill="none"><path stroke-linecap="round" d="M2.2 36.53v-5.1a18.82 18.82 0 0 1 .7-5.3 20 20 0 0 1 1.9-4.8 15.64 15.64 0 0 1 1.7-2.5 20.84 20.84 0 0 1 4.5-4.4 19.89 19.89 0 0 1 5.6-2.9l1-.3m26.2 43.8a.9.9 0 0 0-.1.5 4.13 4.13 0 0 1-.7 1.1 5.17 5.17 0 0 1-3.8 1.7c-.7 0-30.2.6-33.9-.3-1.2-.3-2.1-1.6-2.8-2.5a.76.76 0 0 0-.2-.4M28 11.03l1.6.4a21.91 21.91 0 0 1 5.7 2.9 20.84 20.84 0 0 1 4.5 4.4 22 22 0 0 1 1.7 2.5 20 20 0 0 1 1.9 4.8 23.28 23.28 0 0 1 .6 5.3v5"></path><path d="M18.8 48.83h1.8m1.6 0H24m1.8 0h1.7"></path></g><g stroke-linecap="round" fill="var(--maxi-light-icon-fill,rgba(var(--maxi-light-color-4,255,74,23),1))" data-fill=""><use xlink href="#chicken_B"></use><use x="16.5" xlink href="#chicken_B"></use><path d="M2.2 36.53H1v19a5.78 5.78 0 0 0 1.4-.5c1.8-1 3.3-3.2 4.5-6.5a40.92 40.92 0 0 0 2.1-9.8l.2-2.8-7 .6m43.1 0c0-.3-8.2-.5-8.2-.5.1.7.1 1.6.2 2.8a40.92 40.92 0 0 0 2.1 9.8c1.1 3.3 2.6 5.4 4.4 6.4a4.42 4.42 0 0 0 1.5.5v-19M30.6 6.03c.2-1.3-.8-4.8-1.3-5-1.1-.4-4.9 3.5-5.9 3.4-.2 0-2.6-3.7-3.2-3.3-1.7.9-2.8 3.6-3.2 4.8a7.51 7.51 0 0 0 .5 5.2c.4.7 8.9 1.6 10.2.3a10.3 10.3 0 0 0 2.9-5.4"></path></g><g fill="none"><circle r="3.7" cy="26.23" cx="15.8"></circle><circle r=".9" cy="27.93" cx="17.7"></circle><circle r="3.7" cy="26.23" cx="30.2"></circle><circle r=".9" cy="27.93" cx="32.2"></circle></g></g><defs><path d="M16 54.53a2 2 0 0 0-.8.1c-.6.1-4.1 4.3-3.5 5.3.1.2 1.9-1 2.5-.6s.7 2.4 1.4 2.4c.2 0 1.2-1.6 1.5-1.9.8-.2 2.6.8 2.7.6.7-1.9-3.1-5.9-3.8-5.9" id="chicken_B"></path></defs></svg>

Which does display properly.

https://cldup.com/iSc5gJF7pP.png

Reported issue from comment 3 is also confirmed fixed.

<svg width="1200" height="1200">
    <g fill="white" stroke="green" stroke-width="10">
        <circle cx="40" cy="40" r="25" />
        <g fill="red" stroke="blue" stroke-width="20">
            <circle cx="80" cy="40" r="25" />
            <circle cx="120" cy="40" r="25" />
        </g>
        <circle cx="160" cy="40" r="25" />
    </g>
</svg>

https://cldup.com/7wI_TVdk3i.png

It's my intention to replace force_balance_tags() with the WP_HTML_Processor::normalize() method, though that will leave some rare edge cases that are unsupported until the HTML API can process all HTML (currently it processes all but less than 1% of HTML "in the wild"). for the cases where the HTML API doesn't support the input, we can degrade to the legacy behavior.

Note: See TracTickets for help on using tickets.