-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathitem_43.js
More file actions
98 lines (69 loc) · 2.13 KB
/
item_43.js
File metadata and controls
98 lines (69 loc) · 2.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// Build lightweight Dictionaries from direct instances of 'object'
var dict = { nick: 16, son: 32, kaigi: 64};
var people = [];
// JavaScript provieds 'for...in' loop to enumerate the property names of an
// object
for (var name in dict) {
people.push(name + ": " + dict[name]);
}
people; // ["nick: 16", "son: 32", "kaigi: 64"]
// 'for...in' loop enumerates an object's inherited properties as well as its
// "own" properties
function NaiveDict() {}
NaiveDict.prototype.count = function() {
var i = 0;
for (var name in this) { // counts every property
i++;
}
return i;
};
NaiveDict.prototype.toString = function() {
return "[object NaiveDict]";
};
var dict = new NaiveDict();
dict.nick = 16;
dict.son = 32;
dict.kaigi = 64;
dict.count(); // 5
// problem is that we are using the same object to store both the fixed
// properties (count, toString) and the variable entries (nick, son, kaigi)
//
// A similar mistake is to use the 'Array' type to represent dictionaries
// example below
// this code is vulnerable to 'prototype pollution'
// where properties on a prototype object can cause unexpected properties to
// appear when enumerating dictionary entries
var dict = new Array();
dict.nick = 16;
dict.son = 32;
dict.kaigi = 64;
dict.nick; // 16
// Eg another library in the application may decide to add some convenience
// methods to 'Array.prototype'
Array.prototype.first = function() {
return this[0];
};
Array.prototype.last = function() {
return this[this.length - 1];
};
// now try to enumerate elements of the array
var names = [];
for (var name in dict) {
names.push(name);
}
names; // ["nick", "son", "kaigi", "first", "last"]
// Cardinal Rule: only use direct instances of 'Object' as dictionaries
var dict = {};
dict.nick = 16;
dict.son = 32;
dict.kaigi = 64;
var names = [];
for (var name in dict) {
names.push(name);
}
names; // ["nick", "son", "kaigi"]
// While this implentatin is not safe from pollution,
// but by using 'Object' we localize the risk to 'Object.prototype' alone
//
// see item_47: NEVER add properties to 'Object.prototype' that could pollute
// a 'for...in' loop