Skip to content

Commit

Permalink
Check for LHS Object-coercibility in MemberExpression
Browse files Browse the repository at this point in the history
The spec says that if the LHS (base) of a MemberExpression fails CheckObjectCoercible / RequireObjectCoercible that the resulting TypeError should be propagated, which should preven the RHS of an enclosing AssignmentExpression from being evaluated.  So do that, even though apparently no one else does (see https://bugs.chromium.org/p/v8/issues/detail?id=7847 and tc39/ecma262#1224).
  • Loading branch information
cpcallen committed Jun 15, 2018
1 parent c33f70e commit 745f046
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 10 deletions.
7 changes: 6 additions & 1 deletion server/interpreter.js
Original file line number Diff line number Diff line change
Expand Up @@ -6180,7 +6180,12 @@ stepFuncs_['MemberExpression'] = function (thread, stack, state, node) {
}
stack.pop();
if (state.wantRef_) {
stack[stack.length - 1].ref = [state.tmp_, key];
var base = state.tmp_;
if (base === null || base === undefined) {
throw new this.Error(perms, this.TYPE_ERROR,
"Can't convert " + base + ' to Object');
}
stack[stack.length - 1].ref = [base, key];
} else {
var perms = state.scope.perms;
stack[stack.length - 1].value =
Expand Down
10 changes: 7 additions & 3 deletions server/tests/db/test_01_es5.js
Original file line number Diff line number Diff line change
Expand Up @@ -1162,18 +1162,20 @@ tests.instanceofNonObjectPrototype = function() {
}
};

tests.nulUndefinedProps = function() {
tests.nullUndefinedProps = function() {
try {
undefined.foo;
console.assert(false, "undefined.foo didn't throw");
} catch (e) {
console.assert(e.name === 'TypeError', 'undefined.foo wrong error');
}
try {
undefined.foo = undefined;
var c = 0;
undefined.foo = c++;
console.assert(false, "undefined.foo = ... didn't throw");
} catch (e) {
console.assert(e.name === 'TypeError', 'undefined.foo = ... wrong error');
console.assert(c === 0, 'undefined.foo = ... evaluated RHS');
}
try {
null.foo;
Expand All @@ -1182,10 +1184,12 @@ tests.nulUndefinedProps = function() {
console.assert(e.name === 'TypeError', 'null.foo wrong error');
}
try {
null.foo = undefined;
c = 0;
null.foo = c++;
console.assert(false, "null.foo = ... didn't throw");
} catch (e) {
console.assert(e.name === 'TypeError', 'null.foo = ... wrong error');
console.assert(c === 0, 'null.foo = ... evaluated RHS');
}
};

Expand Down
14 changes: 8 additions & 6 deletions server/tests/testcases.js
Original file line number Diff line number Diff line change
Expand Up @@ -770,12 +770,13 @@ module.exports = [

{ name: 'undefined.foo = ...', src: `
try {
undefined.foo = undefined;
var c = 0;
undefined.foo = c++;
} catch (e) {
e.name;
e.name + ',' + c;
}
`,
expected: 'TypeError' },
expected: 'TypeError,0' },

{ name: 'null.foo', src: `
try {
Expand All @@ -788,12 +789,13 @@ module.exports = [

{ name: 'null.foo = ...', src: `
try {
null.foo = undefined;
var c = 0;
null.foo = c++;
} catch (e) {
e.name;
e.name + ',' + c;
}
`,
expected: 'TypeError' },
expected: 'TypeError,0' },

{ name: 'deleteProp', src: `
var o = {foo: 'bar'};
Expand Down

0 comments on commit 745f046

Please sign in to comment.