juice icon indicating copy to clipboard operation
juice copied to clipboard

[BUG] It stuck in an infinite loop when parsing specific css.

Open greg-md opened this issue 4 years ago • 2 comments

If you run this, you will never get a response.

const juice = require('juice');
const result = juice(`<style>.my-class:not(.is-content-justification-space-between, .is-content-justification-right) {}</style>`);
console.log('result', result);

If there is only one class inside the :not(...), or if the class names are shorter - it could not be reproduced.

Node version: v10.24.1 Juice version: 8.0.0

greg-md avatar Nov 24 '21 15:11 greg-md

I think this will solve it https://github.com/Automattic/juice/pull/442

filoscoder avatar Feb 05 '23 12:02 filoscoder

I recently encountered this as well and I believe it's because of an issue with mensch, the library used to transform CSS into tokens. Selectors are split with split(',') which in this situation creates a token like :not(.is-content-justification-space-between with no closing parenthesis.

When this token is passed to the Slick parser, it blocks at this line as the Regex evaluation seems to never completes.

There is a PR open to fix this in mensch (https://github.com/brettstimmerman/mensch/pull/29) but it uses a pattern with negative lookbehind which is not supported on all browsers.

If it helps, here is a test case to reproduce this issue:

.css file:

#root [mstyles='flowchart_container'] :is([mstyles~='flowchart_block_simple'],[mstyles~='flowchart_block_multi'],[mstyles~='flowchart_block_dashed'],[mstyles~='flowchart_icon_container']) {
	background: var(--background);
	border-color: var(--on-background);
}

.html file:

<div id="root"></div>

.out file:

<div id="root"></div>

sparga avatar Apr 06 '23 18:04 sparga