lib: brand-check Navigator getters to throw ERR_INVALID_THIS#63601
Conversation
Fixes: nodejs#63513 Signed-off-by: Mohamed Sayed <k@3zrv.com>
|
Review requested:
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #63601 +/- ##
=======================================
Coverage 90.32% 90.32%
=======================================
Files 730 730
Lines 234669 234680 +11
Branches 43946 43965 +19
=======================================
+ Hits 211967 211985 +18
Misses 14417 14417
+ Partials 8285 8278 -7
🚀 New features to boost your workflow:
|
|
I don't think adding a check is worth it, I think the current behavior is fine actually, the spec requires a TypeError, we're throwing a TypeError (except for |
LiviaMedeiros
left a comment
There was a problem hiding this comment.
+1 on explicit ERR_INVALID_THIS over implicit private field access. Errors from private fields are misleading and not future-proof: it's too easy to break 'implicit throw' unintentionally (in fact, Navigator.prototype.language was initially introduced using private field, too).
It’s only true if that’s not covered by tests (which I would have expected WPT to cover, but I guess not, or at least not the subset we’re running) |
There was a problem hiding this comment.
In undici we are lenient with errors too with the expectation that a reviewer would notice if a change similar to the one that changed .language was made.
Since it's not reasonable here, I think the change is fine. Regarding the WPTs, brand checks should be implemented the same across globals in most platforms so the assumption is that if you have it implemented properly in one spec, it's also implemented correctly in the thousands of over browser globals.
| const getterNames = [ | ||
| 'hardwareConcurrency', | ||
| 'locks', | ||
| 'language', | ||
| 'languages', | ||
| 'userAgent', | ||
| 'platform', | ||
| ]; | ||
| for (const name of getterNames) { |
There was a problem hiding this comment.
| const getterNames = [ | |
| 'hardwareConcurrency', | |
| 'locks', | |
| 'language', | |
| 'languages', | |
| 'userAgent', | |
| 'platform', | |
| ]; | |
| for (const name of getterNames) { | |
| for (const name of Object.keys(Navigator.prototype)) { |
Fixes: #63513
Add an explicit
#field in thisbrand check to each getter so a proper ERR_INVALID_THIS is thrown, matching browser behavior. This also fixeslanguage, which previously did not error at all on the prototype because it did not touch a private field.