npm / es-module-lexer / 3.0.4

es-module-lexer 3.0.4

Source
https://github.com/guybedford/es-module-lexer
Tag scanned
3.0.4
Compared with
3.0.3 (0 signals introduced since)
Files
34 scanned, 2 skipped (binary, oversized, or unrecognised)
Signals
0 critical · 0 warn · 29 info
Scan time
10.4 s
LLM review
Reviewed by claude-haiku-5-5 (Anthropic): 13 of 13 warn and critical signals; 13 demoted to info.
Disclude version
4.1.0
Scanned (UTC)
2026-10-22 17:24

Signals

Ordered by severity, then signals introduced in this release. Hidden characters are shown as ⟨U+…⟩.

  1. info warn → info by review dynamic-import bench/index.js:37:32

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

    	const loadStart = process.hrtime.bigint();
    	const { parse, init } = await import(build.path);
    	if (init) await init;
    	const load = ms(loadStart, process.hrtime.bigint());
    likely benign LLM, confidence 0.80 Benchmark harness dynamically imports a build artifact chosen from config.
    Reasoning

    The import specifier comes from a build-config path inside a benchmark harness, a common way to load a built module for timing. The pass is AST and the signal is a non-literal import, which alone does not indicate malice.

  2. info whitespace-anomaly build/combine-asm.mjs:25:1

    file mixes tab and space indentation (7 tab-indented and 33 space-indented lines) (raw pass, confidence 0.40)

    const replacements = [
      [/Module\["asm"\]=\s?\(\/\*\* @suppress {uselessCode} \*\/ function\(/, 'function asmInit('],
      [/\)$/, ''],
      [/,\s?_(\w+):/g, ',$1:', null, endFuncs],
  3. info warn → info by review dynamic-execution src/lexer.ts:723:23

    `atob` decodes a base64 value at runtime — common step before dynamic fetch or eval (ast pass, confidence 0.75)

        ? Buffer.from(binary, 'base64')
        : Uint8Array.from(atob(binary), x => x.charCodeAt(0))
    )('WASM_BINARY');
    likely benign LLM, confidence 0.80 Lexer decodes its inlined WebAssembly binary from base64 via atob or Buffer.
    Reasoning

    This decodes an embedded WASM binary from base64 at module load, the standard pattern for bundling WebAssembly in a JS/TS library. It is not fetched remotely or passed to eval, and the decoded bytes are a known parser binary.

  4. info warn → info by review dynamic-import test/_lexer.cjs:8:36

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

      if (process.env.ASM) {
        ({ parse: lexerParse } = await import(
          minimal ? '../dist/lexer.minimal.asm.js' : '../dist/lexer.asm.js'
        ));
    likely benign LLM, confidence 0.92 Test helper imports either the ASM or standard local lexer build.
    Reasoning

    The specifier is a ternary choosing between two local dist build paths based on a test flag. It only loads the project's own build outputs.

  5. info warn → info by review dynamic-import test/_lexer.cjs:13:25

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

      else {
        const lexer = await import(minimal ? '../dist/lexer.minimal.js' : '../dist/lexer.js');
        await lexer.init();
        lexerParse = lexer.parse;
    likely benign LLM, confidence 0.92 Test helper imports a local minimal or full lexer build.
    Reasoning

    The specifier chooses between two local dist files according to a test flag, which is ordinary test-harness module selection.

  6. info unicode-mixed-script test/_unit.cjs:832:41

    identifier `statehashထ` mixes scripts: Latin + Other (in string/comment) (raw pass, confidence 0.40)

        assert.strictEqual(imports.length, 1);
        assert.strictEqual(imports[0].n, './statehashထ.js');
        assert.strictEqual(source.slice(imports[0].s, imports[0].e), '"./statehash\\u1011.js"');
      });
  7. info warn → info by review encoding-base64 test/_unit.cjs:973:47

    base64-like blob (78 bytes, compression ratio 1.01) (raw pass, confidence 0.60)

      test('Multiline string escapes', () => {
        parse("const str = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABmJLR0QA/wAAAAAzJ3zzAAAGTElEQV\\\r\n\t\tRIx+VXe1BU1xn/zjn7ugvL4sIuQnll5U0ELAQxig7WiQYz6NRHa6O206qdSXXSxs60dTK200zNY9q0dcRpMs1jkrRNWmaijCVoaU';\r\n");
      });
    likely benign LLM, confidence 0.93 Unit test fixture contains a base64 PNG data URI inside a string literal.
    Reasoning

    The base64 string is a PNG data URI embedded as a literal in a unit test that checks multiline string escaping. It is test fixture data, not a payload.

  8. info warn → info by review encoding-base64 test/_unit.cjs:973:134

    base64-like blob (101 bytes, compression ratio 1.11) (raw pass, confidence 0.60)

      test('Multiline string escapes', () => {
        parse("const str = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABmJLR0QA/wAAAAAzJ3zzAAAGTElEQV\\\r\n\t\tRIx+VXe1BU1xn/zjn7ugvL4sIuQnll5U0ELAQxig7WiQYz6NRHa6O206qdSXXSxs60dTK200zNY9q0dcRpMs1jkrRNWmaijCVoaU';\r\n");
      });
    likely benign LLM, confidence 0.93 Second base64 fragment of the same PNG data URI test fixture.
    Reasoning

    This is the same PNG data URI fixture in the same string-escape test, so it is test data with no execution role.

  9. info unicode-mixed-script test/_unit.cjs:1021:32

    identifier `p𓀀s` mixes scripts: Latin + Other (in string/comment) (raw pass, confidence 0.40)

      test('Simple export with unicode conversions', () => {
        const source = `export var p𓀀s,q`;
        const [imports, exports] = parse(source);
        assert.strictEqual(imports.length, 0);
  10. info unicode-mixed-script test/_unit.cjs:1025:45

    identifier `p𓀀s` mixes scripts: Latin + Other (in string/comment) (raw pass, confidence 0.40)

        assert.strictEqual(exports.length, 2);
        assertExportIs(source, exports[0], {n: 'p𓀀s', ln: 'p𓀀s' });
        assertExportIs(source, exports[1], {n: 'q', ln: 'q' });
      });
  11. info unicode-mixed-script test/_unit.cjs:1025:59

    identifier `p𓀀s` mixes scripts: Latin + Other (in string/comment) (raw pass, confidence 0.40)

        assert.strictEqual(exports.length, 2);
        assertExportIs(source, exports[0], {n: 'p𓀀s', ln: 'p𓀀s' });
        assertExportIs(source, exports[1], {n: 'q', ln: 'q' });
      });
  12. info unicode-mixed-script test/_unit.cjs:1093:23

    identifier `a𓀀` mixes scripts: Latin + Other (in string/comment) (raw pass, confidence 0.40)

        const source = `
          export function a𓀀 () {
    
          }
  13. info unicode-mixed-script test/_unit.cjs:1102:45

    identifier `a𓀀` mixes scripts: Latin + Other (in string/comment) (raw pass, confidence 0.40)

        assert.strictEqual(exports.length, 2);
        assertExportIs(source, exports[0], {n: 'a𓀀', ln: 'a𓀀' });
        assertExportIs(source, exports[1], {n: 'Q', ln: 'Q' });
      });
  14. info unicode-mixed-script test/_unit.cjs:1102:58

    identifier `a𓀀` mixes scripts: Latin + Other (in string/comment) (raw pass, confidence 0.40)

        assert.strictEqual(exports.length, 2);
        assertExportIs(source, exports[0], {n: 'a𓀀', ln: 'a𓀀' });
        assertExportIs(source, exports[1], {n: 'Q', ln: 'Q' });
      });
  15. info unicode-mixed-script test/_unit.cjs:1556:9

    identifier `x𓀀` mixes scripts: Latin + Other (in string/comment) (raw pass, confidence 0.40)

            braced as bracedOut,
            x𓀀 as astral
          };
          import {
  16. info warn → info by review dynamic-import test/_unit.cjs:2884:31

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

          // file imported has already awaited init.
          const { parse } = await import(min ? '../dist/lexer.minimal.js?preinit' : '../dist/lexer.js?preinit');
          const [imports, exports] = parse(`import 'a'; export var p = 5`);
          assert.strictEqual(imports.length, 1);
    likely benign LLM, confidence 0.92 Unit test dynamically imports a local lexer build with a preinit query string.
    Reasoning

    The dynamic import chooses between local dist lexer builds with query strings for a pre-init test case. This is test-harness logic against the project's own outputs.

  17. info warn → info by review dynamic-import test/_unit.cjs:2891:31

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

        test('Sourcename on the pre-init path', async () => {
          const { parse } = await import(min ? '../dist/lexer.minimal.js?preinit-err' : '../dist/lexer.js?preinit-err');
          assert.throws(() => parse('import{', 'my-file.js'), /^Error: Parse error my-file\.js:\d+:\d+$/);
        });
    likely benign LLM, confidence 0.92 Unit test dynamically imports a local lexer build for error-path checks.
    Reasoning

    This dynamic import selects a local dist build for a pre-init error-path test. It is ordinary test loading.

  18. info warn → info by review dynamic-import test/_unit.cjs:2937:21

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

      test('Entry point exports parse and init only', async () => {
        const m = await import(process.env.ASM
          ? (min ? '../dist/lexer.minimal.asm.js' : '../dist/lexer.asm.js')
          : (min ? '../dist/lexer.minimal.js' : '../dist/lexer.js'));
    likely benign LLM, confidence 0.93 Test imports a local lexer entry point selected by environment flags.
    Reasoning

    The import specifier is a conditional over local dist files chosen by environment flags, used to check the entry point's exports. This is benign test scaffolding.

  19. info warn → info by review dynamic-import test/fuzz-ts.mjs:32:19

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

      : '../dist/lexer.js';
    const mod = await import(new URL(ENGINE, import.meta.url).href);
    if (mod.init) await mod.init();
    const parse = mod.parse;
    likely benign LLM, confidence 0.80 Fuzz test loads the lexer engine module relative to its own location.
    Reasoning

    The fuzz harness imports the engine module from a URL built relative to import.meta.url, which resolves to a local build. Fuzzing harnesses commonly load the system under test this way.

  20. info whitespace-anomaly test/integration.cjs:5:1

    file mixes tab and space indentation (9 tab-indented and 27 space-indented lines) (raw pass, confidence 0.40)

    const init = (async () => {
      if (parse) return;
      if (process.env.WASM) {
        const m = await import('../dist/lexer.js');
  21. info warn → info by review dynamic-import test/no-eval/index.cjs:10:9

    `require` called with a non-literal specifier (ast pass, confidence 0.60)

        const lexer = commonjs
          ? require(minimal ? '../../dist/lexer.minimal.cjs' : '../../dist/lexer.cjs')
          : await import(minimal ? '../../dist/lexer.minimal.js' : '../../dist/lexer.js');
        await lexer.init();
    likely benign LLM, confidence 0.92 No-eval test loads a local lexer build through require or import.
    Reasoning

    The require and import calls select between local dist builds by flag, with the ESM path only as a fallback. The test confirms the library runs without eval, and the loads target only project outputs.

  22. info warn → info by review dynamic-import test/no-eval/index.cjs:11:15

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

          ? require(minimal ? '../../dist/lexer.minimal.cjs' : '../../dist/lexer.cjs')
          : await import(minimal ? '../../dist/lexer.minimal.js' : '../../dist/lexer.js');
        await lexer.init();
        parse = lexer.parse;
    likely benign LLM, confidence 0.92 No-eval test dynamically imports a local lexer build as the ESM fallback.
    Reasoning

    This is the ESM branch of the same conditional loader choosing between local dist builds, consistent with a no-eval compatibility test.

  23. info unicode-mixed-script test/no-eval/index.cjs:22:48

    identifier `unicode𠈄` mixes scripts: Latin + Other (in string/comment) (raw pass, confidence 0.40)

          [String.raw`import 'escaped\x2dspecifier'`, 'escaped-specifier'],
          [String.raw`import 'unicode\u{20204}'`, 'unicode𠈄'],
          ["import 'line\\\ncontinuation'", 'linecontinuation'],
          [String.raw`import 'nul\0character'`, 'nul\0character'],
  24. info warn → info by review long-line test/samples/d3.js:17439:1

    line length 10326 characters (raw pass, confidence 0.65)

    export { version, bisectRight as bisect, bisectRight, bisectLeft, ascending, bisector, cross, descending, deviation, extent, histogram, freedmanDiaconis as thresholdFreedmanDiaconis, scott as thresholdScott, thresholdSturges, max, mean, median, merge, min, pairs, permute, threshold as quantile, sequence as range, scan,
    likely benign LLM, confidence 0.94 Bundled d3 sample file contains a very long line consisting of an export list.
    Reasoning

    This is a single long export statement in a bundled d3 sample file. Long lines are typical of bundled or minified library code and show no hidden or malicious behaviour.

  25. info dynamic-execution test/samples/magic-string.js:181:57

    `btoa` encodes a value as base64 at runtime — used in exfiltration patterns (ast pass, confidence 0.55)

    SourceMap.prototype.toUrl = function toUrl () {
    	return 'data:application/json;charset=utf-8;base64,' + btoa(this.toString());
    };
  26. info whitespace-anomaly test/samples/rollup.js:2:1

    file mixes tab and space indentation (931 tab-indented and 19838 space-indented lines) (raw pass, confidence 0.40)

    /*
    	Rollup.js v0.65.0
    	Sat, 25 Aug 2018 13:41:58 GMT - commit 903516a760ce02804e7c5e4578ddce56e6f6bd17
  27. info dynamic-execution test/samples/rollup.js:907:57

    `btoa` encodes a value as base64 at runtime — used in exfiltration patterns (ast pass, confidence 0.55)

    SourceMap.prototype.toUrl = function toUrl () {
    	return 'data:application/json;charset=utf-8;base64,' + btoa(this.toString());
    };
  28. line length 1190 characters (raw pass, confidence 0.50)

    var astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,14,29,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,28,43,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,
  29. line length 594 characters (raw pass, confidence 0.50)

    var astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,574,3,9,9,525,10,176,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,6,1,45,0,13,2,49,13,9,3,4,9,83,11,7,0,161,11,6,9,7,3,56,1,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,5,0,82,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,243,14,166,9

Reproduce This Scan

Run disclude locally to verify. Add --format sarif for SARIF output. Add --llm (with an API key in the environment) to include the LLM review.

cargo install disclude --version 4.1.0
git clone https://github.com/guybedford/es-module-lexer es-module-lexer && cd es-module-lexer
git checkout 3.0.4
disclude scan --severity info --diff 3.0.3 .