Skip to content

Commit ba7e6b3

Browse files
authored
lib: make Navigator#language getter throw on invalid this
Signed-off-by: Mohamed Sayed <k@3zrv.com> PR-URL: #63601 Fixes: #63513 Reviewed-By: LiviaMedeiros <livia@cirno.name> Reviewed-By: Matthew Aitken <maitken033380023@gmail.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent faa413e commit ba7e6b3

2 files changed

Lines changed: 22 additions & 1 deletion

File tree

lib/internal/navigator.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ function getNavigatorPlatform(arch, platform) {
7979
}
8080

8181
class Navigator {
82-
// Private properties are used to avoid brand validations.
82+
// Private properties are used to avoid brand validations: reading a private
83+
// field from a non-Navigator receiver throws a TypeError on its own.
8384
#availableParallelism;
8485
#locks;
8586
#userAgent;
@@ -113,6 +114,10 @@ class Navigator {
113114
* @returns {string}
114115
*/
115116
get language() {
117+
// `language` does not read a private field, so brand-check explicitly
118+
// to keep parity with the other getters when called on a non-Navigator
119+
// receiver (e.g. `Navigator.prototype.language`).
120+
this.#languages; // eslint-disable-line no-unused-expressions
116121
// The default locale might be changed dynamically, so always invoke the
117122
// binding.
118123
return getDefaultLocale() || 'en-US';

test/parallel/test-navigator.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,19 @@ Object.defineProperty(navigator, 'language', { value: 'for-testing' });
147147
assert.strictEqual(navigator.language, 'for-testing');
148148
assert.strictEqual(navigator.languages.length, 1);
149149
assert.strictEqual(navigator.languages[0] !== 'for-testing', true);
150+
151+
{
152+
const { Navigator } = globalThis;
153+
for (const name of Object.keys(Navigator.prototype)) {
154+
assert.throws(
155+
() => Navigator.prototype[name],
156+
{ name: 'TypeError' },
157+
`expected TypeError when reading ${name} on Navigator.prototype`,
158+
);
159+
assert.throws(
160+
() => Reflect.get(Navigator.prototype, name, {}),
161+
{ name: 'TypeError' },
162+
`expected TypeError when reading ${name} on a plain object`,
163+
);
164+
}
165+
}

0 commit comments

Comments
 (0)