Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions packages/rrweb-snapshot/src/css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -439,10 +439,9 @@ export function parse(css: string, options: ParserOptions = {}) {
return;
}

/* @fix Remove all comments from selectors
* http://ostermiller.org/findcomment.html */
/* @fix Remove all comments from selectors */
const splitSelectors = trim(m[0])
.replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g, '')
.replace(/\/\*[\s\S]*?\*\/+/g, '')
.replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'/g, (m) => {
return m.replace(/,/g, '\u200C');
})
Expand Down
2 changes: 1 addition & 1 deletion packages/rrweb-snapshot/src/snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,7 @@
// So we'll be conservative and keep textContent as-is.
} else if ((n.parentNode as HTMLStyleElement).sheet?.cssRules) {
textContent = stringifyStylesheet(
(n.parentNode as HTMLStyleElement).sheet!,

Check warning on line 778 in packages/rrweb-snapshot/src/snapshot.ts

View workflow job for this annotation

GitHub Actions / ESLint Check and Report Upload

Forbidden non-null assertion
);
}
} catch (err) {
Expand Down Expand Up @@ -927,7 +927,7 @@
attributes.rel = null;
attributes.href = null;
attributes.crossorigin = null;
attributes._cssText = absoluteToStylesheet(cssText, stylesheet!.href!);

Check warning on line 930 in packages/rrweb-snapshot/src/snapshot.ts

View workflow job for this annotation

GitHub Actions / ESLint Check and Report Upload

Forbidden non-null assertion

Check warning on line 930 in packages/rrweb-snapshot/src/snapshot.ts

View workflow job for this annotation

GitHub Actions / ESLint Check and Report Upload

Forbidden non-null assertion
}
}
// dynamic stylesheet
Expand Down Expand Up @@ -1039,10 +1039,10 @@
const recordInlineImage = () => {
image.removeEventListener('load', recordInlineImage);
try {
canvasService!.width = image.naturalWidth;

Check warning on line 1042 in packages/rrweb-snapshot/src/snapshot.ts

View workflow job for this annotation

GitHub Actions / ESLint Check and Report Upload

Forbidden non-null assertion
canvasService!.height = image.naturalHeight;

Check warning on line 1043 in packages/rrweb-snapshot/src/snapshot.ts

View workflow job for this annotation

GitHub Actions / ESLint Check and Report Upload

Forbidden non-null assertion
canvasCtx!.drawImage(image, 0, 0);

Check warning on line 1044 in packages/rrweb-snapshot/src/snapshot.ts

View workflow job for this annotation

GitHub Actions / ESLint Check and Report Upload

Forbidden non-null assertion
attributes.rr_dataURL = canvasService!.toDataURL(

Check warning on line 1045 in packages/rrweb-snapshot/src/snapshot.ts

View workflow job for this annotation

GitHub Actions / ESLint Check and Report Upload

Forbidden non-null assertion
dataURLOptions.type,
dataURLOptions.quality,
);
Expand Down Expand Up @@ -1345,7 +1345,7 @@
(!preserveWhiteSpace &&
_serializedNode.type === NodeType.Text &&
!_serializedNode.isStyle &&
!_serializedNode.textContent.replace(/^\s+|\s+$/gm, '').length)
!_serializedNode.textContent.trim().length)
) {
id = IGNORED_NODE;
} else {
Expand Down
23 changes: 23 additions & 0 deletions packages/rrweb-snapshot/test/css.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,29 @@ describe('css parser', () => {
expect(decl.parent).toEqual(rule);
});

it('should strip comments from selectors', () => {
const cases: Array<[string, string[]]> = [
['.foo /* comment */, .bar { color: red; }', ['.foo', '.bar']],
['a /* x */ b, c /* y */ d { color: red; }', ['a b', 'c d']],
['.x /* trailing */ { color: red; }', ['.x']],
];
for (const [css, expected] of cases) {
const rules = parse(css).stylesheet!.rules.filter(
(r): r is Rule => r.type === 'rule',
);
expect(rules[0].selectors?.map((s) => s.trim())).toEqual(expected);
}
});

it('should not catastrophically backtrack on unterminated selector comments', () => {
const evil = '/*' + '\n*'.repeat(40);
const start = Date.now();
expect(() =>
parse(`${evil} { color: red; }`, { silent: true }),
).not.toThrow();
expect(Date.now() - start).toBeLessThan(500);
});

// TODO(sentry): our parser can't handle this atm
it.skip('parses { and } in attribute selectors correctly', () => {
const result = parse('foo[someAttr~="{someId}"] { color: red; }');
Expand Down
Loading