Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

refactor($parse): remove check which never triggers #13588

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 13 additions & 14 deletions src/ng/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,23 +48,22 @@ function ensureSafeMemberName(name, fullExpression) {
return name;
}

function getStringValue(name, fullExpression) {
// From the JavaScript docs:
function getStringValue(name) {
// Property names must be strings. This means that non-string objects cannot be used
// as keys in an object. Any non-string object, including a number, is typecasted
// into a string via the toString method.
// -- MDN, https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Property_accessors#Property_names
//
// So, to ensure that we are checking the same `name` that JavaScript would use,
// we cast it to a string, if possible.
// Doing `name + ''` can cause a repl error if the result to `toString` is not a string,
// this is, this will handle objects that misbehave.
name = name + '';
if (!isString(name)) {
throw $parseMinErr('iseccst',
'Cannot convert object to primitive value! '
+ 'Expression: {0}', fullExpression);
}
return name;
// So, to ensure that we are checking the same `name` that JavaScript would use, we cast it
// to a string. It's not always possible. If `name` is an object and its `toString` method is
// 'broken' (doesn't return a string, isn't a function, etc.), an error will be thrown:
//
// TypeError: Cannot convert object to primitive value
//
// For performance reasons, we don't catch this error here and allow it to propagate up the call
// stack. Note that you'll get the same error in JavaScript if you try to access a property using
// such a 'broken' object as a key.
return name + '';
}

function ensureSafeObject(obj, fullExpression) {
Expand Down Expand Up @@ -1231,7 +1230,7 @@ ASTCompiler.prototype = {
},

getStringValue: function(item) {
this.assign(item, 'getStringValue(' + item + ',text)');
this.assign(item, 'getStringValue(' + item + ')');
},

ensureSafeAssignContext: function(item) {
Expand Down
13 changes: 13 additions & 0 deletions test/ng/parseSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2201,6 +2201,19 @@ describe('parser', function() {
expect(scope.$eval('true || false || run()')).toBe(true);
});

it('should throw TypeError on using a \'broken\' object as a key to access a property', function() {
scope.object = {};
forEach([
{ toString: 2 },
{ toString: null },
{ toString: function() { return {}; } }
], function(brokenObject) {
scope.brokenObject = brokenObject;
expect(function() {
scope.$eval('object[brokenObject]');
}).toThrow();
});
});

it('should support method calls on primitive types', function() {
scope.empty = '';
Expand Down