[FIX] web_editor: selector exclusion rule

The current rules would allow through a selector of the form

    :not(sel1, sel2)

then because the matcher thing just splits on `,` it would store the
incorrect sections

    :not sel1(

and

    sel2)

as separate selectors in the rules cache, raising an exception when
matching against elements.

Move all the rules to a single regex, and add a rule to exclude any
situation where a comma or an open parenthesis is inside of an open
parenthesis pair: we can't just check if there's a closing parenthesis
with no intermediate `,`, because the selector could be

    :not(:nth-child(3), sel2)

in which case the selector would "pass" as the regex would match the
nth-child's closing paren to the not's opening. This means some
selectors *could* be unnecessarily blacklisted, but currently we don't
have any such nested pseudo-classes so...

If we want to resolve this, we need to actually parse the
selector (using something like Sizzle I guess) in order to properly
split the selector-list and take a real look at the selector's
structure. Maybe one day.

closes odoo/odoo#68093

X-original-commit: d50c3b07f1c0644ac8e412f099ddd7b139671060
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
This commit is contained in:
Xavier Morel
2021-03-18 14:55:13 +00:00
parent f5f0752f88
commit 73d25e253e
@@ -3,6 +3,7 @@ odoo.define('web_editor.convertInline', function (require) {
var FieldHtml = require('web_editor.field.html');
const SELECTORS_IGNORE = /(^\*$|:hover|:before|:after|:active|:link|::|'|\([^(),]+[,(])/g;
/**
* Returns the css rules which applies on an element, tweaked so that they are
* browser/mail client ok.
@@ -29,16 +30,7 @@ function getMatchedCSSRules(a) {
if (rules) {
for (r = rules.length-1; r >= 0; r--) {
var selectorText = rules[r].selectorText;
if (selectorText &&
rules[r].cssText &&
selectorText !== '*' &&
selectorText.indexOf(':hover') === -1 &&
selectorText.indexOf(':before') === -1 &&
selectorText.indexOf(':after') === -1 &&
selectorText.indexOf(':active') === -1 &&
selectorText.indexOf(':link') === -1 &&
selectorText.indexOf('::') === -1 &&
selectorText.indexOf("'") === -1) {
if (selectorText && !SELECTORS_IGNORE.test(selectorText)) {
var st = selectorText.split(/\s*,\s*/);
for (k = 0 ; k < st.length ; k++) {
rulesCache.push({ 'selector': st[k], 'style': rules[r].style });
@@ -481,4 +473,4 @@ return {
attachmentThumbnailToLinkImg: attachmentThumbnailToLinkImg,
linkImgToAttachmentThumbnail: linkImgToAttachmentThumbnail,
};
});
});