UNPKG

accessibility-developer-tools

Version:

This is a library of accessibility-related testing and utility code.

194 lines (161 loc) 6.24 kB
// Copyright 2012 The Closure Library Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS-IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /** * @fileoverview Soy data primitives. * * The goal is to encompass data types used by Soy, especially to mark content * as known to be "safe". * * @author gboyer@google.com (Garrett Boyer) */ goog.provide('goog.soy.data.SanitizedContent'); goog.provide('goog.soy.data.SanitizedContentKind'); goog.provide('goog.soy.data.SanitizedCss'); goog.provide('goog.soy.data.UnsanitizedText'); goog.require('goog.html.SafeHtml'); goog.require('goog.html.uncheckedconversions'); goog.require('goog.string.Const'); /** * A type of textual content. * * This is an enum of type Object so that these values are unforgeable. * * @enum {!Object} */ goog.soy.data.SanitizedContentKind = { /** * A snippet of HTML that does not start or end inside a tag, comment, entity, * or DOCTYPE; and that does not contain any executable code * (JS, {@code <object>}s, etc.) from a different trust domain. */ HTML: goog.DEBUG ? {sanitizedContentKindHtml: true} : {}, /** * Executable Javascript code or expression, safe for insertion in a * script-tag or event handler context, known to be free of any * attacker-controlled scripts. This can either be side-effect-free * Javascript (such as JSON) or Javascript that's entirely under Google's * control. */ JS: goog.DEBUG ? {sanitizedContentJsChars: true} : {}, /** A properly encoded portion of a URI. */ URI: goog.DEBUG ? {sanitizedContentUri: true} : {}, /** A resource URI not under attacker control. */ TRUSTED_RESOURCE_URI: goog.DEBUG ? {sanitizedContentTrustedResourceUri: true} : {}, /** * Repeated attribute names and values. For example, * {@code dir="ltr" foo="bar" onclick="trustedFunction()" checked}. */ ATTRIBUTES: goog.DEBUG ? {sanitizedContentHtmlAttribute: true} : {}, // TODO: Consider separating rules, declarations, and values into // separate types, but for simplicity, we'll treat explicitly blessed // SanitizedContent as allowed in all of these contexts. /** * A CSS3 declaration, property, value or group of semicolon separated * declarations. */ CSS: goog.DEBUG ? {sanitizedContentCss: true} : {}, /** * Unsanitized plain-text content. * * This is effectively the "null" entry of this enum, and is sometimes used * to explicitly mark content that should never be used unescaped. Since any * string is safe to use as text, being of ContentKind.TEXT makes no * guarantees about its safety in any other context such as HTML. */ TEXT: goog.DEBUG ? {sanitizedContentKindText: true} : {} }; /** * A string-like object that carries a content-type and a content direction. * * IMPORTANT! Do not create these directly, nor instantiate the subclasses. * Instead, use a trusted, centrally reviewed library as endorsed by your team * to generate these objects. Otherwise, you risk accidentally creating * SanitizedContent that is attacker-controlled and gets evaluated unescaped in * templates. * * @constructor */ goog.soy.data.SanitizedContent = function() { throw Error('Do not instantiate directly'); }; /** * The context in which this content is safe from XSS attacks. * @type {goog.soy.data.SanitizedContentKind} */ goog.soy.data.SanitizedContent.prototype.contentKind; /** * The content's direction; null if unknown and thus to be estimated when * necessary. * @type {?goog.i18n.bidi.Dir} */ goog.soy.data.SanitizedContent.prototype.contentDir = null; /** * The already-safe content. * @protected {string} */ goog.soy.data.SanitizedContent.prototype.content; /** * Gets the already-safe content. * @return {string} */ goog.soy.data.SanitizedContent.prototype.getContent = function() { return this.content; }; /** @override */ goog.soy.data.SanitizedContent.prototype.toString = function() { return this.content; }; /** * Converts sanitized content of kind TEXT or HTML into SafeHtml. HTML content * is converted without modification, while text content is HTML-escaped. * @return {!goog.html.SafeHtml} * @throws {Error} when the content kind is not TEXT or HTML. */ goog.soy.data.SanitizedContent.prototype.toSafeHtml = function() { if (this.contentKind === goog.soy.data.SanitizedContentKind.TEXT) { return goog.html.SafeHtml.htmlEscape(this.toString()); } if (this.contentKind !== goog.soy.data.SanitizedContentKind.HTML) { throw Error('Sanitized content was not of kind TEXT or HTML.'); } return goog.html.uncheckedconversions .safeHtmlFromStringKnownToSatisfyTypeContract( goog.string.Const.from( 'Soy SanitizedContent of kind HTML produces ' + 'SafeHtml-contract-compliant value.'), this.toString(), this.contentDir); }; /** * An intermediary base class to allow the type system to specify text templates * without referencing the soydata package. * @extends {goog.soy.data.SanitizedContent} * @constructor */ goog.soy.data.UnsanitizedText = function() { // TODO(gboyer): Delete this class after moving soydata to Closure. goog.soy.data.UnsanitizedText.base(this, 'constructor'); }; goog.inherits(goog.soy.data.UnsanitizedText, goog.soy.data.SanitizedContent); /** * An intermediary base class to allow the type system to specify CSS templates * without referencing the soydata package. * @extends {goog.soy.data.SanitizedContent} * @constructor */ goog.soy.data.SanitizedCss = function() { // TODO(gboyer): Delete this class after moving soydata to Closure. goog.soy.data.SanitizedCss.base(this, 'constructor'); }; goog.inherits(goog.soy.data.SanitizedCss, goog.soy.data.SanitizedContent);