Skip to content

overwrite method can cause state corruption #115

@alangpierce

Description

@alangpierce

Follow-up from #113, where an optimization commit was causing the decaffeinate build to fail.

I tracked down the issue and found two problems with the code change:

  • In the first.next = last.next; line, it might end up causing first.next to point to null. In that case, this.lastChunk needs to be updated. In the test case below, this.lastChunk ends up pointing to an object that isn't actually the last chunk.
  • The byStart and byEnd maps are never updated to remove the old chunks, so later operations will find those unreferenced chunks and insert into them. This basically means that later insertions at certain points are just lost.

Here's a test case that worked before and fails now:

		it ( 'allows later insertions at the end', () => {
			const s = new MagicString( 'abcdefg' );

			s.appendLeft(4, '(');
			s.overwrite( 2, 7, '' );
			s.appendLeft(7, 'h');
			console.log(`s.toString is ${s.toString()}`);
			assert.equal( s.toString(), 'abh' );
		});

I was thinking of writing up a fix, but the code seems a bit delicate, so probably @Rich-Harris is better-qualified to come up with a confident fix that updates all relevant state. It might be best to just revert the optimization if the added complexity/risk isn't worth it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions