Skip to content

Commit

Permalink
fix(Snapshot): Harden asset file extension matching
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewpomeroy committed Dec 12, 2023
1 parent 2327ceb commit 3a8a297
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 3 deletions.
5 changes: 3 additions & 2 deletions packages/rrweb-snapshot/src/snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
stringifyStylesheet,
getInputType,
toLowerCase,
extractFileExtension,
} from './utils';

let _id = 1;
Expand Down Expand Up @@ -847,7 +848,7 @@ function slimDOMExcluded(
(sn.tagName === 'link' &&
sn.attributes.rel === 'prefetch' &&
typeof sn.attributes.href === 'string' &&
sn.attributes.href.endsWith('.js')))
extractFileExtension(sn.attributes.href) === 'js'))
) {
return true;
} else if (
Expand Down Expand Up @@ -1179,7 +1180,7 @@ export function serializeNodeWithId(
typeof serializedNode.attributes.rel === 'string' &&
(serializedNode.attributes.rel === 'stylesheet' || (serializedNode.attributes.rel === 'preload' &&
typeof serializedNode.attributes.href === 'string' &&
serializedNode.attributes.href.endsWith('.css')))) {
extractFileExtension(serializedNode.attributes.href) === 'css'))) {
onceStylesheetLoaded(
n as HTMLLinkElement,
() => {
Expand Down
13 changes: 13 additions & 0 deletions packages/rrweb-snapshot/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,3 +331,16 @@ export function getInputType(element: HTMLElement): Lowercase<string> | null {
toLowerCase(type)
: null;
}

/**
* Extracts the file extension from an a path, considering search parameters and fragments.
* @param path Path to file
* @param [baseURL] Base URL of the page, used to resolve relative paths. Defaults to current page URL.
*/
export function extractFileExtension(path: string, baseURL?: string): string | null {
const url = new URL(path, baseURL ?? window.location.href);
const regex = /\.([0-9a-z]+)(?:[\?#]|$)/i;
const match = url.pathname.match(regex);
console.log(url.pathname)
return match?.[1] ?? null;
}
46 changes: 45 additions & 1 deletion packages/rrweb-snapshot/test/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @jest-environment jsdom
*/
import { NodeType, serializedNode } from '../src/types';
import { isNodeMetaEqual } from '../src/utils';
import { extractFileExtension, isNodeMetaEqual } from '../src/utils';
import { serializedNodeWithId } from 'rrweb-snapshot';

describe('utils', () => {
Expand Down Expand Up @@ -147,4 +147,48 @@ describe('utils', () => {
expect(isNodeMetaEqual(element2, element3)).toBeFalsy();
});
});
describe('extractFileExtension', () => {
test('absolute path', () => {
const path = 'https://example.com/styles/main.css';
const extension = extractFileExtension(path);
expect(extension).toBe('css');
});

test('relative path', () => {
const path = 'styles/main.css';
const baseURL = 'https://example.com/';
const extension = extractFileExtension(path, baseURL);
expect(extension).toBe('css');
});

test('path with search parameters', () => {
const path = 'https://example.com/scripts/app.js?version=1.0';
const extension = extractFileExtension(path);
expect(extension).toBe('js');
});

test('path with fragment', () => {
const path = 'https://example.com/styles/main.css#section1';
const extension = extractFileExtension(path);
expect(extension).toBe('css');
});

test('path with search parameters and fragment', () => {
const path = 'https://example.com/scripts/app.js?version=1.0#section1';
const extension = extractFileExtension(path);
expect(extension).toBe('js');
});

test('path without extension', () => {
const path = 'https://example.com/path/to/directory/';
const extension = extractFileExtension(path);
expect(extension).toBeNull();
});

test('path with multiple dots', () => {
const path = 'https://example.com/scripts/app.min.js?version=1.0';
const extension = extractFileExtension(path);
expect(extension).toBe('js');
});
});
});

0 comments on commit 3a8a297

Please sign in to comment.