Skip to content

Commit 46f1b25

Browse files
authored
Fix and test for bug #1457 (#1481)
* Fix and test for bug #1457 (Uncaught SyntaxError: Regular expression too large) - see test case which is extracted from a real world css file; the selector regex was able to traverse the curly brace as when looking for quotes, it wasn't taking into account that the start quote could be escaped * Apply formatting changes * Create fair-ducks-clean.md * Fix @import regex bit which was stopping consumption in the middle of a url - need to consume quotes. Thanks dave.kindel@pendo.io for reporting and isolating this case --------- Co-authored-by: eoghanmurray <eoghanmurray@users.noreply.github.com>
1 parent 03b5216 commit 46f1b25

File tree

4 files changed

+39
-4
lines changed

4 files changed

+39
-4
lines changed

.changeset/eleven-bobcats-peel.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
2-
'rrweb-snapshot': patch
3-
'rrweb': patch
2+
"rrweb-snapshot": patch
3+
"rrweb": patch
44
---
55

66
better support for coexistence with older libraries (e.g. MooTools & Prototype.js) which modify the in-built `Array.from` function

.changeset/fair-ducks-clean.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"rrweb-snapshot": patch
3+
"rrweb": patch
4+
---
5+
6+
Fix and test for bug #1457 which was affecting replay of complex tailwind css

packages/rrweb-snapshot/src/css.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ export function parse(css: string, options: ParserOptions = {}): Stylesheet {
433433
}
434434

435435
// Use match logic from https://github.com/NxtChg/pieces/blob/3eb39c8287a97632e9347a24f333d52d916bc816/js/css_parser/css_parse.js#L46C1-L47C1
436-
const m = match(/^(("(?:\\"|[^"])*"|'(?:\\'|[^'])*'|[^{])+)/);
436+
const m = match(/^(((?<!\\)"(?:\\"|[^"])*"|(?<!\\)'(?:\\'|[^'])*'|[^{])+)/);
437437
if (!m) {
438438
return;
439439
}
@@ -864,7 +864,17 @@ export function parse(css: string, options: ParserOptions = {}): Stylesheet {
864864
*/
865865

866866
function _compileAtrule(name: string) {
867-
const re = new RegExp('^@' + name + '\\s*([^;]+);');
867+
const re = new RegExp(
868+
'^@' +
869+
name +
870+
'\\s*((?:' +
871+
[
872+
'(?<!\\\\)"(?:\\\\"|[^"])*"',
873+
"(?<!\\\\)'(?:\\\\'|[^'])*'",
874+
'[^;]',
875+
].join('|') +
876+
')+);',
877+
);
868878
return () => {
869879
const pos = position();
870880
const m = match(re);

packages/rrweb-snapshot/test/rebuild.test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,4 +203,23 @@ ul li.specified c:hover img, ul li.specified c.\\:hover img {
203203
expect(getDuration(cachedEnd) * factor).toBeLessThan(getDuration(end));
204204
});
205205
});
206+
207+
it('should not incorrectly interpret escaped quotes', () => {
208+
// the ':hover' in the below is a decoy which is not part of the selector,
209+
// previously that part was being incorrectly consumed by the selector regex
210+
const should_not_modify =
211+
".tailwind :is(.before\\:content-\\[\\'\\'\\])::before { --tw-content: \":hover\"; content: var(--tw-content); }.tailwind :is(.\\[\\&\\>li\\]\\:before\\:content-\\[\\'-\\'\\] > li)::before { color: pink; }";
212+
expect(adaptCssForReplay(should_not_modify, cache)).toEqual(
213+
should_not_modify,
214+
);
215+
});
216+
217+
it('should not incorrectly interpret at rules', () => {
218+
// the ':hover' in the below is a decoy which is not part of the selector,
219+
const should_not_modify =
220+
'@import url("https://fonts.googleapis.com/css2?family=Rubik:ital,wght@0,400;0,500;0,700;1,400&display=:hover");';
221+
expect(adaptCssForReplay(should_not_modify, cache)).toEqual(
222+
should_not_modify,
223+
);
224+
});
206225
});

0 commit comments

Comments
 (0)