Skip to content

Commit

Permalink
[Fix] Never call Object prototype builtins directly.
Browse files Browse the repository at this point in the history
  • Loading branch information
ljharb committed Nov 14, 2016
1 parent 5952dbf commit bffd3aa
Show file tree
Hide file tree
Showing 21 changed files with 52 additions and 28 deletions.
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@
"max-len": [2, 120],
"max-params": 0,
"max-statements": 0,
"no-plusplus": 0
"no-plusplus": 0,
"no-prototype-builtins": 2
}
}
6 changes: 4 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use strict';

var has = require('has');

var allRules = {
'jsx-uses-react': require('./lib/rules/jsx-uses-react'),
'no-multi-comp': require('./lib/rules/no-multi-comp'),
Expand Down Expand Up @@ -62,7 +64,7 @@ var allRules = {
function filterRules(rules, predicate) {
var result = {};
for (var key in rules) {
if (rules.hasOwnProperty(key) && predicate(rules[key])) {
if (has(rules, key) && predicate(rules[key])) {
result[key] = rules[key];
}
}
Expand All @@ -72,7 +74,7 @@ function filterRules(rules, predicate) {
function configureAsError(rules) {
var result = {};
for (var key in rules) {
if (!rules.hasOwnProperty(key)) {
if (!has(rules, key)) {
continue;
}
result['react/' + key] = 2;
Expand Down
3 changes: 2 additions & 1 deletion lib/rules/display-name.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/
'use strict';

var has = require('has');
var Components = require('../util/Components');

// ------------------------------------------------------------------------------
Expand Down Expand Up @@ -223,7 +224,7 @@ module.exports = {
var list = components.list();
// Report missing display name for all components
for (var component in list) {
if (!list.hasOwnProperty(component) || list[component].hasDisplayName) {
if (!has(list, component) || list[component].hasDisplayName) {
continue;
}
reportMissingDisplayName(list[component]);
Expand Down
8 changes: 5 additions & 3 deletions lib/rules/jsx-closing-bracket-location.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
*/
'use strict';

var has = require('has');

// ------------------------------------------------------------------------------
// Rule Definition
// ------------------------------------------------------------------------------
Expand Down Expand Up @@ -70,16 +72,16 @@ module.exports = {
options.selfClosing = config;
} else if (typeof config === 'object') {
// [1, {location: 'something'}] (back-compat)
if (config.hasOwnProperty('location')) {
if (has(config, 'location')) {
options.nonEmpty = config.location;
options.selfClosing = config.location;
}
// [1, {nonEmpty: 'something'}]
if (config.hasOwnProperty('nonEmpty')) {
if (has(config, 'nonEmpty')) {
options.nonEmpty = config.nonEmpty;
}
// [1, {selfClosing: 'something'}]
if (config.hasOwnProperty('selfClosing')) {
if (has(config, 'selfClosing')) {
options.selfClosing = config.selfClosing;
}
}
Expand Down
4 changes: 3 additions & 1 deletion lib/rules/jsx-max-props-per-line.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

'use strict';

var has = require('has');

// ------------------------------------------------------------------------------
// Rule Definition
// ------------------------------------------------------------------------------
Expand Down Expand Up @@ -55,7 +57,7 @@ module.exports = {
});

for (var line in props) {
if (!props.hasOwnProperty(line)) {
if (!has(props, line)) {
continue;
}
if (props[line].length > maximum) {
Expand Down
4 changes: 3 additions & 1 deletion lib/rules/jsx-no-duplicate-props.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

'use strict';

var has = require('has');

// ------------------------------------------------------------------------------
// Rule Definition
// ------------------------------------------------------------------------------
Expand Down Expand Up @@ -48,7 +50,7 @@ module.exports = {
name = name.toLowerCase();
}

if (props.hasOwnProperty(name)) {
if (has(props, name)) {
context.report({
node: decl,
message: 'No duplicate props allowed'
Expand Down
3 changes: 2 additions & 1 deletion lib/rules/jsx-tag-spacing.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/
'use strict';

var has = require('has');
var getTokenBeforeClosingBracket = require('../util/getTokenBeforeClosingBracket');

// ------------------------------------------------------------------------------
Expand Down Expand Up @@ -205,7 +206,7 @@ module.exports = {
afterOpening: 'never'
};
for (var key in options) {
if (options.hasOwnProperty(key) && context.options[0].hasOwnProperty(key)) {
if (has(options, key) && has(context.options[0], key)) {
options[key] = context.options[0][key];
}
}
Expand Down
4 changes: 3 additions & 1 deletion lib/rules/jsx-wrap-multilines.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
*/
'use strict';

var has = require('has');

// ------------------------------------------------------------------------------
// Constants
// ------------------------------------------------------------------------------
Expand Down Expand Up @@ -79,7 +81,7 @@ module.exports = {

function isEnabled(type) {
var userOptions = context.options[0] || {};
if (({}).hasOwnProperty.call(userOptions, type)) {
if (has(userOptions, type)) {
return userOptions[type];
}
return DEFAULTS[type];
Expand Down
3 changes: 2 additions & 1 deletion lib/rules/no-direct-mutation-state.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/
'use strict';

var has = require('has');
var Components = require('../util/Components');

// ------------------------------------------------------------------------------
Expand Down Expand Up @@ -76,7 +77,7 @@ module.exports = {
'Program:exit': function() {
var list = components.list();
for (var component in list) {
if (!list.hasOwnProperty(component) || isValid(list[component])) {
if (!has(list, component) || isValid(list[component])) {
continue;
}
reportMutations(list[component]);
Expand Down
3 changes: 2 additions & 1 deletion lib/rules/no-multi-comp.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/
'use strict';

var has = require('has');
var Components = require('../util/Components');

// ------------------------------------------------------------------------------
Expand Down Expand Up @@ -60,7 +61,7 @@ module.exports = {
var i = 0;

for (var component in list) {
if (!list.hasOwnProperty(component) || isIgnored(list[component]) || ++i === 1) {
if (!has(list, component) || isIgnored(list[component]) || ++i === 1) {
continue;
}
context.report({
Expand Down
3 changes: 2 additions & 1 deletion lib/rules/no-set-state.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/
'use strict';

var has = require('has');
var Components = require('../util/Components');

// ------------------------------------------------------------------------------
Expand Down Expand Up @@ -73,7 +74,7 @@ module.exports = {
'Program:exit': function() {
var list = components.list();
for (var component in list) {
if (!list.hasOwnProperty(component) || isValid(list[component])) {
if (!has(list, component) || isValid(list[component])) {
continue;
}
reportSetStateUsages(list[component]);
Expand Down
3 changes: 2 additions & 1 deletion lib/rules/no-unused-prop-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
// As for exceptions for props.children or props.className (and alike) look at
// https://github.com/yannickcr/eslint-plugin-react/issues/7

var has = require('has');
var Components = require('../util/Components');
var variable = require('../util/variable');

Expand Down Expand Up @@ -933,7 +934,7 @@ module.exports = {
var list = components.list();
// Report undeclared proptypes for all classes
for (var component in list) {
if (!list.hasOwnProperty(component) || !mustBeValidated(list[component])) {
if (!has(list, component) || !mustBeValidated(list[component])) {
continue;
}
reportUnusedPropTypes(list[component]);
Expand Down
3 changes: 2 additions & 1 deletion lib/rules/prefer-stateless-function.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
'use strict';

var has = require('has');
var Components = require('../util/Components');
var versionUtil = require('../util/version');

Expand Down Expand Up @@ -371,7 +372,7 @@ module.exports = {
var list = components.list();
for (var component in list) {
if (
!list.hasOwnProperty(component) ||
!has(list, component) ||
hasOtherProperties(list[component].node) ||
list[component].useThis ||
list[component].useRef ||
Expand Down
3 changes: 2 additions & 1 deletion lib/rules/prop-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
// As for exceptions for props.children or props.className (and alike) look at
// https://github.com/yannickcr/eslint-plugin-react/issues/7

var has = require('has');
var Components = require('../util/Components');
var variable = require('../util/variable');

Expand Down Expand Up @@ -915,7 +916,7 @@ module.exports = {
var list = components.list();
// Report undeclared proptypes for all classes
for (var component in list) {
if (!list.hasOwnProperty(component) || !mustBeValidated(list[component])) {
if (!has(list, component) || !mustBeValidated(list[component])) {
continue;
}
reportUndeclaredPropTypes(list[component]);
Expand Down
3 changes: 2 additions & 1 deletion lib/rules/require-optimization.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/
'use strict';

var has = require('has');
var Components = require('../util/Components');

module.exports = {
Expand Down Expand Up @@ -219,7 +220,7 @@ module.exports = {

// Report missing shouldComponentUpdate for all components
for (var component in list) {
if (!list.hasOwnProperty(component) || list[component].hasSCU) {
if (!has(list, component) || list[component].hasSCU) {
continue;
}
reportMissingOptimization(list[component]);
Expand Down
3 changes: 2 additions & 1 deletion lib/rules/require-render-return.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/
'use strict';

var has = require('has');
var Components = require('../util/Components');

// ------------------------------------------------------------------------------
Expand Down Expand Up @@ -111,7 +112,7 @@ module.exports = {
var list = components.list();
for (var component in list) {
if (
!list.hasOwnProperty(component) ||
!has(list, component) ||
!hasRenderMethod(list[component].node) ||
list[component].hasReturnStatement ||
(!utils.isES5Component(list[component].node) && !utils.isES6Component(list[component].node))
Expand Down
9 changes: 5 additions & 4 deletions lib/rules/sort-comp.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/
'use strict';

var has = require('has');
var util = require('util');

var Components = require('../util/Components');
Expand All @@ -24,7 +25,7 @@ function getMethodsOrder(defaultConfig, userConfig) {
var entry;
for (var i = 0, j = order.length; i < j; i++) {
entry = order[i];
if (groups.hasOwnProperty(entry)) {
if (has(groups, entry)) {
config = config.concat(groups[entry]);
} else {
config.push(entry);
Expand Down Expand Up @@ -236,7 +237,7 @@ module.exports = {
*/
function dedupeErrors() {
for (var i in errors) {
if (!errors.hasOwnProperty(i)) {
if (!has(errors, i)) {
continue;
}
var index = errors[i].closest.ref.index;
Expand All @@ -262,7 +263,7 @@ module.exports = {
var indexA;
var indexB;
for (var i in errors) {
if (!errors.hasOwnProperty(i)) {
if (!has(errors, i)) {
continue;
}

Expand Down Expand Up @@ -412,7 +413,7 @@ module.exports = {
'Program:exit': function() {
var list = components.list();
for (var component in list) {
if (!list.hasOwnProperty(component)) {
if (!has(list, component)) {
continue;
}
var properties = getComponentProperties(list[component].node);
Expand Down
7 changes: 4 additions & 3 deletions lib/util/Components.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/
'use strict';

var has = require('has');
var util = require('util');
var doctrine = require('doctrine');
var variableUtil = require('./variable');
Expand Down Expand Up @@ -83,7 +84,7 @@ Components.prototype.list = function() {
var usedPropTypes = {};
// Find props used in components for which we are not confident
for (var i in this._list) {
if (!this._list.hasOwnProperty(i) || this._list[i].confidence >= 2) {
if (!has(this._list, i) || this._list[i].confidence >= 2) {
continue;
}
var component = null;
Expand All @@ -105,7 +106,7 @@ Components.prototype.list = function() {
}
// Assign used props in not confident components to the parent component
for (var j in this._list) {
if (!this._list.hasOwnProperty(j) || this._list[j].confidence < 2) {
if (!has(this._list, j) || this._list[j].confidence < 2) {
continue;
}
var id = this._getId(this._list[j].node);
Expand All @@ -126,7 +127,7 @@ Components.prototype.list = function() {
Components.prototype.length = function() {
var length = 0;
for (var i in this._list) {
if (!this._list.hasOwnProperty(i) || this._list[i].confidence < 2) {
if (!has(this._list, i) || this._list[i].confidence < 2) {
continue;
}
length++;
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"bugs": "https://github.com/yannickcr/eslint-plugin-react/issues",
"dependencies": {
"doctrine": "^1.2.2",
"has": "^1.0.1",
"jsx-ast-utils": "^1.3.3"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion tests/lib/rules/no-unused-prop-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ ruleTester.run('no-unused-prop-types', rule, {
code: [
'class Hello extends React.Component {',
' render() {',
' if (this.props.hasOwnProperty(\'firstname\')) {',
' if (Object.prototype.hasOwnProperty.call(this.props, \'firstname\')) {',
' return <div>Hello {this.props.firstname}</div>;',
' }',
' return <div>Hello</div>;',
Expand Down
2 changes: 1 addition & 1 deletion tests/lib/rules/prop-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ ruleTester.run('prop-types', rule, {
code: [
'class Hello extends React.Component {',
' render() {',
' if (this.props.hasOwnProperty(\'firstname\')) {',
' if (Object.prototype.hasOwnProperty.call(this.props, \'firstname\')) {',
' return <div>Hello {this.props.firstname}</div>;',
' }',
' return <div>Hello</div>;',
Expand Down

0 comments on commit bffd3aa

Please sign in to comment.