Skip to content

Commit

Permalink
fix: validate in-rhs C when transpiling #p in C
Browse files Browse the repository at this point in the history
  • Loading branch information
JLHwung committed Nov 4, 2022
1 parent a5e4038 commit 2bdadfd
Show file tree
Hide file tree
Showing 65 changed files with 266 additions and 90 deletions.
4 changes: 2 additions & 2 deletions Makefile
Expand Up @@ -192,8 +192,8 @@ new-version-checklist:
# @echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
# @echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
# @echo "!!!!!! !!!!!!"
# @echo "!!!!!! Write any message that should !!!!!!"
# @echo "!!!!!! block the release here !!!!!!"
# @echo "!!!!!! Update the minVersion of packages/babel-helpers/src/helpers/checkInRHS.js"
# @echo "!!!!!! !!!!!!"
# @echo "!!!!!! !!!!!!"
# @echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
# @echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
Expand Down
18 changes: 14 additions & 4 deletions packages/babel-helper-create-class-features-plugin/src/fields.ts
Expand Up @@ -211,7 +211,7 @@ const privateInVisitor = privateNameVisitorFactory<{
file: File;
innerBinding?: t.Identifier;
}>({
BinaryExpression(path) {
BinaryExpression(path, { file }) {
const { operator, left, right } = path.node;
if (operator !== "in") return;
if (!t.isPrivateName(left)) return;
Expand All @@ -230,19 +230,29 @@ const privateInVisitor = privateNameVisitorFactory<{
if (privateFieldsAsProperties) {
const { id } = privateNamesMap.get(name);
path.replaceWith(template.expression.ast`
Object.prototype.hasOwnProperty.call(${right}, ${t.cloneNode(id)})
Object.prototype.hasOwnProperty.call(${file.addHelper(
"checkInRHS",
)}(${right}), ${t.cloneNode(id)})
`);
return;
}

const { id, static: isStatic } = privateNamesMap.get(name);

if (isStatic) {
path.replaceWith(template.expression.ast`${right} === ${this.classRef}`);
path.replaceWith(
template.expression.ast`${file.addHelper(
"checkInRHS",
)}(${right}) === ${t.cloneNode(this.classRef)}`,
);
return;
}

path.replaceWith(template.expression.ast`${t.cloneNode(id)}.has(${right})`);
path.replaceWith(
template.expression.ast`${t.cloneNode(id)}.has(${file.addHelper(
"checkInRHS",
)}(${right}))`,
);
},
});

Expand Down
4 changes: 4 additions & 0 deletions packages/babel-helpers/src/helpers-generated.ts
Expand Up @@ -41,6 +41,10 @@ export default Object.freeze({
"7.0.0-beta.0",
'import OverloadYield from"OverloadYield";export default function _awaitAsyncGenerator(value){return new OverloadYield(value,0)}',
),
checkInRHS: helper(
"7.20.1",
'export default function _checkInRHS(value){var type=typeof value;if("object"!==type&&"function"!==type)throw TypeError("right-hand side of \'in\' should be an object, got "+type);return value}',
),
jsx: helper(
"7.0.0-beta.0",
'var REACT_ELEMENT_TYPE;export default function _createRawReactElement(type,props,key,children){REACT_ELEMENT_TYPE||(REACT_ELEMENT_TYPE="function"==typeof Symbol&&Symbol.for&&Symbol.for("react.element")||60103);var defaultProps=type&&type.defaultProps,childrenLength=arguments.length-3;if(props||0===childrenLength||(props={children:void 0}),1===childrenLength)props.children=children;else if(childrenLength>1){for(var childArray=new Array(childrenLength),i=0;i<childrenLength;i++)childArray[i]=arguments[i+3];props.children=childArray}if(props&&defaultProps)for(var propName in defaultProps)void 0===props[propName]&&(props[propName]=defaultProps[propName]);else props||(props=defaultProps||{});return{$$typeof:REACT_ELEMENT_TYPE,type:type,key:void 0===key?null:""+key,ref:null,props:props,_owner:null}}',
Expand Down
9 changes: 9 additions & 0 deletions packages/babel-helpers/src/helpers/checkInRHS.js
@@ -0,0 +1,9 @@
/* @minVersion 7.20.1 */

export default function _checkInRHS(value) {
var type = typeof value;
if (type !== "object" && type !== "function") {
throw TypeError("right-hand side of 'in' should be an object, got " + type);
}
return value;
}
Expand Up @@ -119,7 +119,7 @@ export default declare((api, opt: Options) => {
enableFeature(this.file, FEATURES.privateIn, loose);
},
visitor: {
BinaryExpression(path) {
BinaryExpression(path, state) {
const { node } = path;
if (node.operator !== "in") return;
if (!t.isPrivateName(node.left)) return;
Expand Down Expand Up @@ -158,7 +158,9 @@ export default declare((api, opt: Options) => {
}
path.replaceWith(
template.expression.ast`
${t.cloneNode(outerClass.node.id)} === ${path.node.right}
${t.cloneNode(outerClass.node.id)} === ${state.addHelper(
"checkInRHS",
)}(${node.right})
`,
);
} else {
Expand All @@ -171,7 +173,9 @@ export default declare((api, opt: Options) => {
);

path.replaceWith(
template.expression.ast`${id}.has(${path.node.right})`,
template.expression.ast`${id}.has(${state.addHelper(
"checkInRHS",
)}(${node.right}))`,
);
}
} else {
Expand All @@ -187,7 +191,9 @@ export default declare((api, opt: Options) => {
);

path.replaceWith(
template.expression.ast`${id}.has(${path.node.right})`,
template.expression.ast`${id}.has(${state.addHelper(
"checkInRHS",
)}(${node.right}))`,
);
}
},
Expand Down
Expand Up @@ -7,7 +7,7 @@ class Foo {
});
}
test(other) {
return Object.prototype.hasOwnProperty.call(other, _foo);
return Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(other), _foo);
}
}
function _get_foo() {}
Expand Up @@ -13,12 +13,12 @@ let Foo = /*#__PURE__*/function () {
babelHelpers.createClass(Foo, [{
key: "test",
value: function test() {
return Object.prototype.hasOwnProperty.call(this, _bar);
return Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(this), _bar);
}
}], [{
key: "test",
value: function test() {
return Object.prototype.hasOwnProperty.call(Foo, _foo);
return Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(Foo), _foo);
}
}]);
return Foo;
Expand Down
Expand Up @@ -7,6 +7,6 @@ class Foo {
});
}
test(other) {
return Object.prototype.hasOwnProperty.call(other, _foo);
return Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(other), _foo);
}
}
Expand Up @@ -6,7 +6,7 @@ class Foo {
});
}
test(other) {
return Object.prototype.hasOwnProperty.call(other, _foo);
return Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(other), _foo);
}
}
function _foo2() {}
Expand Up @@ -21,11 +21,11 @@ class Foo {
});
}
test() {
Object.prototype.hasOwnProperty.call(this, _foo);
Object.prototype.hasOwnProperty.call(this, _bar2);
Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(this), _foo);
Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(this), _bar2);
}
}
Object.prototype.hasOwnProperty.call(this, _foo);
Object.prototype.hasOwnProperty.call(this, _bar);
Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(this), _foo);
Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(this), _bar);
}
}
Expand Up @@ -16,9 +16,9 @@ class Foo {
});
}
test() {
Object.prototype.hasOwnProperty.call(this, _foo2);
Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(this), _foo2);
}
}
Object.prototype.hasOwnProperty.call(this, _foo);
Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(this), _foo);
}
}
Expand Up @@ -9,9 +9,9 @@ class Foo {
test() {
class Nested {
test() {
Object.prototype.hasOwnProperty.call(this, _foo);
Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(this), _foo);
}
}
Object.prototype.hasOwnProperty.call(this, _foo);
Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(this), _foo);
}
}
@@ -0,0 +1,27 @@
expect(() => class { static #p = #p in 0 }).toThrowError(`right-hand side of 'in' should be an object, got number`);
expect(() => class { static #p = #p in "" }).toThrowError(`right-hand side of 'in' should be an object, got string`);
expect(() => class { static #p = #p in true }).toThrowError(`right-hand side of 'in' should be an object, got boolean`);
expect(() => class { static #p = #p in void 0 }).toThrowError(`right-hand side of 'in' should be an object, got undefined`);
expect(() => class { static #p = #p in Symbol.iterator }).toThrowError(`right-hand side of 'in' should be an object, got symbol`);
expect(() => class { static #p = #p in 0n }).toThrowError(`right-hand side of 'in' should be an object, got bigint`);

expect(() => class { static #p() {}; static q = #p in 0 }).toThrowError(`right-hand side of 'in' should be an object, got number`);
expect(() => class { static #p() {}; static q = #p in "" }).toThrowError(`right-hand side of 'in' should be an object, got string`);
expect(() => class { static #p() {}; static q = #p in true }).toThrowError(`right-hand side of 'in' should be an object, got boolean`);
expect(() => class { static #p() {}; static q = #p in void 0 }).toThrowError(`right-hand side of 'in' should be an object, got undefined`);
expect(() => class { static #p() {}; static q = #p in Symbol.iterator }).toThrowError(`right-hand side of 'in' should be an object, got symbol`);
expect(() => class { static #p() {}; static q = #p in 0n }).toThrowError(`right-hand side of 'in' should be an object, got bigint`);

expect(() => new class { #p = #p in 0 }).toThrowError(`right-hand side of 'in' should be an object, got number`);
expect(() => new class { #p = #p in "" }).toThrowError(`right-hand side of 'in' should be an object, got string`);
expect(() => new class { #p = #p in true }).toThrowError(`right-hand side of 'in' should be an object, got boolean`);
expect(() => new class { #p = #p in void 0 }).toThrowError(`right-hand side of 'in' should be an object, got undefined`);
expect(() => new class { #p = #p in Symbol.iterator }).toThrowError(`right-hand side of 'in' should be an object, got symbol`);
expect(() => new class { #p = #p in 0n }).toThrowError(`right-hand side of 'in' should be an object, got bigint`);

expect(() => new class { #p() {}; q = #p in 0 }).toThrowError(`right-hand side of 'in' should be an object, got number`);
expect(() => new class { #p() {}; q = #p in "" }).toThrowError(`right-hand side of 'in' should be an object, got string`);
expect(() => new class { #p() {}; q = #p in true }).toThrowError(`right-hand side of 'in' should be an object, got boolean`);
expect(() => new class { #p() {}; q = #p in void 0 }).toThrowError(`right-hand side of 'in' should be an object, got undefined`);
expect(() => new class { #p() {}; q = #p in Symbol.iterator }).toThrowError(`right-hand side of 'in' should be an object, got symbol`);
expect(() => new class { #p() {}; q = #p in 0n }).toThrowError(`right-hand side of 'in' should be an object, got bigint`);
@@ -0,0 +1,3 @@
{
"minNodeVersion": "12.0.0"
}
@@ -1,7 +1,7 @@
var _foo = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("foo");
class Foo {
test(other) {
return Object.prototype.hasOwnProperty.call(other, _foo);
return Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(other), _foo);
}
}
function _get_foo() {}
Expand Down
@@ -1,7 +1,7 @@
var _foo = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("foo");
class Foo {
test(other) {
return Object.prototype.hasOwnProperty.call(other, _foo);
return Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(other), _foo);
}
}
Object.defineProperty(Foo, _foo, {
Expand Down
@@ -1,7 +1,7 @@
var _foo = /*#__PURE__*/babelHelpers.classPrivateFieldLooseKey("foo");
class Foo {
test(other) {
return Object.prototype.hasOwnProperty.call(other, _foo);
return Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(other), _foo);
}
}
function _foo2() {}
Expand Down
Expand Up @@ -12,7 +12,7 @@ let Foo = /*#__PURE__*/function () {
babelHelpers.createClass(Foo, [{
key: "test",
value: function test(other) {
return Object.prototype.hasOwnProperty.call(other, _foo);
return Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(other), _foo);
}
}]);
return Foo;
Expand Down
Expand Up @@ -12,7 +12,7 @@ let Foo = /*#__PURE__*/function () {
babelHelpers.createClass(Foo, [{
key: "test",
value: function test(other) {
return Object.prototype.hasOwnProperty.call(other, _foo);
return Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(other), _foo);
}
}]);
return Foo;
Expand Down
Expand Up @@ -11,7 +11,7 @@ let Foo = /*#__PURE__*/function () {
babelHelpers.createClass(Foo, [{
key: "test",
value: function test(other) {
return Object.prototype.hasOwnProperty.call(other, _foo);
return Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(other), _foo);
}
}]);
return Foo;
Expand Down
Expand Up @@ -7,10 +7,10 @@ class Foo {
});
}
static test() {
return Foo === Foo;
return babelHelpers.checkInRHS(Foo) === Foo;
}
test() {
return _bar.has(this);
return _bar.has(babelHelpers.checkInRHS(this));
}
}
var _foo = {
Expand Down
Expand Up @@ -29,14 +29,14 @@ let Foo = /*#__PURE__*/function () {
babelHelpers.createClass(Nested, [{
key: "test",
value: function test() {
Object.prototype.hasOwnProperty.call(this, _foo);
Object.prototype.hasOwnProperty.call(this, _bar2);
Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(this), _foo);
Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(this), _bar2);
}
}]);
return Nested;
}();
Object.prototype.hasOwnProperty.call(this, _foo);
Object.prototype.hasOwnProperty.call(this, _bar);
Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(this), _foo);
Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(this), _bar);
}
}]);
return Foo;
Expand Down
Expand Up @@ -24,12 +24,12 @@ let Foo = /*#__PURE__*/function () {
babelHelpers.createClass(Nested, [{
key: "test",
value: function test() {
Object.prototype.hasOwnProperty.call(this, _foo2);
Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(this), _foo2);
}
}]);
return Nested;
}();
Object.prototype.hasOwnProperty.call(this, _foo);
Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(this), _foo);
}
}]);
return Foo;
Expand Down
Expand Up @@ -19,12 +19,12 @@ let Foo = /*#__PURE__*/function () {
babelHelpers.createClass(Nested, [{
key: "test",
value: function test() {
Object.prototype.hasOwnProperty.call(this, _foo);
Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(this), _foo);
}
}]);
return Nested;
}();
Object.prototype.hasOwnProperty.call(this, _foo);
Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(this), _foo);
}
}]);
return Foo;
Expand Down
@@ -0,0 +1,27 @@
expect(() => class { static #p = #p in 0 }).toThrowError(`right-hand side of 'in' should be an object, got number`);
expect(() => class { static #p = #p in "" }).toThrowError(`right-hand side of 'in' should be an object, got string`);
expect(() => class { static #p = #p in true }).toThrowError(`right-hand side of 'in' should be an object, got boolean`);
expect(() => class { static #p = #p in void 0 }).toThrowError(`right-hand side of 'in' should be an object, got undefined`);
expect(() => class { static #p = #p in Symbol.iterator }).toThrowError(`right-hand side of 'in' should be an object, got symbol`);
expect(() => class { static #p = #p in 0n }).toThrowError(`right-hand side of 'in' should be an object, got bigint`);

expect(() => class { static #p() {}; static q = #p in 0 }).toThrowError(`right-hand side of 'in' should be an object, got number`);
expect(() => class { static #p() {}; static q = #p in "" }).toThrowError(`right-hand side of 'in' should be an object, got string`);
expect(() => class { static #p() {}; static q = #p in true }).toThrowError(`right-hand side of 'in' should be an object, got boolean`);
expect(() => class { static #p() {}; static q = #p in void 0 }).toThrowError(`right-hand side of 'in' should be an object, got undefined`);
expect(() => class { static #p() {}; static q = #p in Symbol.iterator }).toThrowError(`right-hand side of 'in' should be an object, got symbol`);
expect(() => class { static #p() {}; static q = #p in 0n }).toThrowError(`right-hand side of 'in' should be an object, got bigint`);

expect(() => new class { #p = #p in 0 }).toThrowError(`right-hand side of 'in' should be an object, got number`);
expect(() => new class { #p = #p in "" }).toThrowError(`right-hand side of 'in' should be an object, got string`);
expect(() => new class { #p = #p in true }).toThrowError(`right-hand side of 'in' should be an object, got boolean`);
expect(() => new class { #p = #p in void 0 }).toThrowError(`right-hand side of 'in' should be an object, got undefined`);
expect(() => new class { #p = #p in Symbol.iterator }).toThrowError(`right-hand side of 'in' should be an object, got symbol`);
expect(() => new class { #p = #p in 0n }).toThrowError(`right-hand side of 'in' should be an object, got bigint`);

expect(() => new class { #p() {}; q = #p in 0 }).toThrowError(`right-hand side of 'in' should be an object, got number`);
expect(() => new class { #p() {}; q = #p in "" }).toThrowError(`right-hand side of 'in' should be an object, got string`);
expect(() => new class { #p() {}; q = #p in true }).toThrowError(`right-hand side of 'in' should be an object, got boolean`);
expect(() => new class { #p() {}; q = #p in void 0 }).toThrowError(`right-hand side of 'in' should be an object, got undefined`);
expect(() => new class { #p() {}; q = #p in Symbol.iterator }).toThrowError(`right-hand side of 'in' should be an object, got symbol`);
expect(() => new class { #p() {}; q = #p in 0n }).toThrowError(`right-hand side of 'in' should be an object, got bigint`);
@@ -0,0 +1,3 @@
{
"minNodeVersion": "12.0.0"
}
Expand Up @@ -8,7 +8,7 @@ let Foo = /*#__PURE__*/function () {
babelHelpers.createClass(Foo, [{
key: "test",
value: function test(other) {
return Object.prototype.hasOwnProperty.call(other, _foo);
return Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(other), _foo);
}
}]);
return Foo;
Expand Down
Expand Up @@ -8,7 +8,7 @@ let Foo = /*#__PURE__*/function () {
babelHelpers.createClass(Foo, [{
key: "test",
value: function test(other) {
return Object.prototype.hasOwnProperty.call(other, _foo);
return Object.prototype.hasOwnProperty.call(babelHelpers.checkInRHS(other), _foo);
}
}]);
return Foo;
Expand Down

0 comments on commit 2bdadfd

Please sign in to comment.