From 37893413a837eaf72c2d533016e2c068db70226b Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 7 May 2024 15:05:39 -0700 Subject: [PATCH] Fix an off-by-1 error in section lookup In an indexed map, the offset line & column are stored 1-based. However, the lookup for originalPositionFor was not incrementing the 0-based column from the API argument. --- lib/source-map-consumer.js | 4 +++- test/test-source-map-consumer.js | 9 +++++++++ test/util.js | 25 +++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/lib/source-map-consumer.js b/lib/source-map-consumer.js index be1289d9..2c22219c 100644 --- a/lib/source-map-consumer.js +++ b/lib/source-map-consumer.js @@ -842,8 +842,10 @@ class IndexedSourceMapConsumer extends SourceMapConsumer { return cmp; } + // The generated column is 0-based, but the section offset column is + // stored 1-based. return ( - aNeedle.generatedColumn - section.generatedOffset.generatedColumn + aNeedle.generatedColumn - (section.generatedOffset.generatedColumn - 1) ); } ); diff --git a/test/test-source-map-consumer.js b/test/test-source-map-consumer.js index 1bc09b85..dc40ba28 100644 --- a/test/test-source-map-consumer.js +++ b/test/test-source-map-consumer.js @@ -2183,3 +2183,12 @@ exports["test SourceMapConsumer.with and exceptions"] = async function ( assert.equal(error, 6); assert.equal(consumer._mappingsPtr, 0); }; + +exports["test a mapping at the boundary of indexed source map offset"] = + async function (assert) { + const map = await new SourceMapConsumer( + util.indexedTestMapAtOffsetBoundary + ); + util.assertMapping(1, 0, "/the/root/one.js", 1, 0, null, null, map, assert); + map.destroy(); + }; diff --git a/test/util.js b/test/util.js index d99669c3..665e70e2 100644 --- a/test/util.js +++ b/test/util.js @@ -226,6 +226,31 @@ exports.indexedTestMapColumnOffset = { }, ], }; +// This mapping is for testing a case where the mapped position is at the +// section offset. +exports.indexedTestMapAtOffsetBoundary = { + version: 3, + file: "min.js", + sections: [ + { + offset: { + line: 0, + column: 0, + }, + map: { + version: 3, + sources: ["one.js"], + sourcesContent: [ + "ONE.foo = function (bar) {\n return baz(bar);\n };", + ], + names: ["bar", "baz"], + mappings: "AAAA", + file: "min.js", + sourceRoot: "/the/root", + }, + }, + ], +}; exports.testMapWithSourcesContent = { version: 3, file: "min.js",