From ff8d274b4d5b558c3a50c07f3262cff0527c1683 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Wed, 24 Mar 2021 14:21:13 +0100 Subject: [PATCH] Use ArrayStreams --- package-lock.json | 6 +++--- package.json | 2 +- src/openpgp.js | 4 ++++ src/packet/aead_encrypted_data.js | 15 +++++++++------ src/packet/compressed_data.js | 6 +++++- src/packet/packet.js | 12 +++++++++--- test/general/openpgp.js | 8 ++++---- 7 files changed, 35 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index f5bdfeb8..71d14217 100644 --- a/package-lock.json +++ b/package-lock.json @@ -261,9 +261,9 @@ "dev": true }, "@openpgp/web-stream-tools": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/@openpgp/web-stream-tools/-/web-stream-tools-0.0.1.tgz", - "integrity": "sha512-k3MqSRRjWkODJzsQdHeYxjG3IdmmtUXkXrz6XMq7aDT7GFTZPV/ZTbTHN93YkViPJNO3G0pS+FdO4Qy+UgGZpw==", + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@openpgp/web-stream-tools/-/web-stream-tools-0.0.2.tgz", + "integrity": "sha512-6RDYscGNmPEB/blocMH6bbyu4x0SXZKVHe1n1jHTonGyDJSMhPub99G+zFzRfXVjWamim2mXUPa7gfyK3tKJ7g==", "dev": true, "requires": { "@mattiasbuelens/web-streams-adapter": "0.1.0-alpha.5", diff --git a/package.json b/package.json index 99fcc58e..bbed1532 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "@openpgp/pako": "^1.0.11", "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.3", - "@openpgp/web-stream-tools": "0.0.1", + "@openpgp/web-stream-tools": "0.0.2", "@rollup/plugin-commonjs": "^11.1.0", "@rollup/plugin-node-resolve": "^7.1.3", "@rollup/plugin-replace": "^2.3.2", diff --git a/src/openpgp.js b/src/openpgp.js index 40b7011e..6203cf70 100644 --- a/src/openpgp.js +++ b/src/openpgp.js @@ -570,6 +570,10 @@ async function convertStream(data, streaming, encoding = 'utf8') { if (!streaming && streamType) { return stream.readToEnd(data); } + if (streamType === 'array') { + data = await stream.readToEnd(data); + streamType = false; + } if (streaming && !streamType) { data = stream.toStream(data); streamType = util.isStream(data); diff --git a/src/packet/aead_encrypted_data.js b/src/packet/aead_encrypted_data.js index db999de3..d57d4bf3 100644 --- a/src/packet/aead_encrypted_data.js +++ b/src/packet/aead_encrypted_data.js @@ -144,13 +144,16 @@ class AEADEncryptedDataPacket { let queuedBytes = 0; const iv = this.iv; return stream.transformPair(data, async (readable, writable) => { + if (util.isStream(readable) !== 'array') { + const buffer = new stream.TransformStream({}, { + highWaterMark: streaming ? util.getHardwareConcurrency() * 2 ** (this.chunkSizeByte + 6) : Infinity, + size: array => array.length + }); + stream.pipe(buffer.readable, writable); + writable = buffer.writable; + } const reader = stream.getReader(readable); - const buffer = new stream.TransformStream({}, { - highWaterMark: streaming ? util.getHardwareConcurrency() * 2 ** (this.chunkSizeByte + 6) : Infinity, - size: array => array.length - }); - stream.pipe(buffer.readable, writable); - const writer = stream.getWriter(buffer.writable); + const writer = stream.getWriter(writable); try { while (true) { let chunk = await reader.readBytes(chunkSize + tagLengthIfDecrypting) || new Uint8Array(); diff --git a/src/packet/compressed_data.js b/src/packet/compressed_data.js index fdf32dd0..2a943e0d 100644 --- a/src/packet/compressed_data.js +++ b/src/packet/compressed_data.js @@ -148,7 +148,11 @@ function uncompressed(data) { function node_zlib(func, options = {}) { return function (data) { - return stream.nodeToWeb(stream.webToNode(data).pipe(func(options))); + const webStream = stream.nodeToWeb(stream.webToNode(data).pipe(func(options))); + if (stream.isStream(data) === 'array') { + return stream.fromAsync(() => stream.readToEnd(webStream)); + } + return webStream; }; } diff --git a/src/packet/packet.js b/src/packet/packet.js index 08168120..3da9689d 100644 --- a/src/packet/packet.js +++ b/src/packet/packet.js @@ -150,9 +150,15 @@ export async function readPackets(input, streaming, callback) { const packetSupportsStreaming = supportsStreaming(tag); let packet = null; if (streaming && packetSupportsStreaming) { - const transform = new stream.TransformStream(); - writer = stream.getWriter(transform.writable); - packet = transform.readable; + if (util.isStream(input) === 'array') { + const arrayStream = new stream.ArrayStream(); + writer = stream.getWriter(arrayStream); + packet = arrayStream; + } else { + const transform = new stream.TransformStream(); + writer = stream.getWriter(transform.writable); + packet = transform.readable; + } callbackReturned = callback({ tag, packet }); } else { packet = []; diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 9fbf93b4..521265bc 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -1828,9 +1828,9 @@ module.exports = () => describe('OpenPGP.js public api tests', function() { const { key } = await openpgp.generateKey({ userIDs: {} }); const message = await openpgp.encrypt({ message: openpgp.Message.fromText('test'), publicKeys: key, privateKeys: key, armor: false }); const encrypted = util.concat([message, new Uint8Array([11])]); - await expect( - openpgp.decrypt({ message: await openpgp.readMessage({ binaryMessage: encrypted }), privateKeys: key, publicKeys: key }) - ).to.be.rejectedWith('Error during parsing. This message / key probably does not conform to a valid OpenPGP format.'); + await expect((async () => { + await openpgp.decrypt({ message: await openpgp.readMessage({ binaryMessage: encrypted }), privateKeys: key, publicKeys: key }); + })()).to.be.rejectedWith('Error during parsing. This message / key probably does not conform to a valid OpenPGP format.'); }); }); @@ -2380,7 +2380,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() { const packets = new openpgp.PacketList(); packets.push(message.packets.findPacket(openpgp.enums.packet.signature)); packets.push(message.packets.findPacket(openpgp.enums.packet.literalData)); - verifyOpt.message = new openpgp.Message(packets); + verifyOpt.message = await openpgp.readMessage({ binaryMessage: packets.write() }); return openpgp.verify(verifyOpt); }).then(async function (verified) { expect(openpgp.stream.isStream(verified.data)).to.equal(useNativeStream ? 'web' : 'ponyfill');