From 6d27dd9e7079e4b4d46d02a3f518f66e6dd5222b Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Wed, 21 Aug 2024 13:53:42 +0200 Subject: [PATCH] Fix - race in zstd initialization #318 While ZSTD decoding can be invoked from different places, ensure that initialization performed properly. --- modules/io.mjs | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/modules/io.mjs b/modules/io.mjs index dc72c7eff..4e3ff847b 100644 --- a/modules/io.mjs +++ b/modules/io.mjs @@ -2017,10 +2017,23 @@ async function R__unzip(arr, tgtsize, noalert, src_shift) { const tgt8arr = new Uint8Array(tgtbuf, fullres); if (fmt === 'ZSTD') { - const promise = internals._ZstdStream - ? Promise.resolve(internals._ZstdStream) - : (isNodeJs() ? import('@oneidentity/zstd-js') : import('./base/zstd.mjs')) - .then(({ ZstdInit }) => ZstdInit()).then(({ ZstdStream }) => { internals._ZstdStream = ZstdStream; return ZstdStream; }); + let promise; + if (internals._ZstdStream) + promise = Promise.resolve(internals._ZstdStream); + else if (internals._ZstdInit !== undefined) + promise = new Promise(resolveFunc => { internals._ZstdInit.push(resolveFunc); }) + else { + internals._ZstdInit = []; + promise = (isNodeJs() ? import('@oneidentity/zstd-js') : import('./base/zstd.mjs')) + .then(({ ZstdInit }) => ZstdInit()) + .then(({ ZstdStream }) => { + internals._ZstdStream = ZstdStream; + internals._ZstdInit.forEach(func => func(ZstdStream)); + delete internals._ZstdInit; + return ZstdStream; + }); + } + return promise.then(ZstdStream => { const data2 = ZstdStream.decompress(uint8arr), reslen = data2.length;