1 | /*
|
2 | * Copyright (C) 2016 salesforce.com, inc.
|
3 | *
|
4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | * you may not use this file except in compliance with the License.
|
6 | * You may obtain a copy of the License at
|
7 | *
|
8 | * http://www.apache.org/licenses/LICENSE-2.0
|
9 | *
|
10 | * Unless required by applicable law or agreed to in writing, software
|
11 | * distributed under the License is distributed on an "AS IS" BASIS,
|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13 | * See the License for the specific language governing permissions and
|
14 | * limitations under the License.
|
15 | */
|
16 |
|
17 | ;
|
18 |
|
19 | var util = require('../lib/util.js');
|
20 | var intrinsics = require('../lib/3rdparty/ses/whitelist').whitelist;
|
21 | var anonIntrinsics = intrinsics.cajaVM.anonIntrinsics;
|
22 |
|
23 | module.exports = function(context) {
|
24 | var globalScope;
|
25 |
|
26 | return {
|
27 |
|
28 | "Program": function() {
|
29 | globalScope = context.getScope();
|
30 | },
|
31 |
|
32 | MemberExpression: function(node) {
|
33 | if (node.parent.type === "MemberExpression") {
|
34 | // ignoring intermediate member expressions
|
35 | return;
|
36 | }
|
37 | var currentScope = context.getScope();
|
38 | var ns = util.buildMemberExpressionNamespace(currentScope, globalScope, node);
|
39 | if (ns.length > 0) {
|
40 | var rootIdentifier = ns[0];
|
41 | if (rootIdentifier.type !== "Identifier" || util.isShadowed(currentScope, globalScope, rootIdentifier)) {
|
42 | return;
|
43 | }
|
44 | var api;
|
45 | if (intrinsics.hasOwnProperty(rootIdentifier.name)) {
|
46 | api = intrinsics;
|
47 | } else if (anonIntrinsics.hasOwnProperty(rootIdentifier.name)) {
|
48 | api = anonIntrinsics;
|
49 | } else {
|
50 | return; // nothing to do here, it is not intrinsic
|
51 | }
|
52 | for (var i = 0; i < ns.length; i++) {
|
53 | var identifier = ns[i];
|
54 | if (identifier.type !== 'Identifier') {
|
55 | context.report(node, "Invalid Intrinsic API, use dot notation instead");
|
56 | return;
|
57 | }
|
58 | var token = identifier.name;
|
59 | var nextIdentifier = ns[i + 1];
|
60 | if (typeof api !== "object") {
|
61 | context.report(node, "Invalid Intrinsic API");
|
62 | return;
|
63 | }
|
64 | if (!api.hasOwnProperty(token)) {
|
65 | context.report(node, "Invalid Intrinsic API");
|
66 | return;
|
67 | }
|
68 | if (api[token] === '*') {
|
69 | // anything from this point on is good
|
70 | return;
|
71 | }
|
72 | if (typeof (api[token]) === 'object' && Object.keys(api[token]).length === 0) {
|
73 | // nothing else to inspect
|
74 | return;
|
75 | }
|
76 | if (api[token] === true && !nextIdentifier) {
|
77 | // function call
|
78 | return;
|
79 | }
|
80 | if (api[token] === true && nextIdentifier && nextIdentifier.type === 'Identifier' && (nextIdentifier.name === 'apply' || nextIdentifier.name === 'call')) {
|
81 | // function call with .apply() or .call() are still valid
|
82 | return;
|
83 | }
|
84 | if (api[token] === false && nextIdentifier === undefined) {
|
85 | return;
|
86 | }
|
87 | api = api[token];
|
88 | }
|
89 | }
|
90 | }
|
91 | };
|
92 |
|
93 | };
|
94 |
|
95 | module.exports.schema = [];
|