summaryrefslogtreecommitdiffstats
path: root/dom/webauthn/tests/cbor.js
diff options
context:
space:
mode:
Diffstat (limited to 'dom/webauthn/tests/cbor.js')
-rw-r--r--dom/webauthn/tests/cbor.js406
1 files changed, 406 insertions, 0 deletions
diff --git a/dom/webauthn/tests/cbor.js b/dom/webauthn/tests/cbor.js
new file mode 100644
index 0000000000..3e1f300df3
--- /dev/null
+++ b/dom/webauthn/tests/cbor.js
@@ -0,0 +1,406 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2014-2016 Patrick Gansterer <paroga@paroga.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+(function(global, undefined) { "use strict";
+var POW_2_24 = 5.960464477539063e-8,
+ POW_2_32 = 4294967296,
+ POW_2_53 = 9007199254740992;
+
+function encode(value) {
+ var data = new ArrayBuffer(256);
+ var dataView = new DataView(data);
+ var lastLength;
+ var offset = 0;
+
+ function prepareWrite(length) {
+ var newByteLength = data.byteLength;
+ var requiredLength = offset + length;
+ while (newByteLength < requiredLength)
+ newByteLength <<= 1;
+ if (newByteLength !== data.byteLength) {
+ var oldDataView = dataView;
+ data = new ArrayBuffer(newByteLength);
+ dataView = new DataView(data);
+ var uint32count = (offset + 3) >> 2;
+ for (var i = 0; i < uint32count; ++i)
+ dataView.setUint32(i << 2, oldDataView.getUint32(i << 2));
+ }
+
+ lastLength = length;
+ return dataView;
+ }
+ function commitWrite() {
+ offset += lastLength;
+ }
+ function writeFloat64(value) {
+ commitWrite(prepareWrite(8).setFloat64(offset, value));
+ }
+ function writeUint8(value) {
+ commitWrite(prepareWrite(1).setUint8(offset, value));
+ }
+ function writeUint8Array(value) {
+ var dataView = prepareWrite(value.length);
+ for (var i = 0; i < value.length; ++i)
+ dataView.setUint8(offset + i, value[i]);
+ commitWrite();
+ }
+ function writeUint16(value) {
+ commitWrite(prepareWrite(2).setUint16(offset, value));
+ }
+ function writeUint32(value) {
+ commitWrite(prepareWrite(4).setUint32(offset, value));
+ }
+ function writeUint64(value) {
+ var low = value % POW_2_32;
+ var high = (value - low) / POW_2_32;
+ var dataView = prepareWrite(8);
+ dataView.setUint32(offset, high);
+ dataView.setUint32(offset + 4, low);
+ commitWrite();
+ }
+ function writeTypeAndLength(type, length) {
+ if (length < 24) {
+ writeUint8(type << 5 | length);
+ } else if (length < 0x100) {
+ writeUint8(type << 5 | 24);
+ writeUint8(length);
+ } else if (length < 0x10000) {
+ writeUint8(type << 5 | 25);
+ writeUint16(length);
+ } else if (length < 0x100000000) {
+ writeUint8(type << 5 | 26);
+ writeUint32(length);
+ } else {
+ writeUint8(type << 5 | 27);
+ writeUint64(length);
+ }
+ }
+
+ function encodeItem(value) {
+ var i;
+
+ if (value === false)
+ return writeUint8(0xf4);
+ if (value === true)
+ return writeUint8(0xf5);
+ if (value === null)
+ return writeUint8(0xf6);
+ if (value === undefined)
+ return writeUint8(0xf7);
+
+ switch (typeof value) {
+ case "number":
+ if (Math.floor(value) === value) {
+ if (0 <= value && value <= POW_2_53)
+ return writeTypeAndLength(0, value);
+ if (-POW_2_53 <= value && value < 0)
+ return writeTypeAndLength(1, -(value + 1));
+ }
+ writeUint8(0xfb);
+ return writeFloat64(value);
+
+ case "string":
+ var utf8data = [];
+ for (i = 0; i < value.length; ++i) {
+ var charCode = value.charCodeAt(i);
+ if (charCode < 0x80) {
+ utf8data.push(charCode);
+ } else if (charCode < 0x800) {
+ utf8data.push(0xc0 | charCode >> 6);
+ utf8data.push(0x80 | charCode & 0x3f);
+ } else if (charCode < 0xd800) {
+ utf8data.push(0xe0 | charCode >> 12);
+ utf8data.push(0x80 | (charCode >> 6) & 0x3f);
+ utf8data.push(0x80 | charCode & 0x3f);
+ } else {
+ charCode = (charCode & 0x3ff) << 10;
+ charCode |= value.charCodeAt(++i) & 0x3ff;
+ charCode += 0x10000;
+
+ utf8data.push(0xf0 | charCode >> 18);
+ utf8data.push(0x80 | (charCode >> 12) & 0x3f);
+ utf8data.push(0x80 | (charCode >> 6) & 0x3f);
+ utf8data.push(0x80 | charCode & 0x3f);
+ }
+ }
+
+ writeTypeAndLength(3, utf8data.length);
+ return writeUint8Array(utf8data);
+
+ default:
+ var length;
+ if (Array.isArray(value)) {
+ length = value.length;
+ writeTypeAndLength(4, length);
+ for (i = 0; i < length; ++i)
+ encodeItem(value[i]);
+ } else if (value instanceof Uint8Array) {
+ writeTypeAndLength(2, value.length);
+ writeUint8Array(value);
+ } else {
+ var keys = Object.keys(value);
+ length = keys.length;
+ writeTypeAndLength(5, length);
+ for (i = 0; i < length; ++i) {
+ var key = keys[i];
+ encodeItem(key);
+ encodeItem(value[key]);
+ }
+ }
+ }
+ }
+
+ encodeItem(value);
+
+ if ("slice" in data)
+ return data.slice(0, offset);
+
+ var ret = new ArrayBuffer(offset);
+ var retView = new DataView(ret);
+ for (var i = 0; i < offset; ++i)
+ retView.setUint8(i, dataView.getUint8(i));
+ return ret;
+}
+
+function decode(data, tagger, simpleValue) {
+ var dataView = new DataView(data);
+ var offset = 0;
+
+ if (typeof tagger !== "function")
+ tagger = function(value) { return value; };
+ if (typeof simpleValue !== "function")
+ simpleValue = function() { return undefined; };
+
+ function commitRead(length, value) {
+ offset += length;
+ return value;
+ }
+ function readArrayBuffer(length) {
+ return commitRead(length, new Uint8Array(data, offset, length));
+ }
+ function readFloat16() {
+ var tempArrayBuffer = new ArrayBuffer(4);
+ var tempDataView = new DataView(tempArrayBuffer);
+ var value = readUint16();
+
+ var sign = value & 0x8000;
+ var exponent = value & 0x7c00;
+ var fraction = value & 0x03ff;
+
+ if (exponent === 0x7c00)
+ exponent = 0xff << 10;
+ else if (exponent !== 0)
+ exponent += (127 - 15) << 10;
+ else if (fraction !== 0)
+ return (sign ? -1 : 1) * fraction * POW_2_24;
+
+ tempDataView.setUint32(0, sign << 16 | exponent << 13 | fraction << 13);
+ return tempDataView.getFloat32(0);
+ }
+ function readFloat32() {
+ return commitRead(4, dataView.getFloat32(offset));
+ }
+ function readFloat64() {
+ return commitRead(8, dataView.getFloat64(offset));
+ }
+ function readUint8() {
+ return commitRead(1, dataView.getUint8(offset));
+ }
+ function readUint16() {
+ return commitRead(2, dataView.getUint16(offset));
+ }
+ function readUint32() {
+ return commitRead(4, dataView.getUint32(offset));
+ }
+ function readUint64() {
+ return readUint32() * POW_2_32 + readUint32();
+ }
+ function readBreak() {
+ if (dataView.getUint8(offset) !== 0xff)
+ return false;
+ offset += 1;
+ return true;
+ }
+ function readLength(additionalInformation) {
+ if (additionalInformation < 24)
+ return additionalInformation;
+ if (additionalInformation === 24)
+ return readUint8();
+ if (additionalInformation === 25)
+ return readUint16();
+ if (additionalInformation === 26)
+ return readUint32();
+ if (additionalInformation === 27)
+ return readUint64();
+ if (additionalInformation === 31)
+ return -1;
+ throw "Invalid length encoding";
+ }
+ function readIndefiniteStringLength(majorType) {
+ var initialByte = readUint8();
+ if (initialByte === 0xff)
+ return -1;
+ var length = readLength(initialByte & 0x1f);
+ if (length < 0 || (initialByte >> 5) !== majorType)
+ throw "Invalid indefinite length element";
+ return length;
+ }
+
+ function appendUtf16Data(utf16data, length) {
+ for (var i = 0; i < length; ++i) {
+ var value = readUint8();
+ if (value & 0x80) {
+ if (value < 0xe0) {
+ value = (value & 0x1f) << 6
+ | (readUint8() & 0x3f);
+ length -= 1;
+ } else if (value < 0xf0) {
+ value = (value & 0x0f) << 12
+ | (readUint8() & 0x3f) << 6
+ | (readUint8() & 0x3f);
+ length -= 2;
+ } else {
+ value = (value & 0x0f) << 18
+ | (readUint8() & 0x3f) << 12
+ | (readUint8() & 0x3f) << 6
+ | (readUint8() & 0x3f);
+ length -= 3;
+ }
+ }
+
+ if (value < 0x10000) {
+ utf16data.push(value);
+ } else {
+ value -= 0x10000;
+ utf16data.push(0xd800 | (value >> 10));
+ utf16data.push(0xdc00 | (value & 0x3ff));
+ }
+ }
+ }
+
+ function decodeItem() {
+ var initialByte = readUint8();
+ var majorType = initialByte >> 5;
+ var additionalInformation = initialByte & 0x1f;
+ var i;
+ var length;
+
+ if (majorType === 7) {
+ switch (additionalInformation) {
+ case 25:
+ return readFloat16();
+ case 26:
+ return readFloat32();
+ case 27:
+ return readFloat64();
+ }
+ }
+
+ length = readLength(additionalInformation);
+ if (length < 0 && (majorType < 2 || 6 < majorType))
+ throw "Invalid length";
+
+ switch (majorType) {
+ case 0:
+ return length;
+ case 1:
+ return -1 - length;
+ case 2:
+ if (length < 0) {
+ var elements = [];
+ var fullArrayLength = 0;
+ while ((length = readIndefiniteStringLength(majorType)) >= 0) {
+ fullArrayLength += length;
+ elements.push(readArrayBuffer(length));
+ }
+ var fullArray = new Uint8Array(fullArrayLength);
+ var fullArrayOffset = 0;
+ for (i = 0; i < elements.length; ++i) {
+ fullArray.set(elements[i], fullArrayOffset);
+ fullArrayOffset += elements[i].length;
+ }
+ return fullArray;
+ }
+ return readArrayBuffer(length);
+ case 3:
+ var utf16data = [];
+ if (length < 0) {
+ while ((length = readIndefiniteStringLength(majorType)) >= 0)
+ appendUtf16Data(utf16data, length);
+ } else
+ appendUtf16Data(utf16data, length);
+ return String.fromCharCode.apply(null, utf16data);
+ case 4:
+ var retArray;
+ if (length < 0) {
+ retArray = [];
+ while (!readBreak())
+ retArray.push(decodeItem());
+ } else {
+ retArray = new Array(length);
+ for (i = 0; i < length; ++i)
+ retArray[i] = decodeItem();
+ }
+ return retArray;
+ case 5:
+ var retObject = {};
+ for (i = 0; i < length || length < 0 && !readBreak(); ++i) {
+ var key = decodeItem();
+ retObject[key] = decodeItem();
+ }
+ return retObject;
+ case 6:
+ return tagger(decodeItem(), length);
+ case 7:
+ switch (length) {
+ case 20:
+ return false;
+ case 21:
+ return true;
+ case 22:
+ return null;
+ case 23:
+ return undefined;
+ default:
+ return simpleValue(length);
+ }
+ }
+ }
+
+ var ret = decodeItem();
+ if (offset !== data.byteLength)
+ throw "Remaining bytes";
+ return ret;
+}
+
+var obj = { encode: encode, decode: decode };
+
+if (typeof define === "function" && define.amd)
+ define("cbor/cbor", obj);
+else if (typeof module !== "undefined" && module.exports)
+ module.exports = obj;
+else if (!global.CBOR)
+ global.CBOR = obj;
+
+})(this);