Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/third_party/closure/goog/soy/data.js
2868 views
1
// Copyright 2012 The Closure Library Authors. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS-IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
/**
16
* @fileoverview Soy data primitives.
17
*
18
* The goal is to encompass data types used by Soy, especially to mark content
19
* as known to be "safe".
20
*
21
* @author [email protected] (Garrett Boyer)
22
*/
23
24
goog.provide('goog.soy.data.SanitizedContent');
25
goog.provide('goog.soy.data.SanitizedContentKind');
26
goog.provide('goog.soy.data.SanitizedCss');
27
goog.provide('goog.soy.data.SanitizedHtml');
28
goog.provide('goog.soy.data.SanitizedHtmlAttribute');
29
goog.provide('goog.soy.data.SanitizedJs');
30
goog.provide('goog.soy.data.SanitizedTrustedResourceUri');
31
goog.provide('goog.soy.data.SanitizedUri');
32
goog.provide('goog.soy.data.UnsanitizedText');
33
34
goog.require('goog.Uri');
35
goog.require('goog.html.SafeHtml');
36
goog.require('goog.html.SafeScript');
37
goog.require('goog.html.SafeStyle');
38
goog.require('goog.html.SafeUrl');
39
goog.require('goog.html.TrustedResourceUrl');
40
goog.require('goog.html.uncheckedconversions');
41
goog.require('goog.i18n.bidi.Dir');
42
goog.require('goog.string.Const');
43
44
45
/**
46
* A type of textual content.
47
*
48
* This is an enum of type Object so that these values are unforgeable.
49
*
50
* @enum {!Object}
51
*/
52
goog.soy.data.SanitizedContentKind = {
53
54
/**
55
* A snippet of HTML that does not start or end inside a tag, comment, entity,
56
* or DOCTYPE; and that does not contain any executable code
57
* (JS, {@code <object>}s, etc.) from a different trust domain.
58
*/
59
HTML: goog.DEBUG ? {sanitizedContentKindHtml: true} : {},
60
61
/**
62
* Executable Javascript code or expression, safe for insertion in a
63
* script-tag or event handler context, known to be free of any
64
* attacker-controlled scripts. This can either be side-effect-free
65
* Javascript (such as JSON) or Javascript that's entirely under Google's
66
* control.
67
*/
68
JS: goog.DEBUG ? {sanitizedContentJsChars: true} : {},
69
70
/** A properly encoded portion of a URI. */
71
URI: goog.DEBUG ? {sanitizedContentUri: true} : {},
72
73
/** A resource URI not under attacker control. */
74
TRUSTED_RESOURCE_URI:
75
goog.DEBUG ? {sanitizedContentTrustedResourceUri: true} : {},
76
77
/**
78
* Repeated attribute names and values. For example,
79
* {@code dir="ltr" foo="bar" onclick="trustedFunction()" checked}.
80
*/
81
ATTRIBUTES: goog.DEBUG ? {sanitizedContentHtmlAttribute: true} : {},
82
83
// TODO: Consider separating rules, declarations, and values into
84
// separate types, but for simplicity, we'll treat explicitly blessed
85
// SanitizedContent as allowed in all of these contexts.
86
/**
87
* A CSS3 declaration, property, value or group of semicolon separated
88
* declarations.
89
*/
90
CSS: goog.DEBUG ? {sanitizedContentCss: true} : {},
91
92
/**
93
* Unsanitized plain-text content.
94
*
95
* This is effectively the "null" entry of this enum, and is sometimes used
96
* to explicitly mark content that should never be used unescaped. Since any
97
* string is safe to use as text, being of ContentKind.TEXT makes no
98
* guarantees about its safety in any other context such as HTML.
99
*/
100
TEXT: goog.DEBUG ? {sanitizedContentKindText: true} : {}
101
};
102
103
104
105
/**
106
* A string-like object that carries a content-type and a content direction.
107
*
108
* IMPORTANT! Do not create these directly, nor instantiate the subclasses.
109
* Instead, use a trusted, centrally reviewed library as endorsed by your team
110
* to generate these objects. Otherwise, you risk accidentally creating
111
* SanitizedContent that is attacker-controlled and gets evaluated unescaped in
112
* templates.
113
*
114
* @constructor
115
*/
116
goog.soy.data.SanitizedContent = function() {
117
throw Error('Do not instantiate directly');
118
};
119
120
121
/**
122
* The context in which this content is safe from XSS attacks.
123
* @type {goog.soy.data.SanitizedContentKind}
124
*/
125
goog.soy.data.SanitizedContent.prototype.contentKind;
126
127
128
/**
129
* The content's direction; null if unknown and thus to be estimated when
130
* necessary.
131
* @type {?goog.i18n.bidi.Dir}
132
*/
133
goog.soy.data.SanitizedContent.prototype.contentDir = null;
134
135
136
/**
137
* The already-safe content.
138
* @protected {string}
139
*/
140
goog.soy.data.SanitizedContent.prototype.content;
141
142
143
/**
144
* Gets the already-safe content.
145
* @return {string}
146
*/
147
goog.soy.data.SanitizedContent.prototype.getContent = function() {
148
return this.content;
149
};
150
151
152
/** @override */
153
goog.soy.data.SanitizedContent.prototype.toString = function() {
154
return this.content;
155
};
156
157
158
/**
159
* Converts sanitized content of kind TEXT or HTML into SafeHtml. HTML content
160
* is converted without modification, while text content is HTML-escaped.
161
* @return {!goog.html.SafeHtml}
162
* @throws {Error} when the content kind is not TEXT or HTML.
163
*/
164
goog.soy.data.SanitizedContent.prototype.toSafeHtml = function() {
165
if (this.contentKind === goog.soy.data.SanitizedContentKind.TEXT) {
166
return goog.html.SafeHtml.htmlEscape(this.toString());
167
}
168
if (this.contentKind !== goog.soy.data.SanitizedContentKind.HTML) {
169
throw Error('Sanitized content was not of kind TEXT or HTML.');
170
}
171
return goog.html.uncheckedconversions
172
.safeHtmlFromStringKnownToSatisfyTypeContract(
173
goog.string.Const.from(
174
'Soy SanitizedContent of kind HTML produces ' +
175
'SafeHtml-contract-compliant value.'),
176
this.toString(), this.contentDir);
177
};
178
179
180
/**
181
* Converts sanitized content of kind URI into SafeUrl without modification.
182
* @return {!goog.html.SafeUrl}
183
* @throws {Error} when the content kind is not URI.
184
*/
185
goog.soy.data.SanitizedContent.prototype.toSafeUrl = function() {
186
if (this.contentKind !== goog.soy.data.SanitizedContentKind.URI) {
187
throw Error('Sanitized content was not of kind URI.');
188
}
189
return goog.html.uncheckedconversions
190
.safeUrlFromStringKnownToSatisfyTypeContract(
191
goog.string.Const.from(
192
'Soy SanitizedContent of kind URI produces ' +
193
'SafeHtml-contract-compliant value.'),
194
this.toString());
195
};
196
197
198
/**
199
* Unsanitized plain text string.
200
*
201
* While all strings are effectively safe to use as a plain text, there are no
202
* guarantees about safety in any other context such as HTML. This is
203
* sometimes used to mark that should never be used unescaped.
204
*
205
* @param {*} content Plain text with no guarantees.
206
* @param {?goog.i18n.bidi.Dir=} opt_contentDir The content direction; null if
207
* unknown and thus to be estimated when necessary. Default: null.
208
* @extends {goog.soy.data.SanitizedContent}
209
* @constructor
210
*/
211
goog.soy.data.UnsanitizedText = function(content, opt_contentDir) {
212
// Not calling the superclass constructor which just throws an exception.
213
214
/** @override */
215
this.content = String(content);
216
this.contentDir = opt_contentDir != null ? opt_contentDir : null;
217
};
218
goog.inherits(goog.soy.data.UnsanitizedText, goog.soy.data.SanitizedContent);
219
220
221
/** @override */
222
goog.soy.data.UnsanitizedText.prototype.contentKind =
223
goog.soy.data.SanitizedContentKind.TEXT;
224
225
226
227
/**
228
* Content of type {@link goog.soy.data.SanitizedContentKind.HTML}.
229
*
230
* The content is a string of HTML that can safely be embedded in a PCDATA
231
* context in your app. If you would be surprised to find that an HTML
232
* sanitizer produced {@code s} (e.g. it runs code or fetches bad URLs) and
233
* you wouldn't write a template that produces {@code s} on security or privacy
234
* grounds, then don't pass {@code s} here. The default content direction is
235
* unknown, i.e. to be estimated when necessary.
236
*
237
* @extends {goog.soy.data.SanitizedContent}
238
* @constructor
239
*/
240
goog.soy.data.SanitizedHtml = function() {
241
goog.soy.data.SanitizedHtml.base(this, 'constructor');
242
};
243
goog.inherits(goog.soy.data.SanitizedHtml, goog.soy.data.SanitizedContent);
244
245
/** @override */
246
goog.soy.data.SanitizedHtml.prototype.contentKind =
247
goog.soy.data.SanitizedContentKind.HTML;
248
249
/**
250
* Checks if the value could be used as the Soy type {html}.
251
* @param {*} value
252
* @return {boolean}
253
*/
254
goog.soy.data.SanitizedHtml.isCompatibleWith = function(value) {
255
return goog.isString(value) ||
256
value instanceof goog.soy.data.SanitizedHtml ||
257
value instanceof goog.soy.data.UnsanitizedText ||
258
value instanceof goog.html.SafeHtml;
259
};
260
261
262
263
/**
264
* Content of type {@link goog.soy.data.SanitizedContentKind.JS}.
265
*
266
* The content is JavaScript source that when evaluated does not execute any
267
* attacker-controlled scripts. The content direction is LTR.
268
*
269
* @extends {goog.soy.data.SanitizedContent}
270
* @constructor
271
*/
272
goog.soy.data.SanitizedJs = function() {
273
goog.soy.data.SanitizedJs.base(this, 'constructor');
274
};
275
goog.inherits(goog.soy.data.SanitizedJs, goog.soy.data.SanitizedContent);
276
277
/** @override */
278
goog.soy.data.SanitizedJs.prototype.contentKind =
279
goog.soy.data.SanitizedContentKind.JS;
280
281
/** @override */
282
goog.soy.data.SanitizedJs.prototype.contentDir = goog.i18n.bidi.Dir.LTR;
283
284
/**
285
* Checks if the value could be used as the Soy type {js}.
286
* @param {*} value
287
* @return {boolean}
288
*/
289
goog.soy.data.SanitizedJs.isCompatibleWith = function(value) {
290
return goog.isString(value) ||
291
value instanceof goog.soy.data.SanitizedJs ||
292
value instanceof goog.soy.data.UnsanitizedText ||
293
value instanceof goog.html.SafeScript;
294
};
295
296
297
298
/**
299
* Content of type {@link goog.soy.data.SanitizedContentKind.URI}.
300
*
301
* The content is a URI chunk that the caller knows is safe to emit in a
302
* template. The content direction is LTR.
303
*
304
* @extends {goog.soy.data.SanitizedContent}
305
* @constructor
306
*/
307
goog.soy.data.SanitizedUri = function() {
308
goog.soy.data.SanitizedUri.base(this, 'constructor');
309
};
310
goog.inherits(goog.soy.data.SanitizedUri, goog.soy.data.SanitizedContent);
311
312
/** @override */
313
goog.soy.data.SanitizedUri.prototype.contentKind =
314
goog.soy.data.SanitizedContentKind.URI;
315
316
/** @override */
317
goog.soy.data.SanitizedUri.prototype.contentDir = goog.i18n.bidi.Dir.LTR;
318
319
/**
320
* Checks if the value could be used as the Soy type {uri}.
321
* @param {*} value
322
* @return {boolean}
323
*/
324
goog.soy.data.SanitizedUri.isCompatibleWith = function(value) {
325
return goog.isString(value) ||
326
value instanceof goog.soy.data.SanitizedUri ||
327
value instanceof goog.soy.data.UnsanitizedText ||
328
value instanceof goog.html.SafeUrl ||
329
value instanceof goog.html.TrustedResourceUrl ||
330
value instanceof goog.Uri;
331
};
332
333
334
335
/**
336
* Content of type
337
* {@link goog.soy.data.SanitizedContentKind.TRUSTED_RESOURCE_URI}.
338
*
339
* The content is a TrustedResourceUri chunk that is not under attacker control.
340
* The content direction is LTR.
341
*
342
* @extends {goog.soy.data.SanitizedContent}
343
* @constructor
344
*/
345
goog.soy.data.SanitizedTrustedResourceUri = function() {
346
goog.soy.data.SanitizedTrustedResourceUri.base(this, 'constructor');
347
};
348
goog.inherits(
349
goog.soy.data.SanitizedTrustedResourceUri, goog.soy.data.SanitizedContent);
350
351
/** @override */
352
goog.soy.data.SanitizedTrustedResourceUri.prototype.contentKind =
353
goog.soy.data.SanitizedContentKind.TRUSTED_RESOURCE_URI;
354
355
/** @override */
356
goog.soy.data.SanitizedTrustedResourceUri.prototype.contentDir =
357
goog.i18n.bidi.Dir.LTR;
358
359
/**
360
* Checks if the value could be used as the Soy type {trusted_resource_uri}.
361
* @param {*} value
362
* @return {boolean}
363
*/
364
goog.soy.data.SanitizedTrustedResourceUri.isCompatibleWith = function(value) {
365
return goog.isString(value) ||
366
value instanceof goog.soy.data.SanitizedTrustedResourceUri ||
367
value instanceof goog.soy.data.UnsanitizedText ||
368
value instanceof goog.html.TrustedResourceUrl;
369
};
370
371
372
373
/**
374
* Content of type {@link goog.soy.data.SanitizedContentKind.ATTRIBUTES}.
375
*
376
* The content should be safely embeddable within an open tag, such as a
377
* key="value" pair. The content direction is LTR.
378
*
379
* @extends {goog.soy.data.SanitizedContent}
380
* @constructor
381
*/
382
goog.soy.data.SanitizedHtmlAttribute = function() {
383
goog.soy.data.SanitizedHtmlAttribute.base(this, 'constructor');
384
};
385
goog.inherits(
386
goog.soy.data.SanitizedHtmlAttribute, goog.soy.data.SanitizedContent);
387
388
/** @override */
389
goog.soy.data.SanitizedHtmlAttribute.prototype.contentKind =
390
goog.soy.data.SanitizedContentKind.ATTRIBUTES;
391
392
/** @override */
393
goog.soy.data.SanitizedHtmlAttribute.prototype.contentDir =
394
goog.i18n.bidi.Dir.LTR;
395
396
/**
397
* Checks if the value could be used as the Soy type {attribute}.
398
* @param {*} value
399
* @return {boolean}
400
*/
401
goog.soy.data.SanitizedHtmlAttribute.isCompatibleWith = function(value) {
402
return goog.isString(value) ||
403
value instanceof goog.soy.data.SanitizedHtmlAttribute ||
404
value instanceof goog.soy.data.UnsanitizedText;
405
};
406
407
408
409
/**
410
* Content of type {@link goog.soy.data.SanitizedContentKind.CSS}.
411
*
412
* The content is non-attacker-exploitable CSS, such as {@code color:#c3d9ff}.
413
* The content direction is LTR.
414
*
415
* @extends {goog.soy.data.SanitizedContent}
416
* @constructor
417
*/
418
goog.soy.data.SanitizedCss = function() {
419
goog.soy.data.SanitizedCss.base(this, 'constructor');
420
};
421
goog.inherits(goog.soy.data.SanitizedCss, goog.soy.data.SanitizedContent);
422
423
424
/** @override */
425
goog.soy.data.SanitizedCss.prototype.contentKind =
426
goog.soy.data.SanitizedContentKind.CSS;
427
428
429
/** @override */
430
goog.soy.data.SanitizedCss.prototype.contentDir = goog.i18n.bidi.Dir.LTR;
431
432
433
/**
434
* Checks if the value could be used as the Soy type {css}.
435
* @param {*} value
436
* @return {boolean}
437
*/
438
goog.soy.data.SanitizedCss.isCompatibleWith = function(value) {
439
return goog.isString(value) ||
440
value instanceof goog.soy.data.SanitizedCss ||
441
value instanceof goog.soy.data.UnsanitizedText ||
442
value instanceof goog.html.SafeStyle;
443
};
444
445