Skip to content

Commit

Permalink
Fix to be compat with the JS override mistake
Browse files Browse the repository at this point in the history
JavaScript has a misfeature often called the "override mistake". In an assignment such as
```js
res.constructor = true;
```
if `res` does not yet have its own `constructor` property, but inherits one that this assignment would override (as is the intention here), but the property that would be overridden is a non-writable data property, then the assignment fails. Hardened JS and similar frameworks for securing JS routinely freeze all the primordial objects, which causes their data properties to become non-configurable, non-writable. Also, the TC53 JS standard for embedded devices standardizes on Hardened JS, which will also cause this problem. The XS JS engine for embedded devices use the Hardened JS configuration by default on embedded devices.

Object literals and classes override inherited properties without problem because they use JS's "define" semantics rather than JS's peculiar "assign" semantics. You can also do so manually via `Object.defineProperty`, as this PR does to repair this issue.

See also
tapjs#70
Agoric/agoric-sdk#6451
  • Loading branch information
erights committed Oct 13, 2022
1 parent c84768b commit d5db5ee
Showing 1 changed file with 2 additions and 2 deletions.
4 changes: 2 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ class StackUtils {
setFile(res, site.getFileName(), this._cwd);

if (site.isConstructor()) {
res.constructor = true;
Object.defineProperty(res, 'constructor', { value: true });
}

if (site.isEval()) {
Expand Down Expand Up @@ -260,7 +260,7 @@ class StackUtils {
setFile(res, file, this._cwd);

if (ctor) {
res.constructor = true;
Object.defineProperty(res, 'constructor', { value: true });
}

if (evalOrigin) {
Expand Down

0 comments on commit d5db5ee

Please sign in to comment.