vega 0.3.1 → 0.4.0

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.
@@ -2,11 +2,10 @@
2
2
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3
3
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.vega = global.vega || {}));
5
- }(this, (function (exports) { 'use strict';
5
+ })(this, (function (exports) { 'use strict';
6
6
 
7
7
  function adjustSpatial (item, encode, swap) {
8
8
  let t;
9
-
10
9
  if (encode.x2) {
11
10
  if (encode.x) {
12
11
  if (swap && item.x > item.x2) {
@@ -14,17 +13,14 @@
14
13
  item.x = item.x2;
15
14
  item.x2 = t;
16
15
  }
17
-
18
16
  item.width = item.x2 - item.x;
19
17
  } else {
20
18
  item.x = item.x2 - (item.width || 0);
21
19
  }
22
20
  }
23
-
24
21
  if (encode.xc) {
25
22
  item.x = item.xc - (item.width || 0) / 2;
26
23
  }
27
-
28
24
  if (encode.y2) {
29
25
  if (encode.y) {
30
26
  if (swap && item.y > item.y2) {
@@ -32,13 +28,11 @@
32
28
  item.y = item.y2;
33
29
  item.y2 = t;
34
30
  }
35
-
36
31
  item.height = item.y2 - item.y;
37
32
  } else {
38
33
  item.y = item.y2 - (item.height || 0);
39
34
  }
40
35
  }
41
-
42
36
  if (encode.yc) {
43
37
  item.y = item.yc - (item.height || 0) / 2;
44
38
  }
@@ -88,14 +82,11 @@
88
82
  };
89
83
 
90
84
  const slice = Array.prototype.slice;
91
-
92
85
  const apply = (m, args, cast) => {
93
86
  const obj = cast ? cast(args[0]) : args[0];
94
87
  return obj[m].apply(obj, slice.call(args, 1));
95
88
  };
96
-
97
89
  const datetime = (y, m, d, H, M, S, ms) => new Date(y, m || 0, d != null ? d : 1, H || 0, M || 0, S || 0, ms || 0);
98
-
99
90
  var Functions = {
100
91
  // math functions
101
92
  isNaN: Number.isNaN,
@@ -177,6 +168,8 @@
177
168
  };
178
169
 
179
170
  const EventFunctions = ['view', 'item', 'group', 'xy', 'x', 'y'];
171
+ const DisallowedMethods = new Set([Function, eval, setTimeout, setInterval]);
172
+ if (typeof setImmediate === 'function') DisallowedMethods.add(setImmediate);
180
173
  const Visitors = {
181
174
  Literal: ($, n) => n.value,
182
175
  Identifier: ($, n) => {
@@ -185,22 +178,28 @@
185
178
  },
186
179
  MemberExpression: ($, n) => {
187
180
  const d = !n.computed,
188
- o = $(n.object);
181
+ o = $(n.object);
189
182
  if (d) $.memberDepth += 1;
190
183
  const p = $(n.property);
191
184
  if (d) $.memberDepth -= 1;
185
+ if (DisallowedMethods.has(o[p])) {
186
+ // eslint-disable-next-line no-console
187
+ console.error(`Prevented interpretation of member "${p}" which could lead to insecure code execution`);
188
+ return;
189
+ }
192
190
  return o[p];
193
191
  },
194
192
  CallExpression: ($, n) => {
195
193
  const args = n.arguments;
196
- let name = n.callee.name; // handle special internal functions used by encoders
197
- // re-route to corresponding standard function
194
+ let name = n.callee.name;
198
195
 
196
+ // handle special internal functions used by encoders
197
+ // re-route to corresponding standard function
199
198
  if (name.startsWith('_')) {
200
199
  name = name.slice(1);
201
- } // special case "if" due to conditional evaluation of branches
202
-
200
+ }
203
201
 
202
+ // special case "if" due to conditional evaluation of branches
204
203
  return name === 'if' ? $(args[0]) ? $(args[1]) : $(args[2]) : ($.fn[name] || Functions[name]).apply($.fn, args.map($));
205
204
  },
206
205
  ArrayExpression: ($, n) => n.elements.map($),
@@ -212,20 +211,25 @@
212
211
  $.memberDepth += 1;
213
212
  const k = $(p.key);
214
213
  $.memberDepth -= 1;
215
- o[k] = $(p.value);
214
+ if (DisallowedMethods.has($(p.value))) {
215
+ // eslint-disable-next-line no-console
216
+ console.error(`Prevented interpretation of property "${k}" which could lead to insecure code execution`);
217
+ } else {
218
+ o[k] = $(p.value);
219
+ }
216
220
  return o;
217
221
  }, {})
218
222
  };
219
223
  function interpret (ast, fn, params, datum, event, item) {
220
224
  const $ = n => Visitors[n.type]($, n);
221
-
222
225
  $.memberDepth = 0;
223
226
  $.fn = Object.create(fn);
224
227
  $.params = params;
225
228
  $.datum = datum;
226
229
  $.event = event;
227
- $.item = item; // route event functions to annotated vega event context
230
+ $.item = item;
228
231
 
232
+ // route event functions to annotated vega event context
229
233
  EventFunctions.forEach(f => $.fn[f] = (...args) => event.vega[f](...args));
230
234
  return $(ast);
231
235
  }
@@ -236,76 +240,65 @@
236
240
  */
237
241
  operator(ctx, expr) {
238
242
  const ast = expr.ast,
239
- fn = ctx.functions;
243
+ fn = ctx.functions;
240
244
  return _ => interpret(ast, fn, _);
241
245
  },
242
-
243
246
  /**
244
247
  * Parse an expression provided as an operator parameter value.
245
248
  */
246
249
  parameter(ctx, expr) {
247
250
  const ast = expr.ast,
248
- fn = ctx.functions;
251
+ fn = ctx.functions;
249
252
  return (datum, _) => interpret(ast, fn, _, datum);
250
253
  },
251
-
252
254
  /**
253
255
  * Parse an expression applied to an event stream.
254
256
  */
255
257
  event(ctx, expr) {
256
258
  const ast = expr.ast,
257
- fn = ctx.functions;
259
+ fn = ctx.functions;
258
260
  return event => interpret(ast, fn, undefined, undefined, event);
259
261
  },
260
-
261
262
  /**
262
263
  * Parse an expression used to handle an event-driven operator update.
263
264
  */
264
265
  handler(ctx, expr) {
265
266
  const ast = expr.ast,
266
- fn = ctx.functions;
267
+ fn = ctx.functions;
267
268
  return (_, event) => {
268
269
  const datum = event.item && event.item.datum;
269
270
  return interpret(ast, fn, _, datum, event);
270
271
  };
271
272
  },
272
-
273
273
  /**
274
274
  * Parse an expression that performs visual encoding.
275
275
  */
276
276
  encode(ctx, encode) {
277
277
  const {
278
- marktype,
279
- channels
280
- } = encode,
281
- fn = ctx.functions,
282
- swap = marktype === 'group' || marktype === 'image' || marktype === 'rect';
278
+ marktype,
279
+ channels
280
+ } = encode,
281
+ fn = ctx.functions,
282
+ swap = marktype === 'group' || marktype === 'image' || marktype === 'rect';
283
283
  return (item, _) => {
284
284
  const datum = item.datum;
285
285
  let m = 0,
286
- v;
287
-
286
+ v;
288
287
  for (const name in channels) {
289
288
  v = interpret(channels[name].ast, fn, _, datum, undefined, item);
290
-
291
289
  if (item[name] !== v) {
292
290
  item[name] = v;
293
291
  m = 1;
294
292
  }
295
293
  }
296
-
297
294
  if (marktype !== 'rule') {
298
295
  adjustSpatial(item, channels, swap);
299
296
  }
300
-
301
297
  return m;
302
298
  };
303
299
  }
304
-
305
300
  };
306
301
 
307
302
  exports.expressionInterpreter = expression;
308
303
 
309
- Object.defineProperty(exports, '__esModule', { value: true });
310
-
311
- })));
304
+ }));