@dacely/toildefender 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,55 +1,55 @@
1
- "use strict";
2
-
3
- var assert = require("assert");
4
-
5
- var _ = require("lodash");
6
- var escodegen = require("escodegen");
7
-
8
- var estest = require("../estest");
9
- var traverser = require("../traverser");
10
-
11
-
12
- module.exports = class Health {
13
-
14
- constructor (logger) {
15
- this.logger = logger;
16
- this.strict = false;
17
- }
18
-
19
- throwError (msg) {
20
- if (this.strict) {
21
- throw new Error(msg);
22
- } else {
23
- this.logger.warn(msg);
24
- }
25
- }
26
-
27
- /**
28
- * Perform various health checks on the AST without modifying it.
29
- * @param {Node} ast Root node
30
- * @returns {Node} Root node
31
- */
32
- check (ast) {
33
- var visited = [];
34
-
35
- traverser.traverse(ast, [], (node, stack) => {
36
- if (_.includes(visited, node)) {
37
- this.throwError("Node has multiple parents: " + JSON.stringify(node));
38
- } else {
39
- visited.push(node);
40
- }
41
-
42
- if (node.type == "BlockStatement") {
43
- node.body.forEach(stmt => {
44
- if (!estest.isStatement(stmt)) {
45
- this.throwError(JSON.stringify(stack[1], null, 2));
46
- }
47
- });
48
- }
49
-
50
- return node;
51
- });
52
-
53
- return ast;
54
- }
55
- };
1
+ "use strict";
2
+
3
+ var assert = require("assert");
4
+
5
+ var _ = require("lodash");
6
+ var escodegen = require("escodegen");
7
+
8
+ var estest = require("../estest");
9
+ var traverser = require("../traverser");
10
+
11
+
12
+ module.exports = class Health {
13
+
14
+ constructor (logger) {
15
+ this.logger = logger;
16
+ this.strict = false;
17
+ }
18
+
19
+ throwError (msg) {
20
+ if (this.strict) {
21
+ throw new Error(msg);
22
+ } else {
23
+ this.logger.warn(msg);
24
+ }
25
+ }
26
+
27
+ /**
28
+ * Perform various health checks on the AST without modifying it.
29
+ * @param {Node} ast Root node
30
+ * @returns {Node} Root node
31
+ */
32
+ check (ast) {
33
+ var visited = [];
34
+
35
+ traverser.traverse(ast, [], (node, stack) => {
36
+ if (_.includes(visited, node)) {
37
+ this.throwError("Node has multiple parents: " + JSON.stringify(node));
38
+ } else {
39
+ visited.push(node);
40
+ }
41
+
42
+ if (node.type == "BlockStatement") {
43
+ node.body.forEach(stmt => {
44
+ if (!estest.isStatement(stmt)) {
45
+ this.throwError(JSON.stringify(stack[1], null, 2));
46
+ }
47
+ });
48
+ }
49
+
50
+ return node;
51
+ });
52
+
53
+ return ast;
54
+ }
55
+ };
@@ -1,256 +1,256 @@
1
- "use strict";
2
-
3
- var assert = require("assert");
4
-
5
- var _ = require("lodash");
6
-
7
- var estest = require("../estest");
8
- var ESUtils = require("../esutils");
9
- var traverser = require("../traverser");
10
- var utils = require("../utils");
11
-
12
- function literal(value) {
13
- return { type: "Literal", value: value };
14
- }
15
-
16
- function encodeObjectKey(key, salt, index) {
17
- var encoded = [ key.length ^ ((salt + index * 131) & 65535) ];
18
- for (var i = 0; i < key.length; i += 1) {
19
- encoded.push(key.charCodeAt(i) ^ ((salt + index * 257 + i * 17) & 65535));
20
- }
21
- return encoded;
22
- }
23
-
24
- function objectKey(prop) {
25
- return prop.key.name || prop.key.value;
26
- }
27
-
28
- function isBigIntLiteral(node) {
29
- return node.type == "Literal" && typeof node.value == "bigint";
30
- }
31
-
32
- module.exports = class Identifiers {
33
-
34
- constructor (logger) {
35
- this.logger = logger;
36
- this.esutils = new ESUtils(logger);
37
- }
38
-
39
- /**
40
- * This checks whether the given node has a parent that
41
- * accepts undefined children without throwing errors.
42
- * Those cannot be moved to separate variables without
43
- * causing errors by assigning undefined variables
44
- * to new variables.
45
- * @param {Node} node
46
- * @returns {boolean}
47
- */
48
- hasParentAcceptingUndefined (node) {
49
- var parent = this.esutils.getParent(node);
50
- return parent
51
- && parent.type == "UnaryExpression"
52
- && _.includes([ "typeof", "delete" ], parent.operator);
53
- }
54
-
55
- /**
56
- * Replace property references like obj.prop with obj["prop"].
57
- * @param {Node} ast Root node
58
- * @returns {Node} Root node
59
- */
60
- computeProperties (ast) {
61
- assert.ok(estest.isNode(ast));
62
-
63
- ast = traverser.traverse(ast, [], (node, stack) => {
64
- if (node.type == "MemberExpression"
65
- && !node.computed) {
66
- assert(node.property.type == "Identifier");
67
- node.property = { type: "Literal", value: node.property.name };
68
- node.computed = true;
69
- }
70
-
71
- return node;
72
- });
73
-
74
- return ast;
75
- }
76
-
77
- /**
78
- * Replace objects with an array via veilmark$toObject.
79
- * @param {Node} ast Root node
80
- * @returns {Node} Root node
81
- */
82
- arrayizeObjects (ast, options) {
83
- assert.ok(estest.isNode(ast));
84
- options = options || {};
85
-
86
- ast = traverser.traverse(ast, [], (node, stack) => {
87
- if (node.type == "ObjectExpression") {
88
- if (options.objectPacking === false) {
89
- var arr = [];
90
- node.properties.forEach(prop => {
91
- arr.push(literal(objectKey(prop)));
92
- arr.push(prop.value);
93
- });
94
- return {
95
- type: "CallExpression",
96
- callee: { type: "Identifier", name: "veilmark$toObject" },
97
- arguments: [
98
- {
99
- type: "ArrayExpression",
100
- elements: arr
101
- }
102
- ]
103
- };
104
- }
105
-
106
- var salt = utils.random(1, 65535);
107
- var schema = [ salt, node.properties.length ];
108
- var values = [];
109
-
110
- node.properties.forEach(prop => {
111
- var key = objectKey(prop);
112
- encodeObjectKey(String(key), salt, values.length).forEach(value => schema.push(value));
113
- values.push(prop.value);
114
- });
115
-
116
- return {
117
- type: "CallExpression",
118
- callee: { type: "Identifier", name: "veilmark$toObject" },
119
- arguments: [
120
- {
121
- type: "ArrayExpression",
122
- elements: schema.map(literal)
123
- },
124
- {
125
- type: "ArrayExpression",
126
- elements: values
127
- }
128
- ]
129
- };
130
- }
131
-
132
- return node;
133
- });
134
-
135
- return ast;
136
- }
137
-
138
- // This seems to be ununsed.
139
- // TODO: Figure this out
140
- moveIdentifiers (ast, scopeManager) {
141
- assert.ok(estest.isNode(ast));
142
-
143
- var rng = new utils.UniqueRandomAlpha(3);
144
-
145
- this.esutils.setParentsRecursive(ast);
146
-
147
- scopeManager.scopes.forEach(scope => {
148
- /**
149
- * That could cause problems if there are multiple unresolved
150
- * references with the same name. (is that even possible?)
151
- */
152
-
153
- var replaced = new utils.HashMap();
154
-
155
- scope.references
156
- .filter(reference => !utils.isResolvedReference(reference))
157
- .forEach(reference => {
158
- if (replaced.exists(reference.identifier.name)) {
159
- reference.identifier.name = replaced.get(reference.identifier.name);
160
- } else if (!this.hasParentAcceptingUndefined(reference.identifier)) {
161
- var name = "$$ident$" + rng.get();
162
- replaced.set(reference.identifier.name, name);
163
-
164
- var init;
165
- if (reference.identifier.name == "undefined") {
166
- init = { type: "Identifier", name: "undefined" };
167
- } else {
168
- init = {
169
- type: "ConditionalExpression",
170
- test: {
171
- type: "BinaryExpression",
172
- operator: "!==",
173
- left: {
174
- type: "UnaryExpression",
175
- operator: "typeof",
176
- prefix: true,
177
- argument: { type: "Identifier", name: reference.identifier.name }
178
- },
179
- right: { type: "Literal", value: "undefined" }
180
- },
181
- consequent: { type: "Identifier", name: reference.identifier.name },
182
- alternate: { type: "Identifier", name: "undefined" }
183
- };
184
- }
185
-
186
- this.esutils.insertIntoScope(scope, {
187
- type: "VariableDeclaration",
188
- kind: "var",
189
- declarations: [
190
- {
191
- type: "VariableDeclarator",
192
- id: { type: "Identifier", name: name },
193
- init: init
194
- }
195
- ]
196
- });
197
-
198
- reference.identifier.name = name;
199
- }
200
- });
201
- });
202
-
203
- return ast;
204
- }
205
-
206
- /**
207
- * Move all literals into the veilmark$literals array.
208
- * @param {Node} ast Root node
209
- * @param {ScopeManager} scopeManager Scope manager
210
- * @returns {Node} Root node
211
- */
212
- moveLiterals (ast, scopeManager) {
213
- assert.ok(estest.isNode(ast));
214
-
215
- var rng = new utils.UniqueRandomAlpha(3);
216
-
217
- var vars = [];
218
-
219
- ast = traverser.traverse(ast, [], (node, stack) => {
220
- if (node.type == "Literal" && !isBigIntLiteral(node) && stack.length > 0 && stack[1].node.type != "Property") {
221
- var idx = vars.indexOf(node.value);
222
- if (idx == -1) {
223
- idx = vars.length;
224
- vars.push(node.value);
225
- }
226
-
227
- return {
228
- type: "MemberExpression",
229
- object: { type: "Identifier", name: "veilmark$literals" },
230
- property: { type: "Literal", value: idx },
231
- computed: true
232
- };
233
- }
234
-
235
- return node;
236
- });
237
-
238
- ast.body.splice(0, 0, {
239
- type: "VariableDeclaration",
240
- kind: "var",
241
- declarations: [
242
- {
243
- type: "VariableDeclarator",
244
- id: { type: "Identifier", name: "veilmark$literals" },
245
- init: {
246
- type: "ArrayExpression",
247
- elements: vars.map(x => ({ type: "Literal", value: x }))
248
- }
249
- }
250
- ]
251
- });
252
-
253
- return ast;
254
- }
255
-
256
- };
1
+ "use strict";
2
+
3
+ var assert = require("assert");
4
+
5
+ var _ = require("lodash");
6
+
7
+ var estest = require("../estest");
8
+ var ESUtils = require("../esutils");
9
+ var traverser = require("../traverser");
10
+ var utils = require("../utils");
11
+
12
+ function literal(value) {
13
+ return { type: "Literal", value: value };
14
+ }
15
+
16
+ function encodeObjectKey(key, salt, index) {
17
+ var encoded = [ key.length ^ ((salt + index * 131) & 65535) ];
18
+ for (var i = 0; i < key.length; i += 1) {
19
+ encoded.push(key.charCodeAt(i) ^ ((salt + index * 257 + i * 17) & 65535));
20
+ }
21
+ return encoded;
22
+ }
23
+
24
+ function objectKey(prop) {
25
+ return prop.key.name || prop.key.value;
26
+ }
27
+
28
+ function isBigIntLiteral(node) {
29
+ return node.type == "Literal" && typeof node.value == "bigint";
30
+ }
31
+
32
+ module.exports = class Identifiers {
33
+
34
+ constructor (logger) {
35
+ this.logger = logger;
36
+ this.esutils = new ESUtils(logger);
37
+ }
38
+
39
+ /**
40
+ * This checks whether the given node has a parent that
41
+ * accepts undefined children without throwing errors.
42
+ * Those cannot be moved to separate variables without
43
+ * causing errors by assigning undefined variables
44
+ * to new variables.
45
+ * @param {Node} node
46
+ * @returns {boolean}
47
+ */
48
+ hasParentAcceptingUndefined (node) {
49
+ var parent = this.esutils.getParent(node);
50
+ return parent
51
+ && parent.type == "UnaryExpression"
52
+ && _.includes([ "typeof", "delete" ], parent.operator);
53
+ }
54
+
55
+ /**
56
+ * Replace property references like obj.prop with obj["prop"].
57
+ * @param {Node} ast Root node
58
+ * @returns {Node} Root node
59
+ */
60
+ computeProperties (ast) {
61
+ assert.ok(estest.isNode(ast));
62
+
63
+ ast = traverser.traverse(ast, [], (node, stack) => {
64
+ if (node.type == "MemberExpression"
65
+ && !node.computed) {
66
+ assert(node.property.type == "Identifier");
67
+ node.property = { type: "Literal", value: node.property.name };
68
+ node.computed = true;
69
+ }
70
+
71
+ return node;
72
+ });
73
+
74
+ return ast;
75
+ }
76
+
77
+ /**
78
+ * Replace objects with an array via veilmark$toObject.
79
+ * @param {Node} ast Root node
80
+ * @returns {Node} Root node
81
+ */
82
+ arrayizeObjects (ast, options) {
83
+ assert.ok(estest.isNode(ast));
84
+ options = options || {};
85
+
86
+ ast = traverser.traverse(ast, [], (node, stack) => {
87
+ if (node.type == "ObjectExpression") {
88
+ if (options.objectPacking === false) {
89
+ var arr = [];
90
+ node.properties.forEach(prop => {
91
+ arr.push(literal(objectKey(prop)));
92
+ arr.push(prop.value);
93
+ });
94
+ return {
95
+ type: "CallExpression",
96
+ callee: { type: "Identifier", name: "veilmark$toObject" },
97
+ arguments: [
98
+ {
99
+ type: "ArrayExpression",
100
+ elements: arr
101
+ }
102
+ ]
103
+ };
104
+ }
105
+
106
+ var salt = utils.random(1, 65535);
107
+ var schema = [ salt, node.properties.length ];
108
+ var values = [];
109
+
110
+ node.properties.forEach(prop => {
111
+ var key = objectKey(prop);
112
+ encodeObjectKey(String(key), salt, values.length).forEach(value => schema.push(value));
113
+ values.push(prop.value);
114
+ });
115
+
116
+ return {
117
+ type: "CallExpression",
118
+ callee: { type: "Identifier", name: "veilmark$toObject" },
119
+ arguments: [
120
+ {
121
+ type: "ArrayExpression",
122
+ elements: schema.map(literal)
123
+ },
124
+ {
125
+ type: "ArrayExpression",
126
+ elements: values
127
+ }
128
+ ]
129
+ };
130
+ }
131
+
132
+ return node;
133
+ });
134
+
135
+ return ast;
136
+ }
137
+
138
+ // This seems to be ununsed.
139
+ // TODO: Figure this out
140
+ moveIdentifiers (ast, scopeManager) {
141
+ assert.ok(estest.isNode(ast));
142
+
143
+ var rng = new utils.UniqueRandomAlpha(3);
144
+
145
+ this.esutils.setParentsRecursive(ast);
146
+
147
+ scopeManager.scopes.forEach(scope => {
148
+ /**
149
+ * That could cause problems if there are multiple unresolved
150
+ * references with the same name. (is that even possible?)
151
+ */
152
+
153
+ var replaced = new utils.HashMap();
154
+
155
+ scope.references
156
+ .filter(reference => !utils.isResolvedReference(reference))
157
+ .forEach(reference => {
158
+ if (replaced.exists(reference.identifier.name)) {
159
+ reference.identifier.name = replaced.get(reference.identifier.name);
160
+ } else if (!this.hasParentAcceptingUndefined(reference.identifier)) {
161
+ var name = "$$ident$" + rng.get();
162
+ replaced.set(reference.identifier.name, name);
163
+
164
+ var init;
165
+ if (reference.identifier.name == "undefined") {
166
+ init = { type: "Identifier", name: "undefined" };
167
+ } else {
168
+ init = {
169
+ type: "ConditionalExpression",
170
+ test: {
171
+ type: "BinaryExpression",
172
+ operator: "!==",
173
+ left: {
174
+ type: "UnaryExpression",
175
+ operator: "typeof",
176
+ prefix: true,
177
+ argument: { type: "Identifier", name: reference.identifier.name }
178
+ },
179
+ right: { type: "Literal", value: "undefined" }
180
+ },
181
+ consequent: { type: "Identifier", name: reference.identifier.name },
182
+ alternate: { type: "Identifier", name: "undefined" }
183
+ };
184
+ }
185
+
186
+ this.esutils.insertIntoScope(scope, {
187
+ type: "VariableDeclaration",
188
+ kind: "var",
189
+ declarations: [
190
+ {
191
+ type: "VariableDeclarator",
192
+ id: { type: "Identifier", name: name },
193
+ init: init
194
+ }
195
+ ]
196
+ });
197
+
198
+ reference.identifier.name = name;
199
+ }
200
+ });
201
+ });
202
+
203
+ return ast;
204
+ }
205
+
206
+ /**
207
+ * Move all literals into the veilmark$literals array.
208
+ * @param {Node} ast Root node
209
+ * @param {ScopeManager} scopeManager Scope manager
210
+ * @returns {Node} Root node
211
+ */
212
+ moveLiterals (ast, scopeManager) {
213
+ assert.ok(estest.isNode(ast));
214
+
215
+ var rng = new utils.UniqueRandomAlpha(3);
216
+
217
+ var vars = [];
218
+
219
+ ast = traverser.traverse(ast, [], (node, stack) => {
220
+ if (node.type == "Literal" && !isBigIntLiteral(node) && stack.length > 0 && stack[1].node.type != "Property") {
221
+ var idx = vars.indexOf(node.value);
222
+ if (idx == -1) {
223
+ idx = vars.length;
224
+ vars.push(node.value);
225
+ }
226
+
227
+ return {
228
+ type: "MemberExpression",
229
+ object: { type: "Identifier", name: "veilmark$literals" },
230
+ property: { type: "Literal", value: idx },
231
+ computed: true
232
+ };
233
+ }
234
+
235
+ return node;
236
+ });
237
+
238
+ ast.body.splice(0, 0, {
239
+ type: "VariableDeclaration",
240
+ kind: "var",
241
+ declarations: [
242
+ {
243
+ type: "VariableDeclarator",
244
+ id: { type: "Identifier", name: "veilmark$literals" },
245
+ init: {
246
+ type: "ArrayExpression",
247
+ elements: vars.map(x => ({ type: "Literal", value: x }))
248
+ }
249
+ }
250
+ ]
251
+ });
252
+
253
+ return ast;
254
+ }
255
+
256
+ };