From 20b1ff783899f8dab8a7771814146fe072fe539e Mon Sep 17 00:00:00 2001 From: Richard Bradley Date: Wed, 17 Feb 2016 10:46:48 +0000 Subject: [PATCH] #863 Add "hasOwnProperty" guard to all "for .. in" statements --- .../ng-admin/Crud/button/maExportToCsvButton.js | 1 + .../ng-admin/Crud/field/maButtonField.js | 1 + .../ng-admin/Crud/field/maCheckboxField.js | 1 + .../ng-admin/Crud/field/maChoiceField.js | 1 + .../ng-admin/Crud/field/maChoicesField.js | 1 + .../ng-admin/Crud/field/maDateField.js | 1 + .../ng-admin/Crud/field/maFileField.js | 3 +++ .../ng-admin/Crud/field/maInputField.js | 1 + .../ng-admin/Crud/field/maJsonField.js | 1 + .../ng-admin/Crud/field/maTextField.js | 1 + .../ng-admin/Crud/list/ListController.js | 1 + .../ng-admin/Crud/list/ListLayoutController.js | 1 + src/javascripts/ng-admin/Crud/routing.js | 10 ++++++++++ .../Main/component/filter/OrderElement.js | 1 + src/javascripts/ng-admin/Main/config/routing.js | 3 +++ src/javascripts/test/before_all.js | 16 ++++++++++++++++ src/javascripts/test/karma.conf.js | 1 + 17 files changed, 45 insertions(+) create mode 100644 src/javascripts/test/before_all.js diff --git a/src/javascripts/ng-admin/Crud/button/maExportToCsvButton.js b/src/javascripts/ng-admin/Crud/button/maExportToCsvButton.js index 29e44b5d..7901dd72 100644 --- a/src/javascripts/ng-admin/Crud/button/maExportToCsvButton.js +++ b/src/javascripts/ng-admin/Crud/button/maExportToCsvButton.js @@ -36,6 +36,7 @@ export default function maExportToCsvButton ($stateParams, Papa, notification, A .then(referenceData => { const references = exportView.getReferences(); for (var name in referenceData) { + if (!referenceData.hasOwnProperty(name)) continue; AdminDescription.getEntryConstructor().createArrayFromRest( referenceData[name], [references[name].targetField()], diff --git a/src/javascripts/ng-admin/Crud/field/maButtonField.js b/src/javascripts/ng-admin/Crud/field/maButtonField.js index 606c4993..fcea144a 100644 --- a/src/javascripts/ng-admin/Crud/field/maButtonField.js +++ b/src/javascripts/ng-admin/Crud/field/maButtonField.js @@ -18,6 +18,7 @@ export default function maButtonField() { var a = element.children()[0]; var attributes = field.attributes(); for (var name in attributes) { + if (!attributes.hasOwnProperty(name)) continue; a.setAttribute(name, attributes[name]); } scope.toggle = function() { diff --git a/src/javascripts/ng-admin/Crud/field/maCheckboxField.js b/src/javascripts/ng-admin/Crud/field/maCheckboxField.js index d126ca05..06c9678f 100644 --- a/src/javascripts/ng-admin/Crud/field/maCheckboxField.js +++ b/src/javascripts/ng-admin/Crud/field/maCheckboxField.js @@ -18,6 +18,7 @@ export default function maCheckboxField() { var input = element.children()[0]; var attributes = field.attributes(); for (var name in attributes) { + if (!attributes.hasOwnProperty(name)) continue; input.setAttribute(name, attributes[name]); } }, diff --git a/src/javascripts/ng-admin/Crud/field/maChoiceField.js b/src/javascripts/ng-admin/Crud/field/maChoiceField.js index 44f8313f..92ecec6a 100644 --- a/src/javascripts/ng-admin/Crud/field/maChoiceField.js +++ b/src/javascripts/ng-admin/Crud/field/maChoiceField.js @@ -52,6 +52,7 @@ export default function maChoiceField($compile) { var select = element.children()[0]; for (var name in attributes) { + if (!attributes.hasOwnProperty(name)) continue; select.setAttribute(name, attributes[name]); } diff --git a/src/javascripts/ng-admin/Crud/field/maChoicesField.js b/src/javascripts/ng-admin/Crud/field/maChoicesField.js index 78c79405..0a96afaf 100644 --- a/src/javascripts/ng-admin/Crud/field/maChoicesField.js +++ b/src/javascripts/ng-admin/Crud/field/maChoicesField.js @@ -52,6 +52,7 @@ export default function maChoicesField($compile) { var select = element.children()[0]; for (var name in attributes) { + if (!attributes.hasOwnProperty(name)) continue; select.setAttribute(name, attributes[name]); } diff --git a/src/javascripts/ng-admin/Crud/field/maDateField.js b/src/javascripts/ng-admin/Crud/field/maDateField.js index 2ee04400..363c4e99 100644 --- a/src/javascripts/ng-admin/Crud/field/maDateField.js +++ b/src/javascripts/ng-admin/Crud/field/maDateField.js @@ -27,6 +27,7 @@ export default function maDateField() { var input = element.find('input').eq(0); var attributes = field.attributes(); for (var name in attributes) { + if (!attributes.hasOwnProperty(name)) continue; input.attr(name, attributes[name]); } scope.toggleDatePicker = function ($event) { diff --git a/src/javascripts/ng-admin/Crud/field/maFileField.js b/src/javascripts/ng-admin/Crud/field/maFileField.js index 1ee30320..58687475 100644 --- a/src/javascripts/ng-admin/Crud/field/maFileField.js +++ b/src/javascripts/ng-admin/Crud/field/maFileField.js @@ -27,6 +27,7 @@ export default function maFileField(Upload) { var files = scope.value ? scope.value.split(',') : []; scope.files = {}; for (var file in files) { + if (!files.hasOwnProperty(file)) continue; scope.files[files[file]] = { "name": files[file], "progress": 0 @@ -43,6 +44,7 @@ export default function maFileField(Upload) { var input = element.find('input')[0]; var attributes = field.attributes(); for (var name in attributes) { + if (!attributes.hasOwnProperty(name)) continue; input.setAttribute(name, attributes[name]); } @@ -55,6 +57,7 @@ export default function maFileField(Upload) { scope.files = {}; for (var file in selectedFiles) { + if (!selectedFiles.hasOwnProperty(file)) continue; uploadParams = angular.copy(scope.field().uploadInformation()); uploadParams.file = selectedFiles[file]; Upload diff --git a/src/javascripts/ng-admin/Crud/field/maInputField.js b/src/javascripts/ng-admin/Crud/field/maInputField.js index f929cc35..cc37f44b 100644 --- a/src/javascripts/ng-admin/Crud/field/maInputField.js +++ b/src/javascripts/ng-admin/Crud/field/maInputField.js @@ -19,6 +19,7 @@ export default function maInputField() { var input = element.children()[0]; var attributes = field.attributes(); for (var name in attributes) { + if (!attributes.hasOwnProperty(name)) continue; if (name === 'step') { // allow to use `step` attribute instead of `scope.step` scope.step = attributes[name]; continue; diff --git a/src/javascripts/ng-admin/Crud/field/maJsonField.js b/src/javascripts/ng-admin/Crud/field/maJsonField.js index 08ba2c40..60ca60ce 100644 --- a/src/javascripts/ng-admin/Crud/field/maJsonField.js +++ b/src/javascripts/ng-admin/Crud/field/maJsonField.js @@ -40,6 +40,7 @@ export default function maJsonField() { var input = element.children()[0]; var attributes = field.attributes(); for (var name in attributes) { + if (!attributes.hasOwnProperty(name)) continue; input.setAttribute(name, attributes[name]); } scope.$watch('jsonValue', function(jsonValue) { diff --git a/src/javascripts/ng-admin/Crud/field/maTextField.js b/src/javascripts/ng-admin/Crud/field/maTextField.js index 6e91da48..e75d7737 100644 --- a/src/javascripts/ng-admin/Crud/field/maTextField.js +++ b/src/javascripts/ng-admin/Crud/field/maTextField.js @@ -17,6 +17,7 @@ export default function maTextField() { var input = element.children()[0]; var attributes = field.attributes(); for (var name in attributes) { + if (!attributes.hasOwnProperty(name)) continue; input.setAttribute(name, attributes[name]); } }, diff --git a/src/javascripts/ng-admin/Crud/list/ListController.js b/src/javascripts/ng-admin/Crud/list/ListController.js index 31642b73..32388c59 100644 --- a/src/javascripts/ng-admin/Crud/list/ListController.js +++ b/src/javascripts/ng-admin/Crud/list/ListController.js @@ -57,6 +57,7 @@ export default class ListController { this.progression.done(); for (var name in referenceData) { + if (!referenceData.hasOwnProperty(name)) continue; Entry.createArrayFromRest( referenceData[name], [references[name].targetField()], diff --git a/src/javascripts/ng-admin/Crud/list/ListLayoutController.js b/src/javascripts/ng-admin/Crud/list/ListLayoutController.js index 6e87a622..cded6bb1 100644 --- a/src/javascripts/ng-admin/Crud/list/ListLayoutController.js +++ b/src/javascripts/ng-admin/Crud/list/ListLayoutController.js @@ -96,6 +96,7 @@ export default class ListLayoutController { field, i; for (i in filters) { + if (!filters.hasOwnProperty(i)) continue; field = filters[i]; fieldName = field.name(); if (this.search[fieldName] === '') { diff --git a/src/javascripts/ng-admin/Crud/routing.js b/src/javascripts/ng-admin/Crud/routing.js index 0eed7c48..621f7a20 100644 --- a/src/javascripts/ng-admin/Crud/routing.js +++ b/src/javascripts/ng-admin/Crud/routing.js @@ -63,6 +63,7 @@ function routing($stateProvider) { filterEntries: ['dataStore', 'view', 'filterData', function (dataStore, view, filterData) { const filters = view.getFilterReferences(false); for (var name in filterData) { + if (!filterData.hasOwnProperty(name)) continue; Entry.createArrayFromRest( filterData[name], [filters[name].targetField()], @@ -107,6 +108,7 @@ function routing($stateProvider) { referenceEntries: ['dataStore', 'view', 'referenceData', function (dataStore, view, referenceData) { const references = view.getReferences(); for (var name in referenceData) { + if (!referenceData.hasOwnProperty(name)) continue; Entry.createArrayFromRest( referenceData[name], [references[name].targetField()], @@ -174,6 +176,7 @@ function routing($stateProvider) { referenceEntries: ['dataStore', 'view', 'referenceData', function (dataStore, view, referenceData) { const references = view.getReferences(); for (var name in referenceData) { + if (!referenceData.hasOwnProperty(name)) continue; Entry.createArrayFromRest( referenceData[name], [references[name].targetField()], @@ -188,6 +191,7 @@ function routing($stateProvider) { referencedListEntries: ['dataStore', 'view', 'referencedListData', function (dataStore, view, referencedListData) { const referencedLists = view.getReferencedLists(); for (var name in referencedLists) { + if (!referencedLists.hasOwnProperty(name)) continue; Entry.createArrayFromRest( referencedListData[name], referencedLists[name].targetFields(), @@ -213,6 +217,7 @@ function routing($stateProvider) { Object.keys(referencedLists).map(referencedListName => { const references = referencedLists[referencedListName].getReferences(); for (var name in references) { + if (!references.hasOwnProperty(name)) continue; if (!referenceDataForReferencedLists[referencedListName][name]) { continue; } @@ -269,6 +274,7 @@ function routing($stateProvider) { choiceEntries: ['dataStore', 'view', 'choiceData', function (dataStore, view, filterData) { const choices = view.getReferences(false); for (var name in filterData) { + if (!filterData.hasOwnProperty(name)) continue; Entry.createArrayFromRest( filterData[name], [choices[name].targetField()], @@ -320,6 +326,7 @@ function routing($stateProvider) { referenceEntries: ['dataStore', 'view', 'referenceData', function (dataStore, view, referenceData) { const references = view.getReferences(); for (var name in referenceData) { + if (!referenceData.hasOwnProperty(name)) continue; Entry.createArrayFromRest( referenceData[name], [references[name].targetField()], @@ -334,6 +341,7 @@ function routing($stateProvider) { referencedListEntries: ['dataStore', 'view', 'referencedListData', function (dataStore, view, referencedListData) { const referencedLists = view.getReferencedLists(); for (var name in referencedLists) { + if (!referencedLists.hasOwnProperty(name)) continue; Entry.createArrayFromRest( referencedListData[name], referencedLists[name].targetFields(), @@ -352,6 +360,7 @@ function routing($stateProvider) { choiceEntries: ['dataStore', 'view', 'choiceData', function (dataStore, view, filterData) { const choices = view.getReferences(false); for (var name in filterData) { + if (!filterData.hasOwnProperty(name)) continue; Entry.createArrayFromRest( filterData[name], [choices[name].targetField()], @@ -373,6 +382,7 @@ function routing($stateProvider) { Object.keys(referencedLists).map(referencedListName => { const references = referencedLists[referencedListName].getReferences(); for (var name in references) { + if (!references.hasOwnProperty(name)) continue; if (!referenceDataForReferencedLists[referencedListName][name]) { continue; } diff --git a/src/javascripts/ng-admin/Main/component/filter/OrderElement.js b/src/javascripts/ng-admin/Main/component/filter/OrderElement.js index b3c1a3a4..2c896895 100644 --- a/src/javascripts/ng-admin/Main/component/filter/OrderElement.js +++ b/src/javascripts/ng-admin/Main/component/filter/OrderElement.js @@ -4,6 +4,7 @@ export default function OrderElement() { objectKey; for (objectKey in input) { + if (!input.hasOwnProperty(objectKey)) continue; results.push(input[objectKey]); } diff --git a/src/javascripts/ng-admin/Main/config/routing.js b/src/javascripts/ng-admin/Main/config/routing.js index b279dad7..13c8b0d9 100644 --- a/src/javascripts/ng-admin/Main/config/routing.js +++ b/src/javascripts/ng-admin/Main/config/routing.js @@ -57,6 +57,7 @@ function routing($stateProvider, $urlRouterProvider) { collectionName; for (collectionName in collections) { + if (!collections.hasOwnProperty(collectionName)) continue; collection = collections[collectionName]; collectionSortField = collection.getSortFieldName(); collectionSortDir = collection.sortDir(); @@ -77,6 +78,7 @@ function routing($stateProvider, $urlRouterProvider) { .then(referenceData => { const references = collection.getReferences(); for (var name in referenceData) { + if (!referenceData.hasOwnProperty(name)) continue; Entry.createArrayFromRest( referenceData[name], [references[name].targetField()], @@ -103,6 +105,7 @@ function routing($stateProvider, $urlRouterProvider) { entries = {}; for (collectionName in responses) { + if (!responses.hasOwnProperty(collectionName)) continue; entries[collections[collectionName].name()] = responses[collectionName]; } diff --git a/src/javascripts/test/before_all.js b/src/javascripts/test/before_all.js new file mode 100644 index 00000000..96f1ee4d --- /dev/null +++ b/src/javascripts/test/before_all.js @@ -0,0 +1,16 @@ + +if (!Object.prototype.test_prototype_entry) { + Object.prototype.test_prototype_entry = + "Don't use for..in to enumerate Object properties, as users are free to " + + "add entries to the Object prototype, for example for polyfills. " + + "You should instead use\n" + + " for (let i in xs) { if (!xs.hasOwnProperty(i)) continue; var x = xs[i]; ... }"; +} + +if (!Array.prototype.test_prototype_entry) { + Array.prototype.test_prototype_entry = + "Don't use for..in to enumerate Array properties, as users are free to " + + "add entries to the Array prototype, for example for polyfills. " + + "You should instead use\n" + + " for (let i in xs) { if (!xs.hasOwnProperty(i)) continue; var x = xs[i]; ... }"; +} diff --git a/src/javascripts/test/karma.conf.js b/src/javascripts/test/karma.conf.js index 0c28df70..142f8f35 100644 --- a/src/javascripts/test/karma.conf.js +++ b/src/javascripts/test/karma.conf.js @@ -22,6 +22,7 @@ module.exports = function (config) { 'ng-admin.js', 'test/function.bind.shim.js', + 'test/before_all.js', 'test/unit/**/*.js' ], plugins: ['karma-webpack', 'karma-jasmine', 'karma-chrome-launcher', 'karma-phantomjs-launcher'],