Skip to content

Commit d9f6288

Browse files
committed
Always escape __proto__ in d3.{map,set}.
Rather than conditionally checking for it and changing the class definition, just be pessimissitic and assume that it’s a bad idea to set __proto__.
1 parent 09f43b1 commit d9f6288

File tree

4 files changed

+36
-133
lines changed

4 files changed

+36
-133
lines changed

d3.js

Lines changed: 17 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -259,42 +259,6 @@
259259
empty: d3_map_empty,
260260
forEach: d3_map_forEach
261261
};
262-
if (d3_map_proto in Object.create(null)) {
263-
d3_map_prototype.get = function(key) {
264-
return this._[d3_map_escape(key)];
265-
};
266-
d3_map_prototype.set = function(key, value) {
267-
return this._[d3_map_escape(key)] = value;
268-
};
269-
d3_map_prototype.has = function(key) {
270-
return d3_map_escape(key) in this._;
271-
};
272-
d3_map_prototype.remove = function(key) {
273-
return (key = d3_map_escape(key)) in this._ && delete this._[key];
274-
};
275-
d3_map_prototype.keys = function() {
276-
var keys = [];
277-
for (var key in this._) {
278-
keys.push(d3_map_unescape(key));
279-
}
280-
return keys;
281-
};
282-
d3_map_prototype.entries = function() {
283-
var entries = [];
284-
for (var key in this._) {
285-
entries.push({
286-
key: d3_map_unescape(key),
287-
value: this._[key]
288-
});
289-
}
290-
return entries;
291-
};
292-
d3_map_prototype.forEach = function(f) {
293-
for (var key in this._) {
294-
f.call(this, d3_map_unescape(key), this._[key]);
295-
}
296-
};
297-
}
298262
d3_class(d3_Map, d3_map_prototype);
299263
function d3_map_escape(key) {
300264
return (key += "") === d3_map_proto || key[0] === d3_map_zero ? d3_map_zero + key : key;
@@ -303,30 +267,33 @@
303267
return (key += "")[0] === d3_map_zero ? key.slice(1) : key;
304268
}
305269
function d3_map_get(key) {
306-
return this._[key];
270+
return this._[d3_map_escape(key)];
307271
}
308272
function d3_map_set(key, value) {
309-
return this._[key] = value;
273+
return this._[d3_map_escape(key)] = value;
310274
}
311275
function d3_map_has(key) {
312-
return key in this._;
276+
return d3_map_escape(key) in this._;
313277
}
314278
function d3_map_remove(key) {
315-
return key in this._ && delete this._[key];
279+
return (key = d3_map_escape(key)) in this._ && delete this._[key];
316280
}
317281
function d3_map_keys() {
318282
var keys = [];
319283
for (var key in this._) {
320-
keys.push(key);
284+
keys.push(d3_map_unescape(key));
321285
}
322286
return keys;
323287
}
324288
function d3_map_values() {
325-
var values = [];
289+
var entries = [];
326290
for (var key in this._) {
327-
values.push(this._[key]);
291+
entries.push({
292+
key: d3_map_unescape(key),
293+
value: this._[key]
294+
});
328295
}
329-
return values;
296+
return entries;
330297
}
331298
function d3_map_entries() {
332299
var entries = [];
@@ -353,7 +320,7 @@
353320
}
354321
function d3_map_forEach(f) {
355322
for (var key in this._) {
356-
f.call(this, key, this._[key]);
323+
f.call(this, d3_map_unescape(key), this._[key]);
357324
}
358325
}
359326
d3.nest = function() {
@@ -428,33 +395,22 @@
428395
this._ = Object.create(null);
429396
}
430397
var d3_set_prototype = {
431-
has: d3_map_prototype.has,
398+
has: d3_map_has,
432399
add: d3_set_add,
433-
remove: d3_map_prototype.remove,
434-
values: d3_map_prototype.keys,
400+
remove: d3_map_remove,
401+
values: d3_map_keys,
435402
size: d3_map_size,
436403
empty: d3_map_empty,
437404
forEach: d3_set_forEach
438405
};
439-
if (d3_map_proto in Object.create(null)) {
440-
d3_set_prototype.add = function(key) {
441-
this._[d3_map_escape(key)] = true;
442-
return key;
443-
};
444-
d3_set_prototype.forEach = function(f) {
445-
for (var key in this._) {
446-
f.call(this, d3_map_unescape(key));
447-
}
448-
};
449-
}
450406
d3_class(d3_Set, d3_set_prototype);
451407
function d3_set_add(key) {
452-
this._[key] = true;
408+
this._[d3_map_escape(key)] = true;
453409
return key;
454410
}
455411
function d3_set_forEach(f) {
456412
for (var key in this._) {
457-
f.call(this, key);
413+
f.call(this, d3_map_unescape(key));
458414
}
459415
}
460416
d3.behavior = {};

d3.min.js

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/arrays/map.js

Lines changed: 9 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -27,46 +27,6 @@ var d3_map_proto = "__proto__",
2727
forEach: d3_map_forEach
2828
};
2929

30-
if (d3_map_proto in Object.create(null)) {
31-
d3_map_prototype.get = function(key) {
32-
return this._[d3_map_escape(key)];
33-
};
34-
35-
d3_map_prototype.set = function(key, value) {
36-
return this._[d3_map_escape(key)] = value;
37-
};
38-
39-
d3_map_prototype.has = function(key) {
40-
return d3_map_escape(key) in this._;
41-
};
42-
43-
d3_map_prototype.remove = function(key) {
44-
return (key = d3_map_escape(key)) in this._ && delete this._[key];
45-
};
46-
47-
d3_map_prototype.keys = function() {
48-
var keys = [];
49-
for (var key in this._) {
50-
keys.push(d3_map_unescape(key));
51-
}
52-
return keys;
53-
};
54-
55-
d3_map_prototype.entries = function() {
56-
var entries = [];
57-
for (var key in this._) {
58-
entries.push({key: d3_map_unescape(key), value: this._[key]});
59-
}
60-
return entries;
61-
};
62-
63-
d3_map_prototype.forEach = function(f) {
64-
for (var key in this._) {
65-
f.call(this, d3_map_unescape(key), this._[key]);
66-
}
67-
};
68-
}
69-
7030
d3_class(d3_Map, d3_map_prototype);
7131

7232
function d3_map_escape(key) {
@@ -78,35 +38,35 @@ function d3_map_unescape(key) {
7838
}
7939

8040
function d3_map_get(key) {
81-
return this._[key];
41+
return this._[d3_map_escape(key)];
8242
}
8343

8444
function d3_map_set(key, value) {
85-
return this._[key] = value;
45+
return this._[d3_map_escape(key)] = value;
8646
}
8747

8848
function d3_map_has(key) {
89-
return key in this._;
49+
return d3_map_escape(key) in this._;
9050
}
9151

9252
function d3_map_remove(key) {
93-
return key in this._ && delete this._[key];
53+
return (key = d3_map_escape(key)) in this._ && delete this._[key];
9454
}
9555

9656
function d3_map_keys() {
9757
var keys = [];
9858
for (var key in this._) {
99-
keys.push(key);
59+
keys.push(d3_map_unescape(key));
10060
}
10161
return keys;
10262
}
10363

10464
function d3_map_values() {
105-
var values = [];
65+
var entries = [];
10666
for (var key in this._) {
107-
values.push(this._[key]);
67+
entries.push({key: d3_map_unescape(key), value: this._[key]});
10868
}
109-
return values;
69+
return entries;
11070
}
11171

11272
function d3_map_entries() {
@@ -134,6 +94,6 @@ function d3_map_empty() {
13494

13595
function d3_map_forEach(f) {
13696
for (var key in this._) {
137-
f.call(this, key, this._[key]);
97+
f.call(this, d3_map_unescape(key), this._[key]);
13898
}
13999
}

src/arrays/set.js

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,37 +12,24 @@ function d3_Set() {
1212
}
1313

1414
var d3_set_prototype = {
15-
has: d3_map_prototype.has,
15+
has: d3_map_has,
1616
add: d3_set_add,
17-
remove: d3_map_prototype.remove,
18-
values: d3_map_prototype.keys,
17+
remove: d3_map_remove,
18+
values: d3_map_keys,
1919
size: d3_map_size,
2020
empty: d3_map_empty,
2121
forEach: d3_set_forEach
2222
};
2323

24-
if (d3_map_proto in Object.create(null)) {
25-
d3_set_prototype.add = function(key) {
26-
this._[d3_map_escape(key)] = true;
27-
return key;
28-
};
29-
30-
d3_set_prototype.forEach = function(f) {
31-
for (var key in this._) {
32-
f.call(this, d3_map_unescape(key));
33-
}
34-
};
35-
}
36-
3724
d3_class(d3_Set, d3_set_prototype);
3825

3926
function d3_set_add(key) {
40-
this._[key] = true;
27+
this._[d3_map_escape(key)] = true;
4128
return key;
4229
}
4330

4431
function d3_set_forEach(f) {
4532
for (var key in this._) {
46-
f.call(this, key);
33+
f.call(this, d3_map_unescape(key));
4734
}
4835
}

0 commit comments

Comments
 (0)