OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 var logging = requireNative('logging'); | |
6 | |
5 /** | 7 /** |
6 * Returns a function that logs a 'not available' error to the console and | 8 * Returns a function that logs a 'not available' error to the console and |
7 * returns undefined. | 9 * returns undefined. |
8 * | 10 * |
9 * @param {string} messagePrefix text to prepend to the exception message. | 11 * @param {string} messagePrefix text to prepend to the exception message. |
10 */ | 12 */ |
11 function generateDisabledMethodStub(messagePrefix, opt_messageSuffix) { | 13 function generateDisabledMethodStub(messagePrefix, opt_messageSuffix) { |
12 var message = messagePrefix + ' is not available in packaged apps.'; | 14 var message = messagePrefix + ' is not available in packaged apps.'; |
13 if (opt_messageSuffix) message = message + ' ' + opt_messageSuffix; | 15 if (opt_messageSuffix) message = message + ' ' + opt_messageSuffix; |
14 return function() { | 16 return function() { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
58 * preferred. | 60 * preferred. |
59 * @param {string} objectName The display name to use in the error message | 61 * @param {string} objectName The display name to use in the error message |
60 * thrown by the stub (this is the name that the object is commonly referred | 62 * thrown by the stub (this is the name that the object is commonly referred |
61 * to by web developers, e.g. "document" instead of "HTMLDocument"). | 63 * to by web developers, e.g. "document" instead of "HTMLDocument"). |
62 * @param {Array<string>} methodNames names of methods to disable. | 64 * @param {Array<string>} methodNames names of methods to disable. |
63 * @param {Boolean} useThrowingStubs if true, the replaced methods will throw | 65 * @param {Boolean} useThrowingStubs if true, the replaced methods will throw |
64 * an error instead of silently returning undefined | 66 * an error instead of silently returning undefined |
65 */ | 67 */ |
66 function disableMethods(object, objectName, methodNames, useThrowingStubs) { | 68 function disableMethods(object, objectName, methodNames, useThrowingStubs) { |
67 $Array.forEach(methodNames, function(methodName) { | 69 $Array.forEach(methodNames, function(methodName) { |
70 logging.DCHECK($Object.getOwnPropertyDescriptor(object, methodName), | |
71 objectName + ': ' + methodName); | |
68 var messagePrefix = objectName + '.' + methodName + '()'; | 72 var messagePrefix = objectName + '.' + methodName + '()'; |
69 object[methodName] = useThrowingStubs ? | 73 $Object.defineProperty(object, methodName, { |
70 generateThrowingMethodStub(messagePrefix) : | 74 configurable: false, |
71 generateDisabledMethodStub(messagePrefix); | 75 enumerable: false, |
76 value: useThrowingStubs ? | |
77 generateThrowingMethodStub(messagePrefix) : | |
78 generateDisabledMethodStub(messagePrefix) | |
79 }); | |
72 }); | 80 }); |
73 } | 81 } |
74 | 82 |
75 /** | 83 /** |
76 * Replaces the given properties of the passed in object with stubs that log | 84 * Replaces the given properties of the passed in object with stubs that log |
77 * 'not available' warnings to the console and return undefined when gotten. If | 85 * 'not available' warnings to the console and return undefined when gotten. If |
78 * a property's setter is later invoked, the getter and setter are restored to | 86 * a property's setter is later invoked, the getter and setter are restored to |
79 * default behaviors. | 87 * default behaviors. |
80 * | 88 * |
81 * @param {Object} object The object with properties to disable. The prototype | 89 * @param {Object} object The object with properties to disable. The prototype |
82 * is preferred. | 90 * is preferred. |
83 * @param {string} objectName The display name to use in the error message | 91 * @param {string} objectName The display name to use in the error message |
84 * thrown by the getter stub (this is the name that the object is commonly | 92 * thrown by the getter stub (this is the name that the object is commonly |
85 * referred to by web developers, e.g. "document" instead of | 93 * referred to by web developers, e.g. "document" instead of |
86 * "HTMLDocument"). | 94 * "HTMLDocument"). |
87 * @param {Array<string>} propertyNames names of properties to disable. | 95 * @param {Array<string>} propertyNames names of properties to disable. |
96 * @param {?string=} opt_messageSuffix An optional suffix for the message. | |
97 * @param {boolean=} opt_ignoreMissingProperty True if we allow disabling | |
98 * getters for non-existent properties. | |
88 */ | 99 */ |
89 function disableGetters(object, objectName, propertyNames, opt_messageSuffix) { | 100 function disableGetters(object, objectName, propertyNames, opt_messageSuffix, |
101 opt_ignoreMissingProperty) { | |
90 $Array.forEach(propertyNames, function(propertyName) { | 102 $Array.forEach(propertyNames, function(propertyName) { |
103 logging.DCHECK(opt_ignoreMissingProperty || | |
104 $Object.getOwnPropertyDescriptor(object, propertyName), | |
105 objectName + ': ' + propertyName); | |
91 var stub = generateDisabledMethodStub(objectName + '.' + propertyName, | 106 var stub = generateDisabledMethodStub(objectName + '.' + propertyName, |
92 opt_messageSuffix); | 107 opt_messageSuffix); |
93 stub._is_platform_app_disabled_getter = true; | 108 stub._is_platform_app_disabled_getter = true; |
94 $Object.defineProperty(object, propertyName, { | 109 $Object.defineProperty(object, propertyName, { |
95 configurable: true, | 110 configurable: true, |
96 enumerable: false, | 111 enumerable: false, |
97 get: stub, | 112 get: stub, |
98 set: function(value) { | 113 set: function(value) { |
99 var descriptor = $Object.getOwnPropertyDescriptor(this, propertyName); | 114 var descriptor = $Object.getOwnPropertyDescriptor(this, propertyName); |
100 if (!descriptor || !descriptor.get || | 115 if (!descriptor || !descriptor.get || |
(...skipping 22 matching lines...) Expand all Loading... | |
123 * @param {Object} object The object with properties to disable. The prototype | 138 * @param {Object} object The object with properties to disable. The prototype |
124 * is preferred. | 139 * is preferred. |
125 * @param {string} objectName The display name to use in the error message | 140 * @param {string} objectName The display name to use in the error message |
126 * thrown by the setter stub (this is the name that the object is commonly | 141 * thrown by the setter stub (this is the name that the object is commonly |
127 * referred to by web developers, e.g. "document" instead of | 142 * referred to by web developers, e.g. "document" instead of |
128 * "HTMLDocument"). | 143 * "HTMLDocument"). |
129 * @param {Array<string>} propertyNames names of properties to disable. | 144 * @param {Array<string>} propertyNames names of properties to disable. |
130 */ | 145 */ |
131 function disableSetters(object, objectName, propertyNames, opt_messageSuffix) { | 146 function disableSetters(object, objectName, propertyNames, opt_messageSuffix) { |
132 $Array.forEach(propertyNames, function(propertyName) { | 147 $Array.forEach(propertyNames, function(propertyName) { |
148 logging.DCHECK($Object.getOwnPropertyDescriptor(object, propertyName), | |
149 objectName + ': ' + propertyName); | |
133 var stub = generateDisabledMethodStub(objectName + '.' + propertyName, | 150 var stub = generateDisabledMethodStub(objectName + '.' + propertyName, |
134 opt_messageSuffix); | 151 opt_messageSuffix); |
135 $Object.defineProperty(object, propertyName, { | 152 $Object.defineProperty(object, propertyName, { |
136 configurable: true, | 153 configurable: false, |
137 enumerable: false, | 154 enumerable: false, |
138 get: function() { | 155 get: function() { |
139 return; | 156 return; |
140 }, | 157 }, |
141 set: stub | 158 set: stub |
142 }); | 159 }); |
143 }); | 160 }); |
144 } | 161 } |
145 | 162 |
146 // Disable benign Document methods. | 163 // Disable benign Document methods. |
147 disableMethods(HTMLDocument.prototype, 'document', ['open', 'clear', 'close']); | 164 disableMethods(Document.prototype, 'document', ['open', 'close']); |
165 disableMethods(HTMLDocument.prototype, 'document', ['clear']); | |
148 | 166 |
149 // Replace evil Document methods with exception-throwing stubs. | 167 // Replace evil Document methods with exception-throwing stubs. |
150 disableMethods(HTMLDocument.prototype, 'document', ['write', 'writeln'], true); | 168 disableMethods(Document.prototype, 'document', ['write', 'writeln'], true); |
151 | 169 |
152 // Disable history. | 170 // Disable history. |
153 Object.defineProperty(window, "history", { value: {} }); | 171 Object.defineProperty(window, "history", { value: {} }); |
172 // Note: we just blew away the history object, so we need to ignore the fact | |
173 // that these properties aren't defined on the object. | |
154 disableGetters(window.history, 'history', | 174 disableGetters(window.history, 'history', |
155 ['back', 'forward', 'go', 'length', 'pushState', 'replaceState', 'state']); | 175 ['back', 'forward', 'go', 'length', 'pushState', 'replaceState', 'state'], |
176 null, true); | |
156 | 177 |
157 // Disable find. | 178 // Disable find. |
158 disableMethods(window, 'window', ['find']); | 179 disableMethods(window, 'window', ['find']); |
159 disableMethods(Window.prototype, 'window', ['find']); | |
160 | 180 |
161 // Disable modal dialogs. Shell windows disable these anyway, but it's nice to | 181 // Disable modal dialogs. Shell windows disable these anyway, but it's nice to |
162 // warn. | 182 // warn. |
163 disableMethods(window, 'window', ['alert', 'confirm', 'prompt']); | 183 disableMethods(window, 'window', ['alert', 'confirm', 'prompt']); |
164 disableMethods(Window.prototype, 'window', ['alert', 'confirm', 'prompt']); | |
165 | 184 |
166 // Disable window.*bar. | 185 // Disable window.*bar. |
167 disableGetters(window, 'window', | 186 disableGetters(window, 'window', |
168 ['locationbar', 'menubar', 'personalbar', 'scrollbars', 'statusbar', | 187 ['locationbar', 'menubar', 'personalbar', 'scrollbars', 'statusbar', |
169 'toolbar']); | 188 'toolbar']); |
170 | 189 |
171 // Disable window.localStorage. | 190 // Disable window.localStorage. |
172 // Sometimes DOM security policy prevents us from doing this (e.g. for data: | 191 // Sometimes DOM security policy prevents us from doing this (e.g. for data: |
173 // URLs) so wrap in try-catch. | 192 // URLs) so wrap in try-catch. |
174 try { | 193 try { |
(...skipping 17 matching lines...) Expand all Loading... | |
192 // To deprecate document.all, simply changing its getter and setter would | 211 // To deprecate document.all, simply changing its getter and setter would |
193 // activate its cache mechanism, and degrade the performance. Here we assign | 212 // activate its cache mechanism, and degrade the performance. Here we assign |
194 // it first to 'undefined' to avoid this. | 213 // it first to 'undefined' to avoid this. |
195 document.all = undefined; | 214 document.all = undefined; |
196 disableGetters(document, 'document', | 215 disableGetters(document, 'document', |
197 ['alinkColor', 'all', 'bgColor', 'fgColor', 'linkColor', 'vlinkColor']); | 216 ['alinkColor', 'all', 'bgColor', 'fgColor', 'linkColor', 'vlinkColor']); |
198 }, true); | 217 }, true); |
199 | 218 |
200 // Disable onunload, onbeforeunload. | 219 // Disable onunload, onbeforeunload. |
201 disableSetters(window, 'window', ['onbeforeunload', 'onunload']); | 220 disableSetters(window, 'window', ['onbeforeunload', 'onunload']); |
202 disableSetters(Window.prototype, 'window', ['onbeforeunload', 'onunload']); | |
203 var eventTargetAddEventListener = EventTarget.prototype.addEventListener; | 221 var eventTargetAddEventListener = EventTarget.prototype.addEventListener; |
204 EventTarget.prototype.addEventListener = function(type) { | 222 EventTarget.prototype.addEventListener = function() { |
223 var args = $Array.slice(arguments); | |
224 // Note: Force conversion to a string in order to catch any funny attempts | |
225 // to pass in something that evals to 'load' but wouldn't === 'load'. | |
robwu
2016/02/19 22:32:15
Nit: 'load' -> 'onload'
Devlin
2016/02/19 23:23:11
s/onload/unload Done.
| |
226 var type = args[0] + ''; | |
robwu
2016/02/19 22:32:15
Sorry, this is still not sufficient.
You have to
Devlin
2016/02/19 23:23:11
Ah, I missed a few of the subtleties when I looked
| |
205 if (type === 'unload' || type === 'beforeunload') | 227 if (type === 'unload' || type === 'beforeunload') |
206 generateDisabledMethodStub(type)(); | 228 generateDisabledMethodStub(type)(); |
207 else | 229 else |
208 return $Function.apply(eventTargetAddEventListener, this, arguments); | 230 return $Function.apply(eventTargetAddEventListener, this, args); |
209 }; | 231 }; |
OLD | NEW |