Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/third_party/closure/goog/dom/asserts.js
4509 views
1
/**
2
* @license
3
* Copyright The Closure Library Authors.
4
* SPDX-License-Identifier: Apache-2.0
5
*/
6
7
goog.provide('goog.dom.asserts');
8
9
goog.require('goog.asserts');
10
11
goog.require('goog.utils');
12
13
/**
14
* @fileoverview Custom assertions to ensure that an element has the appropriate
15
* type.
16
*
17
* Using a goog.dom.safe wrapper on an object on the incorrect type (via an
18
* incorrect static type cast) can result in security bugs: For instance,
19
* g.d.s.setAnchorHref ensures that the URL assigned to the .href attribute
20
* satisfies the SafeUrl contract, i.e., is safe to dereference as a hyperlink.
21
* However, the value assigned to a HTMLLinkElement's .href property requires
22
* the stronger TrustedResourceUrl contract, since it can refer to a stylesheet.
23
* Thus, using g.d.s.setAnchorHref on an (incorrectly statically typed) object
24
* of type HTMLLinkElement can result in a security vulnerability.
25
* Assertions of the correct run-time type help prevent such incorrect use.
26
*
27
* In some cases, code using the DOM API is tested using mock objects (e.g., a
28
* plain object such as {'href': url} instead of an actual Location object).
29
* To allow such mocking, the assertions permit objects of types that are not
30
* relevant DOM API objects at all (for instance, not Element or Location).
31
*
32
* Note that instanceof checks don't work straightforwardly in older versions of
33
* IE, or across frames (see,
34
* http://stackoverflow.com/questions/384286/javascript-isdom-how-do-you-check-if-a-javascript-object-is-a-dom-object,
35
* http://stackoverflow.com/questions/26248599/instanceof-htmlelement-in-iframe-is-not-element-or-object).
36
*
37
* Hence, these assertions may pass vacuously in such scenarios. The resulting
38
* risk of security bugs is limited by the following factors:
39
* - A bug can only arise in scenarios involving incorrect static typing (the
40
* wrapper methods are statically typed to demand objects of the appropriate,
41
* precise type).
42
* - Typically, code is tested and exercised in multiple browsers.
43
*/
44
45
/**
46
* Asserts that a given object is a Location.
47
*
48
* To permit this assertion to pass in the context of tests where DOM APIs might
49
* be mocked, also accepts any other type except for subtypes of {!Element}.
50
* This is to ensure that, for instance, HTMLLinkElement is not being used in
51
* place of a Location, since this could result in security bugs due to stronger
52
* contracts required for assignments to the href property of the latter.
53
*
54
* @param {?Object} o The object whose type to assert.
55
* @return {!Location}
56
*/
57
goog.dom.asserts.assertIsLocation = function(o) {
58
'use strict';
59
if (goog.asserts.ENABLE_ASSERTS) {
60
var win = goog.dom.asserts.getWindow_(o);
61
if (win) {
62
if (!o || (!(o instanceof win.Location) && o instanceof win.Element)) {
63
goog.asserts.fail(
64
'Argument is not a Location (or a non-Element mock); got: %s',
65
goog.dom.asserts.debugStringForType_(o));
66
}
67
}
68
}
69
return /** @type {!Location} */ (o);
70
};
71
72
73
/**
74
* Returns a string representation of a value's type.
75
*
76
* @param {*} value An object, or primitive.
77
* @return {string} The best display name for the value.
78
* @private
79
*/
80
goog.dom.asserts.debugStringForType_ = function(value) {
81
'use strict';
82
if (goog.utils.isObject(value)) {
83
try {
84
return /** @type {string|undefined} */ (value.constructor.displayName) ||
85
value.constructor.name || Object.prototype.toString.call(value);
86
} catch (e) {
87
return '<object could not be stringified>';
88
}
89
} else {
90
return value === undefined ? 'undefined' :
91
value === null ? 'null' : typeof value;
92
}
93
};
94
95
/**
96
* Gets window of element.
97
* @param {?Object} o
98
* @return {?Window}
99
* @private
100
* @suppress {strictMissingProperties} ownerDocument not defined on Object
101
*/
102
goog.dom.asserts.getWindow_ = function(o) {
103
'use strict';
104
try {
105
var doc = o && o.ownerDocument;
106
// This can throw “Blocked a frame with origin "chrome-extension://..." from
107
// accessing a cross-origin frame” in Chrome extension.
108
var win =
109
doc && /** @type {?Window} */ (doc.defaultView || doc.parentWindow);
110
win = win || /** @type {!Window} */ (goog.global);
111
// This can throw “Permission denied to access property "Element" on
112
// cross-origin object”.
113
if (win.Element && win.Location) {
114
return win;
115
}
116
} catch (ex) {
117
}
118
return null;
119
};
120
121