Skip to content

Mutating options.format is unsafe when config is re-used #1341

@robhogan

Description

@robhogan
Contributor

Bug report or Feature request?
Bug report

Version (complete output of terser -V or specific git commit)
Confirmed on 5.15.0 and current main (e062dc8)

Description
Terser stores its source map output on the input config object, under options.format.source_map. The returned value includes a getter for a map property, which uses options.format.source_map. If options.format.source_map changes between the minify result and the use of the getter, the output may be incorrect.

In particular, a second call to minify using the same config object will clobber source_map.

Failing test

import {minify} from 'terser';

test('subsequent calls do not clobber previous output', async () => {
  const config = {
    format: {},
    sourceMap: true,
  };

  const fooResult = await minify('"foo";', config);
  const barResult = await minify('module.exports = "bar";', config);

  const fooMap = fooResult.map; // Uses a getter which uses config.format.source_map, which was overwritten by the second call.
  const barMap = barResult.map;

  expect(barMap).toEqual(
    '{"version":3,"names":["module","exports"],"sources":["0"],"mappings":"AAAAA,OAAOC,QAAU"}',
  ); // Succeeds - `barMap` is correct
  expect(fooMap).not.toEqual(barMap); // <-- Fails - `fooMap` is `barMap`
});

Expected result
Test passes - reusing a config object should not affect previous output.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @robhogan

      Issue actions

        Mutating `options.format` is unsafe when config is re-used · Issue #1341 · terser/terser