Skip to content

Commit a1b29a7

Browse files
committed
failed attempts to poison .href setting and using eslint no-restricted-properties
1 parent 0754436 commit a1b29a7

File tree

3 files changed

+53
-5
lines changed

3 files changed

+53
-5
lines changed

.eslintrc.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ module.exports = {
2929
'CallExpression > ArrowFunctionExpression > :expression.body',
3030
],
3131
}],
32+
33+
'no-restricted-properties': [2, {
34+
'property': 'href',
35+
'message': 'Please use allowedObjectName.allowedPropertyName.',
36+
}],
37+
3238
'no-floating-decimal': 2,
3339
'max-len': [2, 100, {
3440
ignoreComments: true,

lighthouse-viewer/test/test-helpers.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,19 @@ function setupJsDomGlobals() {
1919
global.window = window;
2020
global.logger = console;
2121
global.logger.hide = () => {/* noop */};
22+
23+
const anchorElem = document.createElement('a');
24+
const propDesc = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(anchorElem), 'href');
25+
Object.defineProperty(window.HTMLAnchorElement, 'href', {
26+
enumerable: propDesc.enumerable,
27+
configurable: propDesc.configurable,
28+
get: propDesc.get,
29+
set: _ => {
30+
const stack = new Error().stack;
31+
console.log({stack});
32+
throw new Error('Setting .href directly is verboten!');
33+
},
34+
});
2235
}
2336

2437
function cleanupJsDomGlobals() {

report/test/renderer/details-renderer-test.js

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,39 @@ describe('DetailsRenderer', () => {
1919
let renderer;
2020

2121
function createRenderer(options) {
22-
const {document} = new jsdom.JSDOM(reportAssets.REPORT_TEMPLATES).window;
23-
const dom = new DOM(document);
22+
const {window} = new jsdom.JSDOM(reportAssets.REPORT_TEMPLATES);
23+
const dom = new DOM(window.document);
2424
renderer = new DetailsRenderer(dom, options);
2525
renderer.setTemplateContext(dom.document());
26+
global.window = window;
27+
28+
// hack to avoid setting .href directly.
29+
const anchorElem = window.document.createElement('a');
30+
const propDesc = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(anchorElem), 'href');
31+
Object.defineProperty(Object.getPrototypeOf(anchorElem), 'href', {
32+
enumerable: propDesc.enumerable,
33+
configurable: propDesc.configurable,
34+
get: propDesc.get,
35+
set: value => {
36+
const err = new Error();
37+
38+
// Was .href set from safelySetHref ?
39+
let isFound = false;
40+
const prevPrepare = Error.prepareStackTrace;
41+
Error.prepareStackTrace = (error, stack) => {
42+
isFound = stack.some(callsite => callsite.getFunctionName().includes('safelySetHref'));
43+
};
44+
const _ = err.stack; // Triggers call to prepareStackTrace
45+
Error.prepareStackTrace = prevPrepare;
46+
47+
48+
if (isFound) {
49+
propDesc.set.call(propDesc, value);
50+
} else {
51+
throw new Error('Setting .href directly is verboten!');
52+
}
53+
},
54+
});
2655
}
2756

2857
beforeAll(() => {
@@ -313,7 +342,7 @@ describe('DetailsRenderer', () => {
313342
assert.strictEqual(thumbnailEl.alt, '');
314343
});
315344

316-
it('renders link values', () => {
345+
it.only('renders link values', () => {
317346
const linkText = 'Example Site';
318347
const linkUrl = 'https://example.com/';
319348
const link = {
@@ -355,7 +384,7 @@ describe('DetailsRenderer', () => {
355384
assert.equal(linkEl.textContent, linkText);
356385
});
357386

358-
it('renders link value as text if URL is invalid', () => {
387+
it.only('renders link value as text if URL is invalid', () => {
359388
const linkText = 'Invalid Link';
360389
const linkUrl = 'link nonsense';
361390
const link = {
@@ -368,9 +397,9 @@ describe('DetailsRenderer', () => {
368397
headings: [{key: 'content', itemType: 'link', text: 'Heading'}],
369398
items: [{content: link}],
370399
};
371-
372400
const el = renderer.render(details);
373401
const linkEl = el.querySelector('td.lh-table-column--link > .lh-text');
402+
374403
assert.equal(linkEl.localName, 'div');
375404
assert.equal(linkEl.textContent, linkText);
376405
});

0 commit comments

Comments
 (0)