Skip to content

Parsing bug with typescript generated source map #18

@tigerwill90

Description

@tigerwill90

Hi there,

First of all, thanks for this nice package :)

I found a strange behavior using source map generated by typescript. It's look like a parsing bug but maybe I missed something.

Here are two compiled js outputs using tsc. The only diff is the line where the error is thrown.

/*
test.ts
1 | throw Error("foo")
2 |
3 |
*/
var js1 = `"use strict";
throw Error("foo");
//# sourceMappingURL=test.js.map`

var map1 = `{"version":3,"file":"test.js","sourceRoot":"","sources":["../test.ts"],"names":[],"mappings":";AAAA,MAAM,KAAK,CAAC,KAAK,CAAC,CAAA"}`

/*
test.ts
1 |
2 | throw Error("foo")
3 |
*/
var js2 = `"use strict";
throw Error("foo");
//# sourceMappingURL=test.js.map`

var map2 = `{"version":3,"file":"test.js","sourceRoot":"","sources":["../test.ts"],"names":[],"mappings":";AACA,MAAM,KAAK,CAAC,KAAK,CAAC,CAAA"}`

Here is the mapping dump from https://pastcompute.github.io/ScriptMapper/ for map1

../test.ts,2,0,1,0,null
../test.ts,2,6,1,6,null
../test.ts,2,11,1,11,null
../test.ts,2,12,1,12,null
../test.ts,2,17,1,17,null
../test.ts,2,18,1,18,null
../test.ts,2,19,1,18,null

And it look like the first decoded mapping segment is missing, note that the mapping slice is allocated with the correct capacity.

// len(6), cap(7)
0 = {sourcemap.mapping} 
 genLine = {int32} 2
 genColumn = {int32} 6
 sourcesInd = {int32} 0
 sourceLine = {int32} 1
 sourceColumn = {int32} 6
 namesInd = {int32} -1
1 = {sourcemap.mapping} 
 genLine = {int32} 2
 genColumn = {int32} 11
 sourcesInd = {int32} 0
 sourceLine = {int32} 1
 sourceColumn = {int32} 11
 namesInd = {int32} -1
2 = {sourcemap.mapping} 
 genLine = {int32} 2
 genColumn = {int32} 12
 sourcesInd = {int32} 0
 sourceLine = {int32} 1
 sourceColumn = {int32} 12
 namesInd = {int32} -1
3 = {sourcemap.mapping} 
 genLine = {int32} 2
 genColumn = {int32} 17
 sourcesInd = {int32} 0
 sourceLine = {int32} 1
 sourceColumn = {int32} 17
 namesInd = {int32} -1
4 = {sourcemap.mapping} 
 genLine = {int32} 2
 genColumn = {int32} 18
 sourcesInd = {int32} 0
 sourceLine = {int32} 1
 sourceColumn = {int32} 18
 namesInd = {int32} -1
5 = {sourcemap.mapping} 
 genLine = {int32} 2
 genColumn = {int32} 19
 sourcesInd = {int32} 0
 sourceLine = {int32} 1
 sourceColumn = {int32} 18
 namesInd = {int32} -1

Here is the mapping dump for map2

../test.ts,2,0,2,0,null
../test.ts,2,6,2,6,null
../test.ts,2,11,2,11,null
../test.ts,2,12,2,12,null
../test.ts,2,17,2,17,null
../test.ts,2,18,2,18,null
../test.ts,2,19,2,18,null

And this produce the expected result

// len(7), cap(7)
0 = {sourcemap.mapping} 
 genLine = {int32} 2
 genColumn = {int32} 0
 sourcesInd = {int32} 0
 sourceLine = {int32} 2
 sourceColumn = {int32} 0
 namesInd = {int32} -1
1 = {sourcemap.mapping} 
 genLine = {int32} 2
 genColumn = {int32} 6
 sourcesInd = {int32} 0
 sourceLine = {int32} 2
 sourceColumn = {int32} 6
 namesInd = {int32} -1
2 = {sourcemap.mapping} 
 genLine = {int32} 2
 genColumn = {int32} 11
 sourcesInd = {int32} 0
 sourceLine = {int32} 2
 sourceColumn = {int32} 11
 namesInd = {int32} -1
3 = {sourcemap.mapping} 
 genLine = {int32} 2
 genColumn = {int32} 12
 sourcesInd = {int32} 0
 sourceLine = {int32} 2
 sourceColumn = {int32} 12
 namesInd = {int32} -1
4 = {sourcemap.mapping} 
 genLine = {int32} 2
 genColumn = {int32} 17
 sourcesInd = {int32} 0
 sourceLine = {int32} 2
 sourceColumn = {int32} 17
 namesInd = {int32} -1
5 = {sourcemap.mapping} 
 genLine = {int32} 2
 genColumn = {int32} 18
 sourcesInd = {int32} 0
 sourceLine = {int32} 2
 sourceColumn = {int32} 18
 namesInd = {int32} -1
6 = {sourcemap.mapping} 
 genLine = {int32} 2
 genColumn = {int32} 19
 sourcesInd = {int32} 0
 sourceLine = {int32} 2
 sourceColumn = {int32} 18
 namesInd = {int32} -1

So if I haven't missed anything along the way, smp.Source(2, 1) should produce 1, 0, true

SourceMap(map1)
func SourceMap(m string) {
	smp, err := sourcemap.Parse("test.js.map", []byte(m))
	if err != nil {
		panic(err)
	}
	fmt.Println(smp.Source(2, 1)) // 0 0 false
}

Let me know if I can help you reproduce this strange behavior somehow :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions