Bug 860312 - [devtools] Add LegacyLenientThis getters to unsafe list. r=devtools-reviewers,ochameau.

Getters with LegacyLenientThis attribute will trigger a warning in the console
if it's called with the unexpected `this`.
We can't tell in DevTools if we have the "right" `this`.
For example displaying an `HTMLDivElementPrototype` object, we'll trigger the
warning because of the `onmouseenter` getter, which is supposed to be called
with the `HTMLElement` instance, which we don't have at this point.

For this reason, we exclude those from being safe getters, which will prevent
triggering the warning.

Differential Revision: https://phabricator.services.mozilla.com/D174070
This commit is contained in:
Nicolas Chevobbe 2023-04-11 06:25:58 +00:00
parent 3fbff23a4b
commit affbaffc08
4 changed files with 76 additions and 1 deletions

View File

@ -296,6 +296,7 @@ https_first_disabled = true
[browser_webconsole_insecure_passwords_web_console_warning.js]
[browser_webconsole_inspect_cross_domain_object.js]
[browser_webconsole_keyboard_accessibility.js]
[browser_webconsole_lenient_this_warning.js]
[browser_webconsole_limit_multiline.js]
[browser_webconsole_location_debugger_link.js]
fail-if = a11y_checks # bug 1687728 frame-link-filename is not accessible

View File

@ -0,0 +1,68 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Check that calling the LenientThis warning is only called when expected.
const TEST_URI = `data:text/html;charset=utf8,<!DOCTYPE html>${encodeURI(`
<h1>LenientThis warning</h1>
<script>
const el = document.createElement('div');
globalThis.htmlDivElementProto = Object.getPrototypeOf(el);
function triggerLenientThisWarning(){
Object.getOwnPropertyDescriptor(
Object.getPrototypeOf(globalThis.htmlDivElementProto),
'onmouseenter'
).get.call()
}
</script>`)}`;
add_task(async function() {
const hud = await openNewTabAndConsole(TEST_URI);
const expectedWarningMessageText =
"Ignoring get or set of property that has [LenientThis] ";
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function() {
const global = content.wrappedJSObject;
global.console.log(global.htmlDivElementProto);
});
info("Wait for a bit so any warning message could be displayed");
await wait(1000);
await waitFor(() => findConsoleAPIMessage(hud, "HTMLDivElementPrototype"));
ok(
!findWarningMessage(hud, expectedWarningMessageText, ".warn"),
"Displaying the HTMLDivElementPrototype does not trigger the LenientThis warning"
);
info(
"Call a LenientThis getter with the wrong `this` to trigger a warning message"
);
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function() {
content.wrappedJSObject.triggerLenientThisWarning();
});
await waitFor(() =>
findWarningMessage(hud, expectedWarningMessageText, ".warn")
);
ok(
true,
"Calling the LenientThis getter with an unexpected `this` did triggered the warning"
);
info(
"Clear the console and call the LenientThis getter with an unexpected `this` again"
);
await clearOutput(hud);
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function() {
content.wrappedJSObject.triggerLenientThisWarning();
});
info("Wait for a bit so any warning message could be displayed");
await wait(1000);
ok(
!findWarningMessage(hud, expectedWarningMessageText, ".warn"),
"Calling the LenientThis getter a second time did not trigger the warning again"
);
});

View File

@ -13,6 +13,9 @@ module.exports = [
"mozPreservesPitch",
"mozPressure",
"nearestViewportElement",
"onmouseenter",
"onmouseleave",
"onmozfullscreenchange",
"onmozfullscreenerror",
"onreadystatechange",
];

View File

@ -178,7 +178,10 @@ for result in results:
not iface in DEPRECATED_INTERFACE__EXCLUDE_LIST
and not name in unsafe_getters_names
and member.isAttr()
and member.getExtendedAttribute("Deprecated")
and (
member.getExtendedAttribute("Deprecated")
or member.getExtendedAttribute("LegacyLenientThis")
)
):
unsafe_getters_names.append(name)