From 8e3566e02d734458ec26f03398c50bc832e4d90e Mon Sep 17 00:00:00 2001 From: Nikita Skovoroda Date: Wed, 31 Jul 2024 14:42:51 +0300 Subject: [PATCH] module: validate that strip-types does not insert any code --- lib/internal/modules/helpers.js | 39 +++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/lib/internal/modules/helpers.js b/lib/internal/modules/helpers.js index d466cec51cfbf7..9631b3d986af47 100644 --- a/lib/internal/modules/helpers.js +++ b/lib/internal/modules/helpers.js @@ -307,10 +307,49 @@ function lazyLoadTSParser() { return parseTS; } +function doesTSStripTypesResultMatchSource(code, source) { + const sourceBuf = Buffer.from(source); + const codeBuf = Buffer.from(code); + if (sourceBuf.length !== codeBuf.length) return false; + for (let i = 0; i < codeBuf.length; i++) { + // should match either the source buffer or spaces (sometimes multi-byte) or semicolon + const val = codeBuf[i]; + if (val === sourceBuf[i]) continue; // source match + // https://github.com/nodejs/amaro/blob/e533394f576f946add41dd8816816435e8100c3b/deps/swc/crates/swc_fast_ts_strip/src/lib.rs#L400-L414 + if (val === 0x3b) continue; // Semicolon 3b + // https://github.com/nodejs/amaro/blob/e533394f576f946add41dd8816816435e8100c3b/deps/swc/crates/swc_fast_ts_strip/src/lib.rs#L200-L226 + if (val === 0x20) continue; // Space 20 + if (val === 0xc2) { + // No-Break Space 00A0 + if (i + 1 >= codeBuf.length) return false; + if (codeBuf[++i] !== 0xa0) return false; + continue; + } + if (val === 0xc2) { + // En Space 2002 + if (i + 2 >= codeBuf.length) return false; + if (codeBuf[++i] !== 0x80) return false; + if (codeBuf[++i] !== 0x82) return false; + continue; + } + if (val === 0xef) { + // ZWNBSP FEFF + if (i < 1 || codeBuf[i - 1] !== 0x20) return false; // only can get insterted after a space + if (i + 2 >= codeBuf.length) return false; + if (codeBuf[++i] !== 0xbb) return false; + if (codeBuf[++i] !== 0xbf) return false; + continue; + } + return false; + } + return true; +} + function tsParse(source) { if (!source || typeof source !== 'string') { return; } const transformSync = lazyLoadTSParser(); const { code } = transformSync(source, { mode: 'strip-only' }); + assert(doesTSStripTypesResultMatchSource(code, source), 'Unexpected strip-types result') return code; }