PageRenderTime 27ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/deps/v8/src/uri.js

https://gitlab.com/MichelZuniga/node
JavaScript | 392 lines | 295 code | 40 blank | 57 comment | 140 complexity | 83eca3db8b2542fed8ce11fa9ce9b60b MD5 | raw file
  1. // Copyright 2006-2008 the V8 project authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. "use strict";
  5. // This file relies on the fact that the following declaration has been made
  6. // in runtime.js:
  7. // var $Array = global.Array;
  8. // -------------------------------------------------------------------
  9. // This file contains support for URI manipulations written in
  10. // JavaScript.
  11. (function() {
  12. // -------------------------------------------------------------------
  13. // Define internal helper functions.
  14. function HexValueOf(code) {
  15. // 0-9
  16. if (code >= 48 && code <= 57) return code - 48;
  17. // A-F
  18. if (code >= 65 && code <= 70) return code - 55;
  19. // a-f
  20. if (code >= 97 && code <= 102) return code - 87;
  21. return -1;
  22. }
  23. // Does the char code correspond to an alpha-numeric char.
  24. function isAlphaNumeric(cc) {
  25. // a - z
  26. if (97 <= cc && cc <= 122) return true;
  27. // A - Z
  28. if (65 <= cc && cc <= 90) return true;
  29. // 0 - 9
  30. if (48 <= cc && cc <= 57) return true;
  31. return false;
  32. }
  33. //Lazily initialized.
  34. var hexCharCodeArray = 0;
  35. function URIAddEncodedOctetToBuffer(octet, result, index) {
  36. result[index++] = 37; // Char code of '%'.
  37. result[index++] = hexCharCodeArray[octet >> 4];
  38. result[index++] = hexCharCodeArray[octet & 0x0F];
  39. return index;
  40. }
  41. function URIEncodeOctets(octets, result, index) {
  42. if (hexCharCodeArray === 0) {
  43. hexCharCodeArray = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
  44. 65, 66, 67, 68, 69, 70];
  45. }
  46. index = URIAddEncodedOctetToBuffer(octets[0], result, index);
  47. if (octets[1]) index = URIAddEncodedOctetToBuffer(octets[1], result, index);
  48. if (octets[2]) index = URIAddEncodedOctetToBuffer(octets[2], result, index);
  49. if (octets[3]) index = URIAddEncodedOctetToBuffer(octets[3], result, index);
  50. return index;
  51. }
  52. function URIEncodeSingle(cc, result, index) {
  53. var x = (cc >> 12) & 0xF;
  54. var y = (cc >> 6) & 63;
  55. var z = cc & 63;
  56. var octets = new $Array(3);
  57. if (cc <= 0x007F) {
  58. octets[0] = cc;
  59. } else if (cc <= 0x07FF) {
  60. octets[0] = y + 192;
  61. octets[1] = z + 128;
  62. } else {
  63. octets[0] = x + 224;
  64. octets[1] = y + 128;
  65. octets[2] = z + 128;
  66. }
  67. return URIEncodeOctets(octets, result, index);
  68. }
  69. function URIEncodePair(cc1 , cc2, result, index) {
  70. var u = ((cc1 >> 6) & 0xF) + 1;
  71. var w = (cc1 >> 2) & 0xF;
  72. var x = cc1 & 3;
  73. var y = (cc2 >> 6) & 0xF;
  74. var z = cc2 & 63;
  75. var octets = new $Array(4);
  76. octets[0] = (u >> 2) + 240;
  77. octets[1] = (((u & 3) << 4) | w) + 128;
  78. octets[2] = ((x << 4) | y) + 128;
  79. octets[3] = z + 128;
  80. return URIEncodeOctets(octets, result, index);
  81. }
  82. function URIHexCharsToCharCode(highChar, lowChar) {
  83. var highCode = HexValueOf(highChar);
  84. var lowCode = HexValueOf(lowChar);
  85. if (highCode == -1 || lowCode == -1) {
  86. throw new $URIError("URI malformed");
  87. }
  88. return (highCode << 4) | lowCode;
  89. }
  90. // Callers must ensure that |result| is a sufficiently long sequential
  91. // two-byte string!
  92. function URIDecodeOctets(octets, result, index) {
  93. var value;
  94. var o0 = octets[0];
  95. if (o0 < 0x80) {
  96. value = o0;
  97. } else if (o0 < 0xc2) {
  98. throw new $URIError("URI malformed");
  99. } else {
  100. var o1 = octets[1];
  101. if (o0 < 0xe0) {
  102. var a = o0 & 0x1f;
  103. if ((o1 < 0x80) || (o1 > 0xbf)) {
  104. throw new $URIError("URI malformed");
  105. }
  106. var b = o1 & 0x3f;
  107. value = (a << 6) + b;
  108. if (value < 0x80 || value > 0x7ff) {
  109. throw new $URIError("URI malformed");
  110. }
  111. } else {
  112. var o2 = octets[2];
  113. if (o0 < 0xf0) {
  114. var a = o0 & 0x0f;
  115. if ((o1 < 0x80) || (o1 > 0xbf)) {
  116. throw new $URIError("URI malformed");
  117. }
  118. var b = o1 & 0x3f;
  119. if ((o2 < 0x80) || (o2 > 0xbf)) {
  120. throw new $URIError("URI malformed");
  121. }
  122. var c = o2 & 0x3f;
  123. value = (a << 12) + (b << 6) + c;
  124. if ((value < 0x800) || (value > 0xffff)) {
  125. throw new $URIError("URI malformed");
  126. }
  127. } else {
  128. var o3 = octets[3];
  129. if (o0 < 0xf8) {
  130. var a = (o0 & 0x07);
  131. if ((o1 < 0x80) || (o1 > 0xbf)) {
  132. throw new $URIError("URI malformed");
  133. }
  134. var b = (o1 & 0x3f);
  135. if ((o2 < 0x80) || (o2 > 0xbf)) {
  136. throw new $URIError("URI malformed");
  137. }
  138. var c = (o2 & 0x3f);
  139. if ((o3 < 0x80) || (o3 > 0xbf)) {
  140. throw new $URIError("URI malformed");
  141. }
  142. var d = (o3 & 0x3f);
  143. value = (a << 18) + (b << 12) + (c << 6) + d;
  144. if ((value < 0x10000) || (value > 0x10ffff)) {
  145. throw new $URIError("URI malformed");
  146. }
  147. } else {
  148. throw new $URIError("URI malformed");
  149. }
  150. }
  151. }
  152. }
  153. if (0xD800 <= value && value <= 0xDFFF) {
  154. throw new $URIError("URI malformed");
  155. }
  156. if (value < 0x10000) {
  157. %_TwoByteSeqStringSetChar(index++, value, result);
  158. } else {
  159. %_TwoByteSeqStringSetChar(index++, (value >> 10) + 0xd7c0, result);
  160. %_TwoByteSeqStringSetChar(index++, (value & 0x3ff) + 0xdc00, result);
  161. }
  162. return index;
  163. }
  164. // ECMA-262, section 15.1.3
  165. function Encode(uri, unescape) {
  166. var uriLength = uri.length;
  167. var array = new InternalArray(uriLength);
  168. var index = 0;
  169. for (var k = 0; k < uriLength; k++) {
  170. var cc1 = uri.charCodeAt(k);
  171. if (unescape(cc1)) {
  172. array[index++] = cc1;
  173. } else {
  174. if (cc1 >= 0xDC00 && cc1 <= 0xDFFF) throw new $URIError("URI malformed");
  175. if (cc1 < 0xD800 || cc1 > 0xDBFF) {
  176. index = URIEncodeSingle(cc1, array, index);
  177. } else {
  178. k++;
  179. if (k == uriLength) throw new $URIError("URI malformed");
  180. var cc2 = uri.charCodeAt(k);
  181. if (cc2 < 0xDC00 || cc2 > 0xDFFF) throw new $URIError("URI malformed");
  182. index = URIEncodePair(cc1, cc2, array, index);
  183. }
  184. }
  185. }
  186. var result = %NewString(array.length, NEW_ONE_BYTE_STRING);
  187. for (var i = 0; i < array.length; i++) {
  188. %_OneByteSeqStringSetChar(i, array[i], result);
  189. }
  190. return result;
  191. }
  192. // ECMA-262, section 15.1.3
  193. function Decode(uri, reserved) {
  194. var uriLength = uri.length;
  195. var one_byte = %NewString(uriLength, NEW_ONE_BYTE_STRING);
  196. var index = 0;
  197. var k = 0;
  198. // Optimistically assume one-byte string.
  199. for ( ; k < uriLength; k++) {
  200. var code = uri.charCodeAt(k);
  201. if (code == 37) { // '%'
  202. if (k + 2 >= uriLength) throw new $URIError("URI malformed");
  203. var cc = URIHexCharsToCharCode(uri.charCodeAt(k+1), uri.charCodeAt(k+2));
  204. if (cc >> 7) break; // Assumption wrong, two-byte string.
  205. if (reserved(cc)) {
  206. %_OneByteSeqStringSetChar(index++, 37, one_byte); // '%'.
  207. %_OneByteSeqStringSetChar(index++, uri.charCodeAt(k+1), one_byte);
  208. %_OneByteSeqStringSetChar(index++, uri.charCodeAt(k+2), one_byte);
  209. } else {
  210. %_OneByteSeqStringSetChar(index++, cc, one_byte);
  211. }
  212. k += 2;
  213. } else {
  214. if (code > 0x7f) break; // Assumption wrong, two-byte string.
  215. %_OneByteSeqStringSetChar(index++, code, one_byte);
  216. }
  217. }
  218. one_byte = %TruncateString(one_byte, index);
  219. if (k == uriLength) return one_byte;
  220. // Write into two byte string.
  221. var two_byte = %NewString(uriLength - k, NEW_TWO_BYTE_STRING);
  222. index = 0;
  223. for ( ; k < uriLength; k++) {
  224. var code = uri.charCodeAt(k);
  225. if (code == 37) { // '%'
  226. if (k + 2 >= uriLength) throw new $URIError("URI malformed");
  227. var cc = URIHexCharsToCharCode(uri.charCodeAt(++k), uri.charCodeAt(++k));
  228. if (cc >> 7) {
  229. var n = 0;
  230. while (((cc << ++n) & 0x80) != 0) { }
  231. if (n == 1 || n > 4) throw new $URIError("URI malformed");
  232. var octets = new $Array(n);
  233. octets[0] = cc;
  234. if (k + 3 * (n - 1) >= uriLength) throw new $URIError("URI malformed");
  235. for (var i = 1; i < n; i++) {
  236. if (uri.charAt(++k) != '%') throw new $URIError("URI malformed");
  237. octets[i] = URIHexCharsToCharCode(uri.charCodeAt(++k),
  238. uri.charCodeAt(++k));
  239. }
  240. index = URIDecodeOctets(octets, two_byte, index);
  241. } else if (reserved(cc)) {
  242. %_TwoByteSeqStringSetChar(index++, 37, two_byte); // '%'.
  243. %_TwoByteSeqStringSetChar(index++, uri.charCodeAt(k - 1), two_byte);
  244. %_TwoByteSeqStringSetChar(index++, uri.charCodeAt(k), two_byte);
  245. } else {
  246. %_TwoByteSeqStringSetChar(index++, cc, two_byte);
  247. }
  248. } else {
  249. %_TwoByteSeqStringSetChar(index++, code, two_byte);
  250. }
  251. }
  252. two_byte = %TruncateString(two_byte, index);
  253. return one_byte + two_byte;
  254. }
  255. // -------------------------------------------------------------------
  256. // Define exported functions.
  257. // ECMA-262 - B.2.1.
  258. function URIEscapeJS(str) {
  259. var s = ToString(str);
  260. return %URIEscape(s);
  261. }
  262. // ECMA-262 - B.2.2.
  263. function URIUnescapeJS(str) {
  264. var s = ToString(str);
  265. return %URIUnescape(s);
  266. }
  267. // ECMA-262 - 15.1.3.1.
  268. function URIDecode(uri) {
  269. var reservedPredicate = function(cc) {
  270. // #$
  271. if (35 <= cc && cc <= 36) return true;
  272. // &
  273. if (cc == 38) return true;
  274. // +,
  275. if (43 <= cc && cc <= 44) return true;
  276. // /
  277. if (cc == 47) return true;
  278. // :;
  279. if (58 <= cc && cc <= 59) return true;
  280. // =
  281. if (cc == 61) return true;
  282. // ?@
  283. if (63 <= cc && cc <= 64) return true;
  284. return false;
  285. };
  286. var string = ToString(uri);
  287. return Decode(string, reservedPredicate);
  288. }
  289. // ECMA-262 - 15.1.3.2.
  290. function URIDecodeComponent(component) {
  291. var reservedPredicate = function(cc) { return false; };
  292. var string = ToString(component);
  293. return Decode(string, reservedPredicate);
  294. }
  295. // ECMA-262 - 15.1.3.3.
  296. function URIEncode(uri) {
  297. var unescapePredicate = function(cc) {
  298. if (isAlphaNumeric(cc)) return true;
  299. // !
  300. if (cc == 33) return true;
  301. // #$
  302. if (35 <= cc && cc <= 36) return true;
  303. // &'()*+,-./
  304. if (38 <= cc && cc <= 47) return true;
  305. // :;
  306. if (58 <= cc && cc <= 59) return true;
  307. // =
  308. if (cc == 61) return true;
  309. // ?@
  310. if (63 <= cc && cc <= 64) return true;
  311. // _
  312. if (cc == 95) return true;
  313. // ~
  314. if (cc == 126) return true;
  315. return false;
  316. };
  317. var string = ToString(uri);
  318. return Encode(string, unescapePredicate);
  319. }
  320. // ECMA-262 - 15.1.3.4
  321. function URIEncodeComponent(component) {
  322. var unescapePredicate = function(cc) {
  323. if (isAlphaNumeric(cc)) return true;
  324. // !
  325. if (cc == 33) return true;
  326. // '()*
  327. if (39 <= cc && cc <= 42) return true;
  328. // -.
  329. if (45 <= cc && cc <= 46) return true;
  330. // _
  331. if (cc == 95) return true;
  332. // ~
  333. if (cc == 126) return true;
  334. return false;
  335. };
  336. var string = ToString(component);
  337. return Encode(string, unescapePredicate);
  338. }
  339. // -------------------------------------------------------------------
  340. // Install exported functions.
  341. %CheckIsBootstrapping();
  342. // Set up non-enumerable URI functions on the global object and set
  343. // their names.
  344. InstallFunctions(global, DONT_ENUM, $Array(
  345. "escape", URIEscapeJS,
  346. "unescape", URIUnescapeJS,
  347. "decodeURI", URIDecode,
  348. "decodeURIComponent", URIDecodeComponent,
  349. "encodeURI", URIEncode,
  350. "encodeURIComponent", URIEncodeComponent
  351. ));
  352. })();