const.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. // Copyright 2013 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. goog.provide('goog.string.Const');
  15. goog.require('goog.asserts');
  16. goog.require('goog.string.TypedString');
  17. /**
  18. * Wrapper for compile-time-constant strings.
  19. *
  20. * Const is a wrapper for strings that can only be created from program
  21. * constants (i.e., string literals). This property relies on a custom Closure
  22. * compiler check that {@code goog.string.Const.from} is only invoked on
  23. * compile-time-constant expressions.
  24. *
  25. * Const is useful in APIs whose correct and secure use requires that certain
  26. * arguments are not attacker controlled: Compile-time constants are inherently
  27. * under the control of the application and not under control of external
  28. * attackers, and hence are safe to use in such contexts.
  29. *
  30. * Instances of this type must be created via its factory method
  31. * {@code goog.string.Const.from} and not by invoking its constructor. The
  32. * constructor intentionally takes no parameters and the type is immutable;
  33. * hence only a default instance corresponding to the empty string can be
  34. * obtained via constructor invocation.
  35. *
  36. * @see goog.string.Const#from
  37. * @constructor
  38. * @final
  39. * @struct
  40. * @implements {goog.string.TypedString}
  41. */
  42. goog.string.Const = function() {
  43. /**
  44. * The wrapped value of this Const object. The field has a purposely ugly
  45. * name to make (non-compiled) code that attempts to directly access this
  46. * field stand out.
  47. * @private {string}
  48. */
  49. this.stringConstValueWithSecurityContract__googStringSecurityPrivate_ = '';
  50. /**
  51. * A type marker used to implement additional run-time type checking.
  52. * @see goog.string.Const#unwrap
  53. * @const {!Object}
  54. * @private
  55. */
  56. this.STRING_CONST_TYPE_MARKER__GOOG_STRING_SECURITY_PRIVATE_ =
  57. goog.string.Const.TYPE_MARKER_;
  58. };
  59. /**
  60. * @override
  61. * @const
  62. */
  63. goog.string.Const.prototype.implementsGoogStringTypedString = true;
  64. /**
  65. * Returns this Const's value a string.
  66. *
  67. * IMPORTANT: In code where it is security-relevant that an object's type is
  68. * indeed {@code goog.string.Const}, use {@code goog.string.Const.unwrap}
  69. * instead of this method.
  70. *
  71. * @see goog.string.Const#unwrap
  72. * @override
  73. */
  74. goog.string.Const.prototype.getTypedStringValue = function() {
  75. return this.stringConstValueWithSecurityContract__googStringSecurityPrivate_;
  76. };
  77. /**
  78. * Returns a debug-string representation of this value.
  79. *
  80. * To obtain the actual string value wrapped inside an object of this type,
  81. * use {@code goog.string.Const.unwrap}.
  82. *
  83. * @see goog.string.Const#unwrap
  84. * @override
  85. */
  86. goog.string.Const.prototype.toString = function() {
  87. return 'Const{' +
  88. this.stringConstValueWithSecurityContract__googStringSecurityPrivate_ +
  89. '}';
  90. };
  91. /**
  92. * Performs a runtime check that the provided object is indeed an instance
  93. * of {@code goog.string.Const}, and returns its value.
  94. * @param {!goog.string.Const} stringConst The object to extract from.
  95. * @return {string} The Const object's contained string, unless the run-time
  96. * type check fails. In that case, {@code unwrap} returns an innocuous
  97. * string, or, if assertions are enabled, throws
  98. * {@code goog.asserts.AssertionError}.
  99. */
  100. goog.string.Const.unwrap = function(stringConst) {
  101. // Perform additional run-time type-checking to ensure that stringConst is
  102. // indeed an instance of the expected type. This provides some additional
  103. // protection against security bugs due to application code that disables type
  104. // checks.
  105. if (stringConst instanceof goog.string.Const &&
  106. stringConst.constructor === goog.string.Const &&
  107. stringConst.STRING_CONST_TYPE_MARKER__GOOG_STRING_SECURITY_PRIVATE_ ===
  108. goog.string.Const.TYPE_MARKER_) {
  109. return stringConst
  110. .stringConstValueWithSecurityContract__googStringSecurityPrivate_;
  111. } else {
  112. goog.asserts.fail(
  113. 'expected object of type Const, got \'' + stringConst + '\'');
  114. return 'type_error:Const';
  115. }
  116. };
  117. /**
  118. * Creates a Const object from a compile-time constant string.
  119. *
  120. * It is illegal to invoke this function on an expression whose
  121. * compile-time-contant value cannot be determined by the Closure compiler.
  122. *
  123. * Correct invocations include,
  124. * <pre>
  125. * var s = goog.string.Const.from('hello');
  126. * var t = goog.string.Const.from('hello' + 'world');
  127. * </pre>
  128. *
  129. * In contrast, the following are illegal:
  130. * <pre>
  131. * var s = goog.string.Const.from(getHello());
  132. * var t = goog.string.Const.from('hello' + world);
  133. * </pre>
  134. *
  135. * @param {string} s A constant string from which to create a Const.
  136. * @return {!goog.string.Const} A Const object initialized to stringConst.
  137. */
  138. goog.string.Const.from = function(s) {
  139. return goog.string.Const.create__googStringSecurityPrivate_(s);
  140. };
  141. /**
  142. * Type marker for the Const type, used to implement additional run-time
  143. * type checking.
  144. * @const {!Object}
  145. * @private
  146. */
  147. goog.string.Const.TYPE_MARKER_ = {};
  148. /**
  149. * Utility method to create Const instances.
  150. * @param {string} s The string to initialize the Const object with.
  151. * @return {!goog.string.Const} The initialized Const object.
  152. * @private
  153. */
  154. goog.string.Const.create__googStringSecurityPrivate_ = function(s) {
  155. var stringConst = new goog.string.Const();
  156. stringConst.stringConstValueWithSecurityContract__googStringSecurityPrivate_ =
  157. s;
  158. return stringConst;
  159. };
  160. /**
  161. * A Const instance wrapping the empty string.
  162. * @const {!goog.string.Const}
  163. */
  164. goog.string.Const.EMPTY = goog.string.Const.from('');