endojs / endo

Endo is a distributed secure JavaScript sandbox, based on SES
Apache License 2.0
829 stars 72 forks source link

Babel versions circa 7.20 are incompatible with Hardened JavaScript #1846

Closed kriskowal closed 11 months ago

kriskowal commented 1 year ago

Describe the bug

Refs: https://github.com/Agoric/agoric-sdk/issues/8458 Refs: https://github.com/endojs/endo/pull/1842

New contract packages are encountering a new Hardened JavaScript incompatibility (property override mistake) when attempting to use @endo/bundle-source to generate contract bundles.

One of the following errors appears:

(TypeError#1)
TypeError#1: Cannot assign to read only property 'constructor' of object '[object Object]'
  at _interopRequireWildcard (/home/x/projects/x/contract/node_modules/@babel/highlight/lib/index.js:12:710)
  at Object.<anonymous> (/home/x/projects/x/contract/node_modules/@babel/highlight/lib/index.js:10:14)
  at Module._compile (node:internal/modules/cjs/loader:1256:14)
  at module.exports.o.a._extensions..js (/home/x/projects/xcontract/node_modules/esm/esm.js:1:102412)
  at Module.load (node:internal/modules/cjs/loader:1119:32)
  at Module._load (node:internal/modules/cjs/loader:960:12)
  at Module.require (node:internal/modules/cjs/loader:1143:19)

Or:

TypeError#1: Cannot assign to read only property 'constructor' of object '[object Object]'
  at _interopRequireWildcard (/home/x/projects/x/contract/node_modules/@babel/code-frame/lib/index.js:11:710)
  at Object.<anonymous> (/home/x/projects/x/contract/node_modules/@babel/code-frame/lib/index.js:9:14)
  at Module._compile (node:internal/modules/cjs/loader:1256:14)
  at module.exports.o.a._extensions..js (/home/x/projects/x/contract/node_modules/esm/esm.js:1:102412)
  at Module.load (node:internal/modules/cjs/loader:1119:32)
  at Module._load (node:internal/modules/cjs/loader:960:12)
  at Module.require (node:internal/modules/cjs/loader:1143:19)
  at require (node:internal/modules/cjs/helpers:121:18)
  at Object.<anonymous> (/home/x/projects/x/contract/node_modules/@babel/traverse/lib/path/replacement.js:12:18)
  at Module._compile (node:internal/modules/cjs/loader:1256:14)
  at module.exports.o.a._extensions..js (/home/x/projects/x/contract/node_modules/esm/esm.js:1:102412)
  at Module.load (node:internal/modules/cjs/loader:1119:32)
  at Module._load (node:internal/modules/cjs/loader:960:12)
  at Module.require (node:internal/modules/cjs/loader:1143:19)

Work-arounds

One option is to patch current versions, as demonstrated for this contract https://github.com/Kryha/KREAd/pull/24/commits/3c986551c694e80b97a2f7b1097ca367ac3b09c5

Or, adding the following snippet to package.json in the affected application and running yarn should temporarily mitigate the problem. This will become vestigial and should be removed when a patch for @babel/code-frame gets released.

{
  "resolutions": {
    "@babel/code-frame": "7.18.6"
  }
}

Or, call lockdown with override-taming set to severe:

lockdown({ overrideTaming: 'severe' });

Steps to reproduce

  1. Create a new package
  2. Add @endo/bundle-source to dependencies
  3. Run yarn
  4. Create an empty entry entry.js
  5. Run bundle-source --to-json bundles entry.js entry

Expected behavior

Should generate a bundle in bundles.

Platform environment

All

Additional context

Babel released what it believed to be a backward-compatible version circa 7.20 that introduced one or more property override mistakes incompatible with the Hardened JavaScript environment. Since semver does not differentiate between ordinary JavaScript and hardened JavaScript and as Babel does not test under a Hardened JavaScript environment (or merely an environment with a few frozen intrinsic prototypes), the breaking change was not recognized by the authors.

Notes

erights commented 1 year ago

See https://github.com/endojs/endo/issues/576

mhofman commented 12 months ago

For reference, I was able to downgrade babel in a dapp by using the following resolutions to update the yarn.lock without yarn complaining about incompatible versions, then remove the resolutions and make sure that the offending versions didn't re-appear.

  "resolutions": {
    "@babel/template": "7.22.5",
    "@babel/core": "7.22.11",
    "@babel/highlight": "7.22.10",
    "@babel/code-frame": "7.22.10",
    "@babel/generator": "7.22.10",
    "@babel/helper-builder-binary-assignment-operator-visitor": "7.22.10",
    "@babel/helper-compilation-targets": "7.22.10",
    "@babel/helper-create-class-features-plugin": "7.22.11",
    "@babel/helper-create-regexp-features-plugin": "7.22.9",
    "@babel/helper-environment-visitor": "7.22.5",
    "@babel/helper-member-expression-to-functions": "7.22.5",
    "@babel/helper-module-imports": "7.22.5",
    "@babel/helper-module-transforms": "7.22.9",
    "@babel/helper-remap-async-to-generator": "7.22.9",
    "@babel/helper-replace-supers": "7.22.9",
    "@babel/helper-validator-identifier": "7.22.5",
    "@babel/helper-validator-option": "7.22.5",
    "@babel/helper-wrap-function": "7.22.10",
    "@babel/helpers": "7.22.11",
    "@babel/parser": "7.22.11",
    "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "7.22.5",
    "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "7.22.5",
    "@babel/plugin-proposal-decorators": "7.22.10",
    "@babel/plugin-transform-async-generator-functions": "7.22.11",
    "@babel/plugin-transform-block-scoping": "7.22.10",
    "@babel/plugin-transform-classes": "7.22.6",
    "@babel/plugin-transform-destructuring": "7.22.10",
    "@babel/plugin-transform-for-of": "7.22.5",
    "@babel/plugin-transform-object-rest-spread": "7.22.11",
    "@babel/plugin-transform-optional-chaining": "7.22.12",
    "@babel/plugin-transform-parameters": "7.22.5",
    "@babel/plugin-transform-react-jsx": "7.22.5",
    "@babel/plugin-transform-runtime": "7.22.10",
    "@babel/plugin-transform-typescript": "7.22.11",
    "@babel/preset-env": "7.22.10",
    "@babel/preset-react": "7.22.5",
    "@babel/preset-typescript": "7.22.11",
    "@babel/runtime-corejs3": "7.22.11",
    "@babel/runtime": "7.22.11",
    "@babel/traverse": "7.22.11",
    "@babel/eslint-parser": "7.22.11",
    "@babel/plugin-transform-class-static-block": "7.22.11",
    "@babel/plugin-transform-modules-systemjs": "7.22.11",
    "@babel/compat-data": "7.22.9",
    "@babel/plugin-transform-dynamic-import": "7.22.11",
    "@babel/plugin-transform-export-namespace-from": "7.22.11",
    "@babel/plugin-transform-json-strings": "7.22.11",
    "@babel/plugin-transform-logical-assignment-operators": "7.22.11",
    "@babel/plugin-transform-modules-commonjs": "7.22.11",
    "@babel/plugin-transform-nullish-coalescing-operator": "7.22.11",
    "@babel/plugin-transform-numeric-separator": "7.22.11",
    "@babel/plugin-transform-optional-catch-binding": "7.22.11",
    "@babel/plugin-transform-private-property-in-object": "7.22.11",
    "@babel/types": "7.22.11"
  }

I've also verified that the following patches to chalk are sufficient to work around the babel override mistake in affected versions: https://github.com/Agoric/dapp-card-store/commit/7cf26480b003a46ceaf245ebdfda4c9f24cfd3a9

Finally I've also asked if it'd be possible to release new versions of @babel/highlight and @babel/code-frame with the fixed helper.

mhofman commented 11 months ago

Looks like new versions of the babel packages got published with the fix.