|
@@ -1,4 +1,4 @@
|
|
|
-import CryptoJS from "crypto-js";
|
|
|
+import utf8 from "utf8";
|
|
|
|
|
|
|
|
|
/**
|
|
@@ -64,58 +64,6 @@ const Utils = {
|
|
|
},
|
|
|
|
|
|
|
|
|
- /**
|
|
|
- * Adds leading zeros to strings
|
|
|
- *
|
|
|
- * @param {string} str - String to add leading characters to.
|
|
|
- * @param {number} max - Maximum width of the string.
|
|
|
- * @param {char} [chr='0'] - The character to pad with.
|
|
|
- * @returns {string}
|
|
|
- *
|
|
|
- * @example
|
|
|
- * // returns "0a"
|
|
|
- * Utils.padLeft("a", 2);
|
|
|
- *
|
|
|
- * // returns "000a"
|
|
|
- * Utils.padLeft("a", 4);
|
|
|
- *
|
|
|
- * // returns "xxxa"
|
|
|
- * Utils.padLeft("a", 4, "x");
|
|
|
- *
|
|
|
- * // returns "bcabchello"
|
|
|
- * Utils.padLeft("hello", 10, "abc");
|
|
|
- */
|
|
|
- padLeft: function(str, max, chr) {
|
|
|
- chr = chr || "0";
|
|
|
- let startIndex = chr.length - (max - str.length);
|
|
|
- startIndex = startIndex < 0 ? 0 : startIndex;
|
|
|
- return str.length < max ?
|
|
|
- Utils.padLeft(chr.slice(startIndex, chr.length) + str, max, chr) : str;
|
|
|
- },
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * Adds trailing spaces to strings.
|
|
|
- *
|
|
|
- * @param {string} str - String to add trailing characters to.
|
|
|
- * @param {number} max - Maximum width of the string.
|
|
|
- * @param {char} [chr='0'] - The character to pad with.
|
|
|
- * @returns {string}
|
|
|
- *
|
|
|
- * @example
|
|
|
- * // returns "a "
|
|
|
- * Utils.padRight("a", 4);
|
|
|
- *
|
|
|
- * // returns "axxx"
|
|
|
- * Utils.padRight("a", 4, "x");
|
|
|
- */
|
|
|
- padRight: function(str, max, chr) {
|
|
|
- chr = chr || " ";
|
|
|
- return str.length < max ?
|
|
|
- Utils.padRight(str + chr.slice(0, max-str.length), max, chr) : str;
|
|
|
- },
|
|
|
-
|
|
|
-
|
|
|
/**
|
|
|
* Adds trailing bytes to a byteArray.
|
|
|
*
|
|
@@ -152,14 +100,6 @@ const Utils = {
|
|
|
},
|
|
|
|
|
|
|
|
|
- /**
|
|
|
- * @alias Utils.padLeft
|
|
|
- */
|
|
|
- pad: function(str, max, chr) {
|
|
|
- return Utils.padLeft(str, max, chr);
|
|
|
- },
|
|
|
-
|
|
|
-
|
|
|
/**
|
|
|
* Truncates a long string to max length and adds suffix.
|
|
|
*
|
|
@@ -201,7 +141,7 @@ const Utils = {
|
|
|
hex: function(c, length) {
|
|
|
c = typeof c == "string" ? Utils.ord(c) : c;
|
|
|
length = length || 2;
|
|
|
- return Utils.pad(c.toString(16), length);
|
|
|
+ return c.toString(16).padStart(length, "0");
|
|
|
},
|
|
|
|
|
|
|
|
@@ -222,7 +162,7 @@ const Utils = {
|
|
|
bin: function(c, length) {
|
|
|
c = typeof c == "string" ? Utils.ord(c) : c;
|
|
|
length = length || 8;
|
|
|
- return Utils.pad(c.toString(2), length);
|
|
|
+ return c.toString(2).padStart(length, "0");
|
|
|
},
|
|
|
|
|
|
|
|
@@ -340,6 +280,39 @@ const Utils = {
|
|
|
},
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
+ * Coverts data of varying types to a byteArray.
|
|
|
+ * Accepts hex, Base64, UTF8 and Latin1 strings.
|
|
|
+ *
|
|
|
+ * @param {string} str
|
|
|
+ * @param {string} type - One of "Hex", "Base64", "UTF8" or "Latin1"
|
|
|
+ * @returns {byteArray}
|
|
|
+ *
|
|
|
+ * @example
|
|
|
+ * // returns [208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130]
|
|
|
+ * Utils.convertToByteArray("Привет", "utf8");
|
|
|
+ *
|
|
|
+ * // returns [208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130]
|
|
|
+ * Utils.convertToByteArray("d097d0b4d180d0b0d0b2d181d182d0b2d183d0b9d182d0b5", "hex");
|
|
|
+ *
|
|
|
+ * // returns [208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130]
|
|
|
+ * Utils.convertToByteArray("0JfQtNGA0LDQstGB0YLQstGD0LnRgtC1", "base64");
|
|
|
+ */
|
|
|
+ convertToByteArray: function(str, type) {
|
|
|
+ switch (type.toLowerCase()) {
|
|
|
+ case "hex":
|
|
|
+ return Utils.fromHex(str);
|
|
|
+ case "base64":
|
|
|
+ return Utils.fromBase64(str, null, "byteArray");
|
|
|
+ case "utf8":
|
|
|
+ return Utils.strToUtf8ByteArray(str);
|
|
|
+ case "latin1":
|
|
|
+ default:
|
|
|
+ return Utils.strToByteArray(str);
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
/**
|
|
|
* Converts a string to a byte array.
|
|
|
* Treats the string as UTF-8 if any values are over 255.
|
|
@@ -381,17 +354,17 @@ const Utils = {
|
|
|
* Utils.strToUtf8ByteArray("你好");
|
|
|
*/
|
|
|
strToUtf8ByteArray: function(str) {
|
|
|
- let wordArray = CryptoJS.enc.Utf8.parse(str),
|
|
|
- byteArray = Utils.wordArrayToByteArray(wordArray);
|
|
|
+ const utf8Str = utf8.encode(str);
|
|
|
|
|
|
- if (str.length !== wordArray.sigBytes) {
|
|
|
+ if (str.length !== utf8Str.length) {
|
|
|
if (ENVIRONMENT_IS_WORKER()) {
|
|
|
self.setOption("attemptHighlight", false);
|
|
|
} else if (ENVIRONMENT_IS_WEB()) {
|
|
|
window.app.options.attemptHighlight = false;
|
|
|
}
|
|
|
}
|
|
|
- return byteArray;
|
|
|
+
|
|
|
+ return Utils.strToByteArray(utf8Str);
|
|
|
},
|
|
|
|
|
|
|
|
@@ -443,26 +416,21 @@ const Utils = {
|
|
|
* Utils.byteArrayToUtf8([228,189,160,229,165,189]);
|
|
|
*/
|
|
|
byteArrayToUtf8: function(byteArray) {
|
|
|
+ const str = Utils.byteArrayToChars(byteArray);
|
|
|
try {
|
|
|
- // Try to output data as UTF-8 string
|
|
|
- const words = [];
|
|
|
- for (let i = 0; i < byteArray.length; i++) {
|
|
|
- words[i >>> 2] |= byteArray[i] << (24 - (i % 4) * 8);
|
|
|
- }
|
|
|
- let wordArray = new CryptoJS.lib.WordArray.init(words, byteArray.length),
|
|
|
- str = CryptoJS.enc.Utf8.stringify(wordArray);
|
|
|
+ const utf8Str = utf8.decode(str);
|
|
|
|
|
|
- if (str.length !== wordArray.sigBytes) {
|
|
|
+ if (str.length !== utf8Str.length) {
|
|
|
if (ENVIRONMENT_IS_WORKER()) {
|
|
|
self.setOption("attemptHighlight", false);
|
|
|
} else if (ENVIRONMENT_IS_WEB()) {
|
|
|
window.app.options.attemptHighlight = false;
|
|
|
}
|
|
|
}
|
|
|
- return str;
|
|
|
+ return utf8Str;
|
|
|
} catch (err) {
|
|
|
// If it fails, treat it as ANSI
|
|
|
- return Utils.byteArrayToChars(byteArray);
|
|
|
+ return str;
|
|
|
}
|
|
|
},
|
|
|
|
|
@@ -470,7 +438,7 @@ const Utils = {
|
|
|
/**
|
|
|
* Converts a charcode array to a string.
|
|
|
*
|
|
|
- * @param {byteArray} byteArray
|
|
|
+ * @param {byteArray|Uint8Array} byteArray
|
|
|
* @returns {string}
|
|
|
*
|
|
|
* @example
|
|
@@ -491,33 +459,25 @@ const Utils = {
|
|
|
|
|
|
|
|
|
/**
|
|
|
- * Converts a CryptoJS.lib.WordArray to a byteArray.
|
|
|
- *
|
|
|
- * @param {CryptoJS.lib.WordArray} wordArray
|
|
|
- * @returns {byteArray}
|
|
|
- *
|
|
|
+ * Converts an ArrayBuffer to a string.
|
|
|
+ *
|
|
|
+ * @param {ArrayBuffer} arrayBuffer
|
|
|
+ * @returns {string}
|
|
|
+ *
|
|
|
* @example
|
|
|
- * // returns [84, 101, 115, 116]
|
|
|
- * Utils.wordArrayToByteArray(CryptoJS.enc.Hex.parse("54657374"));
|
|
|
+ * // returns "hello"
|
|
|
+ * Utils.arrayBufferToStr(Uint8Array.from([104,101,108,108,111]).buffer);
|
|
|
*/
|
|
|
- wordArrayToByteArray: function(wordArray) {
|
|
|
- if (wordArray.sigBytes <= 0) return [];
|
|
|
-
|
|
|
- let words = wordArray.words,
|
|
|
- byteArray = [];
|
|
|
-
|
|
|
- for (let i = 0; i < wordArray.sigBytes; i++) {
|
|
|
- byteArray.push((words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff);
|
|
|
- }
|
|
|
-
|
|
|
- return byteArray;
|
|
|
+ arrayBufferToStr: function(arrayBuffer) {
|
|
|
+ const byteArray = Array.prototype.slice.call(new Uint8Array(arrayBuffer));
|
|
|
+ return Utils.byteArrayToUtf8(byteArray);
|
|
|
},
|
|
|
|
|
|
|
|
|
/**
|
|
|
* Base64's the input byte array using the given alphabet, returning a string.
|
|
|
*
|
|
|
- * @param {byteArray|string} data
|
|
|
+ * @param {byteArray|Uint8Array|string} data
|
|
|
* @param {string} [alphabet]
|
|
|
* @returns {string}
|
|
|
*
|
|
@@ -636,7 +596,7 @@ const Utils = {
|
|
|
/**
|
|
|
* Convert a byte array into a hex string.
|
|
|
*
|
|
|
- * @param {byteArray} data
|
|
|
+ * @param {Uint8Array|byteArray} data
|
|
|
* @param {string} [delim=" "]
|
|
|
* @param {number} [padding=2]
|
|
|
* @returns {string}
|
|
@@ -656,7 +616,7 @@ const Utils = {
|
|
|
let output = "";
|
|
|
|
|
|
for (let i = 0; i < data.length; i++) {
|
|
|
- output += Utils.pad(data[i].toString(16), padding) + delim;
|
|
|
+ output += data[i].toString(16).padStart(padding, "0") + delim;
|
|
|
}
|
|
|
|
|
|
// Add \x or 0x to beginning
|
|
@@ -1248,21 +1208,6 @@ const Utils = {
|
|
|
"None": /\s+/g // Included here to remove whitespace when there shouldn't be any
|
|
|
},
|
|
|
|
|
|
-
|
|
|
- /**
|
|
|
- * A mapping of string formats to their classes in the CryptoJS library.
|
|
|
- * @constant
|
|
|
- */
|
|
|
- format: {
|
|
|
- "Hex": CryptoJS.enc.Hex,
|
|
|
- "Base64": CryptoJS.enc.Base64,
|
|
|
- "UTF8": CryptoJS.enc.Utf8,
|
|
|
- "UTF16": CryptoJS.enc.Utf16,
|
|
|
- "UTF16LE": CryptoJS.enc.Utf16LE,
|
|
|
- "UTF16BE": CryptoJS.enc.Utf16BE,
|
|
|
- "Latin1": CryptoJS.enc.Latin1,
|
|
|
- },
|
|
|
-
|
|
|
};
|
|
|
|
|
|
export default Utils;
|
|
@@ -1376,29 +1321,43 @@ String.prototype.count = function(chr) {
|
|
|
};
|
|
|
|
|
|
|
|
|
-////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
-// Library overrides ///////////////////////////////////////////////////////////////////////////////
|
|
|
-////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
-
|
|
|
-/**
|
|
|
- * Override for the CryptoJS Hex encoding parser to remove whitespace before attempting to parse
|
|
|
- * the hex string.
|
|
|
- *
|
|
|
- * @param {string} hexStr
|
|
|
- * @returns {CryptoJS.lib.WordArray}
|
|
|
+/*
|
|
|
+ * Polyfills
|
|
|
*/
|
|
|
-CryptoJS.enc.Hex.parse = function (hexStr) {
|
|
|
- // Remove whitespace
|
|
|
- hexStr = hexStr.replace(/\s/g, "");
|
|
|
|
|
|
- // Shortcut
|
|
|
- const hexStrLength = hexStr.length;
|
|
|
-
|
|
|
- // Convert
|
|
|
- const words = [];
|
|
|
- for (let i = 0; i < hexStrLength; i += 2) {
|
|
|
- words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);
|
|
|
- }
|
|
|
-
|
|
|
- return new CryptoJS.lib.WordArray.init(words, hexStrLength / 2);
|
|
|
-};
|
|
|
+// https://github.com/uxitten/polyfill/blob/master/string.polyfill.js
|
|
|
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart
|
|
|
+if (!String.prototype.padStart) {
|
|
|
+ String.prototype.padStart = function padStart(targetLength, padString) {
|
|
|
+ targetLength = targetLength>>0; //floor if number or convert non-number to 0;
|
|
|
+ padString = String((typeof padString !== "undefined" ? padString : " "));
|
|
|
+ if (this.length > targetLength) {
|
|
|
+ return String(this);
|
|
|
+ } else {
|
|
|
+ targetLength = targetLength-this.length;
|
|
|
+ if (targetLength > padString.length) {
|
|
|
+ padString += padString.repeat(targetLength/padString.length); //append to original to ensure we are longer than needed
|
|
|
+ }
|
|
|
+ return padString.slice(0, targetLength) + String(this);
|
|
|
+ }
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+// https://github.com/uxitten/polyfill/blob/master/string.polyfill.js
|
|
|
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd
|
|
|
+if (!String.prototype.padEnd) {
|
|
|
+ String.prototype.padEnd = function padEnd(targetLength, padString) {
|
|
|
+ targetLength = targetLength>>0; //floor if number or convert non-number to 0;
|
|
|
+ padString = String((typeof padString !== "undefined" ? padString : " "));
|
|
|
+ if (this.length > targetLength) {
|
|
|
+ return String(this);
|
|
|
+ } else {
|
|
|
+ targetLength = targetLength-this.length;
|
|
|
+ if (targetLength > padString.length) {
|
|
|
+ padString += padString.repeat(targetLength/padString.length); //append to original to ensure we are longer than needed
|
|
|
+ }
|
|
|
+ return String(this) + padString.slice(0, targetLength);
|
|
|
+ }
|
|
|
+ };
|
|
|
+}
|