Pass more tests
- Allow leading spaces in headers (since we were already accepting leading spaces everywhere else in the armored text). - Read ReadableStreams before passing them to a Worker
This commit is contained in:
parent
05479e6e6b
commit
37014ecf30
|
@ -207,7 +207,6 @@ function dearmor(input) {
|
||||||
const reEmptyLine = /^[ \f\r\t\u00a0\u2000-\u200a\u202f\u205f\u3000]*$/;
|
const reEmptyLine = /^[ \f\r\t\u00a0\u2000-\u200a\u202f\u205f\u3000]*$/;
|
||||||
|
|
||||||
const reader = stream.getReader(input);
|
const reader = stream.getReader(input);
|
||||||
let lineIndex = 0;
|
|
||||||
let type;
|
let type;
|
||||||
const headers = [];
|
const headers = [];
|
||||||
let lastHeaders = headers;
|
let lastHeaders = headers;
|
||||||
|
@ -232,13 +231,13 @@ function dearmor(input) {
|
||||||
});
|
});
|
||||||
while (true) {
|
while (true) {
|
||||||
let line = await reader.readLine();
|
let line = await reader.readLine();
|
||||||
if (!line) break;
|
if (line === undefined) {
|
||||||
if (lineIndex++ === 0) {
|
controller.error('Misformed armored text');
|
||||||
// trim string
|
break;
|
||||||
line = line.trim();
|
|
||||||
}
|
}
|
||||||
// remove trailing whitespace at end of lines
|
// remove trailing whitespace at end of lines
|
||||||
line = line.replace(/[\t\r\n ]+$/g, '');
|
// remove leading whitespace for compat with older versions of OpenPGP.js
|
||||||
|
line = line.trim();
|
||||||
if (!type) {
|
if (!type) {
|
||||||
if (reSplit.test(line)) {
|
if (reSplit.test(line)) {
|
||||||
type = getType(line);
|
type = getType(line);
|
||||||
|
@ -257,7 +256,7 @@ function dearmor(input) {
|
||||||
} else if (!textDone && type === 2) {
|
} else if (!textDone && type === 2) {
|
||||||
if (!reSplit.test(line)) {
|
if (!reSplit.test(line)) {
|
||||||
// Reverse dash-escaping for msg
|
// Reverse dash-escaping for msg
|
||||||
text.push(line.replace(/^- /mg, ''));
|
text.push(line.replace(/^- /, ''));
|
||||||
} else {
|
} else {
|
||||||
text = text.join('\r\n');
|
text = text.join('\r\n');
|
||||||
textDone = true;
|
textDone = true;
|
||||||
|
|
|
@ -127,15 +127,15 @@ export function generateKey({ userIds=[], passphrase="", numBits=2048, keyExpira
|
||||||
return asyncProxy.delegate('generateKey', options);
|
return asyncProxy.delegate('generateKey', options);
|
||||||
}
|
}
|
||||||
|
|
||||||
return generate(options).then(key => {
|
return generate(options).then(async key => {
|
||||||
const revocationCertificate = key.getRevocationCertificate();
|
const revocationCertificate = key.getRevocationCertificate();
|
||||||
key.revocationSignatures = [];
|
key.revocationSignatures = [];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
||||||
key: key,
|
key: key,
|
||||||
privateKeyArmored: key.armor(),
|
privateKeyArmored: await stream.readToEnd(key.armor()),
|
||||||
publicKeyArmored: key.toPublic().armor(),
|
publicKeyArmored: await stream.readToEnd(key.toPublic().armor())
|
||||||
revocationCertificate: revocationCertificate
|
revocationCertificate: revocationCertificate
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -453,6 +453,9 @@ export function verify({ message, publicKeys, signature=null, date=new Date() })
|
||||||
return Promise.resolve().then(async function() {
|
return Promise.resolve().then(async function() {
|
||||||
const result = {};
|
const result = {};
|
||||||
result.data = message instanceof CleartextMessage ? message.getText() : message.getLiteralData();
|
result.data = message instanceof CleartextMessage ? message.getText() : message.getLiteralData();
|
||||||
|
if (!message.fromStream) {
|
||||||
|
result.data = await stream.readToEnd(result.data);
|
||||||
|
}
|
||||||
result.signatures = signature ?
|
result.signatures = signature ?
|
||||||
await message.verifyDetached(signature, publicKeys, date) :
|
await message.verifyDetached(signature, publicKeys, date) :
|
||||||
await message.verify(publicKeys, date);
|
await message.verify(publicKeys, date);
|
||||||
|
|
|
@ -235,14 +235,15 @@ export default {
|
||||||
if (bodydata === null) {
|
if (bodydata === null) {
|
||||||
bodydata = await reader.readBytes(packet_length);
|
bodydata = await reader.readBytes(packet_length);
|
||||||
|
|
||||||
|
const peekedByte = await reader.peekBytes(1);
|
||||||
resolve({
|
resolve({
|
||||||
tag: tag,
|
tag: tag,
|
||||||
packet: bodydata,
|
packet: bodydata,
|
||||||
done: !await reader.peekBytes(1)
|
done: !(peekedByte && peekedByte.length)
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const { done } = await reader.read();
|
const { done, value } = await reader.read();
|
||||||
if (!done) {
|
if (!done && value.length) {
|
||||||
throw new Error('Packets after a packet with partial lengths are not supported');
|
throw new Error('Packets after a packet with partial lengths are not supported');
|
||||||
} else {
|
} else {
|
||||||
controller.close();
|
controller.close();
|
||||||
|
|
|
@ -165,7 +165,7 @@ SymEncryptedAEADProtected.prototype.crypt = async function (fn, key, data) {
|
||||||
cryptedBytes += chunk.length - tagLengthIfDecrypting;
|
cryptedBytes += chunk.length - tagLengthIfDecrypting;
|
||||||
queuedBytes += chunk.length - tagLengthIfDecrypting;
|
queuedBytes += chunk.length - tagLengthIfDecrypting;
|
||||||
latestPromise = latestPromise.then(() => cryptedPromise).then(crypted => {
|
latestPromise = latestPromise.then(() => cryptedPromise).then(crypted => {
|
||||||
if (crypted.length) controller.enqueue(crypted);
|
controller.enqueue(crypted);
|
||||||
queuedBytes -= chunk.length;
|
queuedBytes -= chunk.length;
|
||||||
}).catch(err => controller.error(err));
|
}).catch(err => controller.error(err));
|
||||||
// console.log(fn, done, queuedBytes, controller.desiredSize);
|
// console.log(fn, done, queuedBytes, controller.desiredSize);
|
||||||
|
@ -181,6 +181,6 @@ SymEncryptedAEADProtected.prototype.crypt = async function (fn, key, data) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return modeInstance[fn](data, this.iv);
|
return modeInstance[fn](await stream.readToEnd(data), this.iv);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
27
src/util.js
27
src/util.js
|
@ -53,33 +53,38 @@ export default {
|
||||||
/**
|
/**
|
||||||
* Get transferable objects to pass buffers with zero copy (similar to "pass by reference" in C++)
|
* Get transferable objects to pass buffers with zero copy (similar to "pass by reference" in C++)
|
||||||
* See: https://developer.mozilla.org/en-US/docs/Web/API/Worker/postMessage
|
* See: https://developer.mozilla.org/en-US/docs/Web/API/Worker/postMessage
|
||||||
|
* Also, convert ReadableStreams to Uint8Arrays
|
||||||
* @param {Object} obj the options object to be passed to the web worker
|
* @param {Object} obj the options object to be passed to the web worker
|
||||||
* @returns {Array<ArrayBuffer>} an array of binary data to be passed
|
* @returns {Array<ArrayBuffer>} an array of binary data to be passed
|
||||||
*/
|
*/
|
||||||
getTransferables: function(obj) {
|
prepareBuffers: async function(obj) {
|
||||||
// Internet Explorer does not support Transferable objects.
|
// Internet Explorer does not support Transferable objects.
|
||||||
if (isIE11) {
|
if (isIE11) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
if (config.zero_copy && Object.prototype.isPrototypeOf(obj)) {
|
const transferables = [];
|
||||||
const transferables = [];
|
await util.collectBuffers(obj, transferables);
|
||||||
util.collectBuffers(obj, transferables);
|
return transferables.length ? transferables : undefined;
|
||||||
return transferables.length ? transferables : undefined;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
collectBuffers: function(obj, collection) {
|
collectBuffers: async function(obj, collection) {
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (util.isUint8Array(obj) && collection.indexOf(obj.buffer) === -1) {
|
if (util.isUint8Array(obj) && collection.indexOf(obj.buffer) === -1) {
|
||||||
collection.push(obj.buffer);
|
if (config.zero_copy) {
|
||||||
|
collection.push(obj.buffer);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Object.prototype.isPrototypeOf(obj)) {
|
if (Object.prototype.isPrototypeOf(obj)) {
|
||||||
Object.values(obj).forEach(value => { // recursively search all children
|
await Promise.all(Object.entries(obj).map(async ([key, value]) => { // recursively search all children
|
||||||
util.collectBuffers(value, collection);
|
if (util.isStream(value)) {
|
||||||
});
|
obj[key] = value = await stream.readToEnd(value);
|
||||||
|
}
|
||||||
|
await util.collectBuffers(value, collection);
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ AsyncProxy.prototype.getID = function() {
|
||||||
*/
|
*/
|
||||||
AsyncProxy.prototype.seedRandom = async function(workerId, size) {
|
AsyncProxy.prototype.seedRandom = async function(workerId, size) {
|
||||||
const buf = await crypto.random.getRandomBytes(size);
|
const buf = await crypto.random.getRandomBytes(size);
|
||||||
this.workers[workerId].postMessage({ event:'seed-random', buf }, util.getTransferables(buf));
|
this.workers[workerId].postMessage({ event:'seed-random', buf }, await util.prepareBuffers(buf));
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -143,9 +143,10 @@ AsyncProxy.prototype.delegate = function(method, options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
// clone packets (for web worker structured cloning algorithm)
|
// clone packets (for web worker structured cloning algorithm)
|
||||||
this.workers[workerId].postMessage({ id:id, event:method, options:packet.clone.clonePackets(options) }, util.getTransferables(options));
|
const transferables = await util.prepareBuffers(options);
|
||||||
|
this.workers[workerId].postMessage({ id:id, event:method, options:packet.clone.clonePackets(options) }, transferables);
|
||||||
this.workers[workerId].requests++;
|
this.workers[workerId].requests++;
|
||||||
|
|
||||||
// remember to handle parsing cloned packets from worker
|
// remember to handle parsing cloned packets from worker
|
||||||
|
|
|
@ -112,18 +112,18 @@ describe("ASCII armor", function() {
|
||||||
await expect(msg).to.be.rejectedWith(Error, /Improperly formatted armor header/);
|
await expect(msg).to.be.rejectedWith(Error, /Improperly formatted armor header/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Exception if improperly formatted armor header - signature section', function () {
|
it('Exception if improperly formatted armor header - signature section', async function () {
|
||||||
[' Space: leading', 'Space : trailing', 'Space :switched', ': empty', 'none', 'Space:missing'].forEach(function (invalidHeader) {
|
await Promise.all(['Space : trailing', 'Space :switched', ': empty', 'none', 'Space:missing'].map(async function (invalidHeader) {
|
||||||
expect(openpgp.cleartext.readArmored(getArmor(['Hash: SHA1'], [invalidHeader]))).to.be.rejectedWith(Error, /Improperly formatted armor header/);
|
await expect(openpgp.cleartext.readArmored(getArmor(['Hash: SHA1'], [invalidHeader]))).to.be.rejectedWith(Error, /Improperly formatted armor header/);
|
||||||
});
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Ignore unknown armor header - signature section', async function () {
|
it('Ignore unknown armor header - signature section', async function () {
|
||||||
const validHeaders = ['Version: BCPG C# v1.7.4114.6375', 'Independent Reserve Pty. Ltd. 2017: 1.0.0.0'];
|
const validHeaders = ['Version: BCPG C# v1.7.4114.6375', 'Independent Reserve Pty. Ltd. 2017: 1.0.0.0'];
|
||||||
expect(await openpgp.cleartext.readArmored(getArmor(['Hash: SHA1'], validHeaders))).to.be.an.instanceof(openpgp.cleartext.CleartextMessage);
|
expect(await openpgp.cleartext.readArmored(getArmor(['Hash: SHA1'], validHeaders))).to.be.an.instanceof(openpgp.cleartext.CleartextMessage);
|
||||||
['A: Hello', 'Ab: 1.2.3', 'Abcd: #!/yah', 'Acd 123 5.6.$.8: Hello', '_: Hello', '*: Hello', '* & ## ?? ()(): Hello', '( ): Weird'].forEach(async function (validHeader) {
|
await Promise.all(['A: Hello', 'Ab: 1.2.3', 'Abcd: #!/yah', 'Acd 123 5.6.$.8: Hello', '_: Hello', '*: Hello', '* & ## ?? ()(): Hello', '( ): Weird'].map(async function (validHeader) {
|
||||||
expect(await openpgp.cleartext.readArmored(getArmor(['Hash: SHA1'], [validHeader]))).to.be.an.instanceof(openpgp.cleartext.CleartextMessage);
|
expect(await openpgp.cleartext.readArmored(getArmor(['Hash: SHA1'], [validHeader]))).to.be.an.instanceof(openpgp.cleartext.CleartextMessage);
|
||||||
});
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Exception if wrong armor header type', async function () {
|
it('Exception if wrong armor header type', async function () {
|
||||||
|
|
|
@ -346,7 +346,7 @@ zoGJ6s48HcP591pN93uAitCcYcinY2ZslmdiCXw+zbeoX4spNrV4T4CYxBjNQdIa
|
||||||
'BIDZSFjrJY/gm2kgQX2Pn9hGqDdGhxiALjxhA0+OJQNw4v11y0zVGdofh0IHjkcZ',
|
'BIDZSFjrJY/gm2kgQX2Pn9hGqDdGhxiALjxhA0+OJQNw4v11y0zVGdofh0IHjkcZ',
|
||||||
'onCOcv4DKguN2w==',
|
'onCOcv4DKguN2w==',
|
||||||
'=OqO3',
|
'=OqO3',
|
||||||
'-----END PGP PUBLIC KEY BLOCK----'].join('\n');
|
'-----END PGP PUBLIC KEY BLOCK-----'].join('\n');
|
||||||
|
|
||||||
const pub_v3 =
|
const pub_v3 =
|
||||||
['-----BEGIN PGP PUBLIC KEY BLOCK-----',
|
['-----BEGIN PGP PUBLIC KEY BLOCK-----',
|
||||||
|
@ -1731,7 +1731,7 @@ t/ia1kMpSEiOVLlX5dfHZzhR3WNtBqU=
|
||||||
};
|
};
|
||||||
const opt = {numBits: 512, userIds: 'test <a@b.com>', passphrase: 'hello'};
|
const opt = {numBits: 512, userIds: 'test <a@b.com>', passphrase: 'hello'};
|
||||||
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
|
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
|
||||||
return openpgp.generateKey(opt).then(function(key) {
|
return openpgp.generateKey(opt).then(async function(key) {
|
||||||
testPref(key.key);
|
testPref(key.key);
|
||||||
testPref((await openpgp.key.readArmored(key.publicKeyArmored)).keys[0]);
|
testPref((await openpgp.key.readArmored(key.publicKeyArmored)).keys[0]);
|
||||||
});
|
});
|
||||||
|
@ -1877,8 +1877,8 @@ VYGdb3eNlV8CfoEC
|
||||||
const opt = {numBits: 512, userIds: userId, passphrase: 'passphrase'};
|
const opt = {numBits: 512, userIds: userId, passphrase: 'passphrase'};
|
||||||
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
|
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
|
||||||
const key = (await openpgp.generateKey(opt)).key;
|
const key = (await openpgp.generateKey(opt)).key;
|
||||||
const armor1 = key.armor();
|
const armor1 = await openpgp.stream.readToEnd(key.armor());
|
||||||
const armor2 = key.armor();
|
const armor2 = await openpgp.stream.readToEnd(key.armor());
|
||||||
expect(armor1).to.equal(armor2);
|
expect(armor1).to.equal(armor2);
|
||||||
expect(await key.decrypt('passphrase')).to.be.true;
|
expect(await key.decrypt('passphrase')).to.be.true;
|
||||||
expect(key.isDecrypted()).to.be.true;
|
expect(key.isDecrypted()).to.be.true;
|
||||||
|
@ -1888,7 +1888,7 @@ VYGdb3eNlV8CfoEC
|
||||||
expect(key.isDecrypted()).to.be.false;
|
expect(key.isDecrypted()).to.be.false;
|
||||||
expect(await key.decrypt('new_passphrase')).to.be.true;
|
expect(await key.decrypt('new_passphrase')).to.be.true;
|
||||||
expect(key.isDecrypted()).to.be.true;
|
expect(key.isDecrypted()).to.be.true;
|
||||||
const armor3 = key.armor();
|
const armor3 = await openpgp.stream.readToEnd(key.armor());
|
||||||
expect(armor3).to.not.equal(armor1);
|
expect(armor3).to.not.equal(armor1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -249,10 +249,10 @@ describe("Packet", function() {
|
||||||
|
|
||||||
return parsed[0].decrypt('test').then(() => {
|
return parsed[0].decrypt('test').then(() => {
|
||||||
const key = parsed[0].sessionKey;
|
const key = parsed[0].sessionKey;
|
||||||
return parsed[1].decrypt(parsed[0].sessionKeyAlgorithm, key).then(() => {
|
return parsed[1].decrypt(parsed[0].sessionKeyAlgorithm, key).then(async () => {
|
||||||
const compressed = parsed[1].packets[0];
|
const compressed = parsed[1].packets[0];
|
||||||
|
|
||||||
const result = stringify(compressed.packets[0].data);
|
const result = await stringify(compressed.packets[0].data);
|
||||||
|
|
||||||
expect(result).to.equal('Hello world!\n');
|
expect(result).to.equal('Hello world!\n');
|
||||||
});
|
});
|
||||||
|
@ -393,7 +393,7 @@ describe("Packet", function() {
|
||||||
return msg[0].decrypt(key).then(async () => {
|
return msg[0].decrypt(key).then(async () => {
|
||||||
await msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey);
|
await msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey);
|
||||||
|
|
||||||
const text = stringify(msg[1].packets[0].packets[0].data);
|
const text = await stringify(msg[1].packets[0].packets[0].data);
|
||||||
|
|
||||||
expect(text).to.equal('Hello world!');
|
expect(text).to.equal('Hello world!');
|
||||||
});
|
});
|
||||||
|
@ -654,7 +654,7 @@ describe("Packet", function() {
|
||||||
return msg[0].decrypt(key).then(async () => {
|
return msg[0].decrypt(key).then(async () => {
|
||||||
await msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey);
|
await msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey);
|
||||||
|
|
||||||
const text = stringify(msg[1].packets[0].packets[0].data);
|
const text = await stringify(msg[1].packets[0].packets[0].data);
|
||||||
|
|
||||||
expect(text).to.equal('Hello world!');
|
expect(text).to.equal('Hello world!');
|
||||||
});
|
});
|
||||||
|
|
|
@ -523,7 +523,7 @@ describe("Signature", function() {
|
||||||
expect(pubKey2.getKeys(keyids[1])).to.not.be.empty;
|
expect(pubKey2.getKeys(keyids[1])).to.not.be.empty;
|
||||||
expect(pubKey3.getKeys(keyids[0])).to.not.be.empty;
|
expect(pubKey3.getKeys(keyids[0])).to.not.be.empty;
|
||||||
|
|
||||||
expect(sMsg.getText()).to.equal(plaintext);
|
expect(await openpgp.stream.readToEnd(sMsg.getText())).to.equal(plaintext);
|
||||||
|
|
||||||
return sMsg.verify([pubKey2, pubKey3]).then(verifiedSig => {
|
return sMsg.verify([pubKey2, pubKey3]).then(verifiedSig => {
|
||||||
expect(verifiedSig).to.exist;
|
expect(verifiedSig).to.exist;
|
||||||
|
@ -720,7 +720,7 @@ yYDnCgA=
|
||||||
const csMsg = await openpgp.message.readArmored(signed.data);
|
const csMsg = await openpgp.message.readArmored(signed.data);
|
||||||
return openpgp.verify({ publicKeys:[pubKey], message:csMsg });
|
return openpgp.verify({ publicKeys:[pubKey], message:csMsg });
|
||||||
|
|
||||||
}).then(function(cleartextSig) {
|
}).then(async function(cleartextSig) {
|
||||||
expect(cleartextSig).to.exist;
|
expect(cleartextSig).to.exist;
|
||||||
expect(cleartextSig.data).to.deep.equal(plaintext);
|
expect(cleartextSig.data).to.deep.equal(plaintext);
|
||||||
expect(cleartextSig.signatures).to.have.length(1);
|
expect(cleartextSig.signatures).to.have.length(1);
|
||||||
|
|
|
@ -116,7 +116,7 @@ describe('Util unit tests', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getTransferables', function() {
|
describe('prepareBuffers', function() {
|
||||||
let zero_copyVal;
|
let zero_copyVal;
|
||||||
const buf1 = new Uint8Array(1);
|
const buf1 = new Uint8Array(1);
|
||||||
const buf2 = new Uint8Array(1);
|
const buf2 = new Uint8Array(1);
|
||||||
|
@ -137,18 +137,18 @@ describe('Util unit tests', function() {
|
||||||
openpgp.config.zero_copy = zero_copyVal;
|
openpgp.config.zero_copy = zero_copyVal;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return undefined when zero_copy is false', function() {
|
it('should return undefined when zero_copy is false', async function() {
|
||||||
openpgp.config.zero_copy = false;
|
openpgp.config.zero_copy = false;
|
||||||
expect(openpgp.util.getTransferables(obj)).to.be.undefined;
|
expect(await openpgp.util.prepareBuffers(obj)).to.be.undefined;
|
||||||
});
|
});
|
||||||
it('should return undefined for no input', function() {
|
it('should return undefined for no input', async function() {
|
||||||
expect(openpgp.util.getTransferables()).to.be.undefined;
|
expect(await openpgp.util.prepareBuffers()).to.be.undefined;
|
||||||
});
|
});
|
||||||
it('should return undefined for an empty oject', function() {
|
it('should return undefined for an empty oject', async function() {
|
||||||
expect(openpgp.util.getTransferables({})).to.be.undefined;
|
expect(await openpgp.util.prepareBuffers({})).to.be.undefined;
|
||||||
});
|
});
|
||||||
it('should return two buffers', function() {
|
it('should return two buffers', async function() {
|
||||||
expect(openpgp.util.getTransferables(obj)).to.deep.equal([buf1.buffer, buf2.buffer]);
|
expect(await openpgp.util.prepareBuffers(obj)).to.deep.equal([buf1.buffer, buf2.buffer]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user