From 20c2fe3f5bbec2af81211ac3d9a5edd17449e1eb Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Fri, 29 May 2026 14:46:41 +0100 Subject: [PATCH 01/28] Adding security policy --- SECURITY.md | 23 +++++++++++++++++++++++ bugzilla-security-section.png | Bin 0 -> 57209 bytes 2 files changed, 23 insertions(+) create mode 100644 SECURITY.md create mode 100644 bugzilla-security-section.png diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..14b14fab --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,23 @@ +# Sourcemap Security Policy +Mozilla takes the security of our software seriously. If you believe you have found a security +vulnerability in the [source-map](https://github.com/mozilla/source-map) library, please report it to us as described below. + +## Report a security bug! +Please report source-map security vulnerabilities at [bugzilla.mozilla.org](https://bugzilla.mozilla.org/enter_bug.cgi?format=__default__&product=DevTools&short_desc=[source-map%20security]) and make sure that the +checkbox in the "Security" section is checked so the required access controls are automatically configured: + +![Security section in Bugzilla](bugzilla-security-section.png) + +## Bounty program? +There is not a bug bounty program for this library ([source-map](https://github.com/mozilla/source-map)) as a whole, but security +vulnerabilities may be eligible for a bug bounty if they can be exploited as used by Firefox. +Please see the [Firefox bug bounty program](https://www.mozilla.org/en-US/security/client-bug-bounty/) for more details and how to submit bugs to that program. + +## I have a question! Who can help? +Questions regarding security bugs or our bounty programs can be directed to security@mozilla.com. +An encryption key for sending [GPG encrypted mails](https://www.mozilla.org/en-US/security/#pgpkey) is also available. + +## Where can I find security advisories? +We publish security advisories for all released versions of the library as part of the release notes. + +General information about security at Mozilla is available at [https://www.mozilla.org/en-US/security/](https://www.mozilla.org/en-US/security/). \ No newline at end of file diff --git a/bugzilla-security-section.png b/bugzilla-security-section.png new file mode 100644 index 0000000000000000000000000000000000000000..99e095c0c10a0ccdf0fdaf7a42785e14320df931 GIT binary patch literal 57209 zcma%j1y~hb*ES`of^>(V9J-}L=`Mjomw>c%gGe_h-Q6kO4RUA>C7n{z-T&~s?-T!b zeb1+O9nLT_YtP=R*S+=_q#!5$1eFjK1_tJdq=bkP3=EPgaD0Z02>dp(F-nAiK`k;B z7FLiH7A9A)wKg`jFoJ=R2#SeAdW)rw_i<6iRpPz3LbmThHX1@CrYmTyDBqV#2*iT$ z=@W^%mUngf^G`;iv4u;S*y?D{1N}rRU}zi2LjoHZaYaPe$(Ar2&js)A)9#1rH$3b% zTHN-Nju(=7VItSTaIabEp9rA}YU8hMy$J~n&0N-jL9U01gm~w$lzUbSBI#UanbQoVlZquLGzQfOX+HsMgutG7EjwKFTpVV7kX+~kt zU@W(*ho@}>sfVW+vbzpZQ+>nH7lk>X!j;BHhmjN)Uf0>M(YH8WF*4i%zVp zG--<=b_D0qCI0ci!rk?!?n>7^gK;s}%McuNeuoqzGrLBhk{`W0d;s zPbLYcXB(JQNP)NYeW?a+8e-+nRyI!wP&fMgH^wgCJ8#Dv~D~p5Qeu28pfj9EC0jIoQ`A-8m3FC_QY%5kyAo zE0w;gz;VK6|Fq$;c7SUJ(g-vA(`G+`PEb5Te|up$qXjBdAMq!AKwHt0GZ)U#C%Yx> z4=h@UX}(EI{Rgra0(=OqzSN2^FT67|*%f*~JP@4qh~PKf8NT_0`FwAm6+Tu8FcWpi z*vs@+C{suq0kc1n6(-8s9o5-XU?)lmUI=9ric2pVk==ZHqJ6^b3U~WNxF=sPl-Uvg z=9D~#HS70U!s#nh%VKqPUe=6y%(RZt$oR%bh zn&->b!M${2L$Afdi06dtgz1Fhgv1$q9T?YEw90TmdI91iOABM_m|9|5*85odMeBqLCr>3CDpwXv$25SE@ zO{++6qp_0MRo+GYnZ7S_O)B_hkVK-zQ%78YjkVWYZ0HZ zC9x!Psl;tV-W9z2vPRN3rG!93LgPPfRzP3yyns!qHd{v$E88JQJ4byiDMvbISn^z2 z9-{DW!05(E=^g4jvv;Nad~w}<+mMES+jn;F9 z*5Yl0Y%gu|)?C+Kt{JVz^#$~m#WBUSk_(E6DmoO%n6Wx=R(sEg-xjAAwka&p{(PIS zT$jb1QztU29#s^d2QG8gJ*>o(?bD`_G%ZuA95Xbk`kG;ze#En$1xbOF#eQR`(CyIq zT$`=mCyWE`R(K&{(~3o^T&U@QzPQXVInaM`|| zU@B-$?}Or3z0+VR@p+Yzk-3~hF~(Ion#EF5kVjCMP@-OT2@c5@oeGA|lueX!WR#Td z<~1ues$OS2eH~ExCEZRTPufIEO`cQBDZr|7&yHV|KUXJKr(_{rKz&hCP^DGoJ{5NI zqgCX)4_!+&6c+D|;`P90&i%-*zP?%^AYs|o4puj7jBc&6Fl}Y&i`P%q*D~j`c*AkX z(f7*qm5XJeC81HnR8{{;QbLUSSM~buly>TN*2fmds>ijs{7;B8iriw#AaXi{3w?d)D9;VVoKMo?4E9zwyNN_ zzU~{EVVo~*-;;MUyr#M)yx!`f84!e%o9=9(}0qA|y(|KJR1!Wm!BefIgXUAu=8=Q4- zOdffORtg@NTLZ@J)XcQ*(+YShR zGuxTnk=a?;ncFenfz}!DT!!+M=v?UA@HNpIk>$*eOxnzsY7J$4<+kiIv^<;*)-el( zr$wb@syZo6R~>`}9K{?a2FxtWEF3Jl;Jaeh$#?W@XCHnd%*J>`-hN&k_&!Xq!SeyF z-q7Z$ji1f%D#^-ucLX)p3+xw7EA>ZG&eoXCm=Q1JUR+YEyd0zopq|QGQZ`T;IyAbJ zya}&1GoLEk#lc6heI#7qSb(HN?JLj`%nq_t(U5K+9wT-LIT2k9@@FGvlVTGnMbmUL zZXR&GyV{fK97stpR3}vzv=p+|vwpvrUtu%bvn(4b+si4OWXM@-Jv#Hb(#XDOW3te) z%TjXIbMRF^w%y zt{2I`c1y0KUo#Dnf{;X!0)jn4G@qK1&Dd>9OTOv5Rf-$C>ZA>DB2DG#;I`e!KOSu` zEbKjs@VJXQUu^?eCu`JTBuZUQ%__%7hfcSD6?CWU;Abo9**zuYxvrq1pdwx^>);S3 zHMplyr}~!Hll5wCSJ^60V>@&wd`fxeSl$Pk31#vOzpO87&&#-dd@D1ro>Cb=L=)yB ztDtNQ6|sABtRVePdY^mWZnxyDB&;?5M#)8I)qU&HC0ZjBCeshCrrPMyAh=#TJ=-UrbnS$P?z1p-U&MG&{F9s;?k5>E2rDJCs$!Vk|sHm8cG_7ysEFN zD|#F9wqgfMVrOe=HQnOQb(&V~H;%Mx8`bt%_UD^gS3IqC-!BSz+24=Am@HlTtRY#G z8uKN4Rykm>#h-((Y(}wSsEt|)Zd3)|@!RW9Th?8h9zew@e@4Z%=H1>Iv2PGus*lEB zfluv1Ha2?sd#qc*mj)*}OY0{^bAs>gxNbD=PrnPM-2Y4sjK}w&bZ0xRSxOmegq-&; z)XF2u2wX-U>ATYIXN~n1%Ad$mZGSTf(?Otbc3qhVu%i;d)%LQTi; zTU~*1)>#X7i!+ajM>pxG|?t|j7Ldj6i+n`?Wq#|xH^2+>}Tf=wUD zUSo~GlE$*KFtoriGRz}bOc;3J2p0GU14{_==#OI<7%5nyzmAn)LI1r64hAN`6b9kH z_h2cZ7%H~eRR7$o2?OyJ|24)^EXNUG`Ze;&h}0oPz&D+^0X0^iDpwnj!) zcJHn2%XPmq11C^ENT}Pvz~H`k_`pgkQ60d*z|EPy1>1vVWq1s&EgALSSsNHJI$M5t z7zc*WnFlzuG_uzxceb>!vg2{)fBwfEJizh8X{P7of81hk&i@=Nt3WPnZEHmSijkR- z`MCfpIXO9>?K@*0B@wazk^_J7KYwp;|AB{z$;ruy(TR=G+SY`Lg`1n3iJ6s&m6ZXw zgTc@1E7>|mbk*%<`rKORTy};ib z=lkPH|KG*G=lLH(1yg4u3$TbOKxqf8Nq~imlk2}^|MSxSN~-=hDJ%P{e^UPA%0DO{ z*1)4=WM^&R@W4YAD^q&`Rz9Zx?ezbo0{=}Wz{1YX#PVOVf1dxJH0u9C^Uw4DlSbaw z6kwzN!}J9He8xY|{r7%8rU&`|Lm&R5Y=4{uv`qk&kLfSX6+j(?Md^Wo5rUBvdHvQI z_Gb!8la=!2$EkYCsbrSp;%|{O!q1gopav=Vf2I*lq%xw<^i}W=eeyQ?4plM=Bja%f zt9$}l+>XxPf#7h=a z5?$s({|n+jM%T-K_FhDs2UQ#yx9IZ8d;QS?gZAJT<~JP;F(uD`YXDVpg-O3m^mV-0 z!b^u0tlnp}iWQxYd>Kg7xr~S~IsFYdhKlr_U|PNS)ncf~z1zjePttwq>{B;ie-|$x zysmh{x$gWHyU2!u_=l8Asb3~e{{%)%;p>i)U-O2F8H|z+|D+Em|7S1LN%nGS69aZp zy*Sqr7k1I|Yj9zYOH83rG^zCe#ozx5z$Zp%Q$+ZlfM?V_N!O4p$TFteELp@Q*oamW zJ3kq{o0c;!rf}VG4)pJm`iCfuUwV&tiQ%urTV4iOu@CuOyYmKz)E`9~QbiXU`4viy z6Q^DO#z1YwBIIhRJ)SKu7&F+y7&eT{!B1Y$;XNY`VCATRmdV_gIWV^FwfqL7$h{Lp z$<@MvDQUF~o_A`uloVGGqAFSGrCGL+Z5$=d$Nh#XQZdtE=I2O+*>zDbZa5=&NqBnS zat+m12;M%u{|(W@q6}yt5RUpyj)e>{<1ml*@Nm$Bxl0`=H*o%M6ZkJ1z_8iwPW zYbUD%HDe57zGNt@=YIXfVP#AAds<9|aW#U>>pH5C@BfLTbbXe#+iXv=C2dh*-+iyg zuxywm$YaNh9ukwZcM+opl-O;knuqhUWA;76^;-SP~BF zrA&Soomycg+mjq~BU(Kz|2GcX;{`Zq6T#?v|EE9tQ_Jx`A&f+13XuRV=~<&f?hi$V z(sTvUHx-cBq~8;#aEcIqs((xLh5u8I6#?z_L~Z0=qW~Kp&EFD)aFCF?c;b$fVXIU{ z;$nLDwt^IDkLds5NB^96zIeJt1tDa7?l$n|T`72Q7%0A&eoKEq&+_xA2OV-%%!@HE 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

2J*YEva_ClGPwNepO_t-L0m=YJwqIL`CeU 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 Date: Tue, 7 May 2024 15:05:39 -0700 Subject: [PATCH 02/28] 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 | 5 ++++- test/test-source-map-consumer.js | 9 +++++++++ test/util.js | 25 +++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/lib/source-map-consumer.js b/lib/source-map-consumer.js index be1289d9..7381a668 100644 --- a/lib/source-map-consumer.js +++ b/lib/source-map-consumer.js @@ -842,8 +842,11 @@ 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", From 66cf9e3daa611567e83ddd23aea3bcc65299f16f Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 16 Apr 2024 18:46:36 -0700 Subject: [PATCH 03/28] Add draft source map spec tests This commit adds a submodule for the draft source map spec test repo and adds a new test file that runs each of the test cases. Some test cases that have known failures are skipped, with a comment explaining why. --- .gitmodules | 3 ++ test/source-map-tests | 1 + test/test-spec-tests.js | 102 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+) create mode 100644 .gitmodules create mode 160000 test/source-map-tests create mode 100644 test/test-spec-tests.js diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..34cbd89f --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "test/source-map-tests"] + path = test/source-map-tests + url = https://github.com/takikawa/source-map-tests.git diff --git a/test/source-map-tests b/test/source-map-tests new file mode 160000 index 00000000..b2852261 --- /dev/null +++ b/test/source-map-tests @@ -0,0 +1 @@ +Subproject commit b2852261baf54df31ac33e2ccc5c8fe246c9a4bb diff --git a/test/test-spec-tests.js b/test/test-spec-tests.js new file mode 100644 index 00000000..bc169bbf --- /dev/null +++ b/test/test-spec-tests.js @@ -0,0 +1,102 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2024 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +const fs = require('node:fs/promises'); +const SourceMapConsumer = + require("../lib/source-map-consumer").SourceMapConsumer; + +const sourceMapSpecTests = require("./source-map-tests/source-map-spec-tests.json"); + +async function readJSON(path) { + const file = await fs.open(require.resolve(path)); + const json = JSON.parse(await file.readFile()); + file.close(); + return json; +} + +// Known failures due to intentional implementation choices or due to bugs. +const skippedTests = [ + // Versions are explicitly checked a bit loosely. + "versionNumericString", + // Stricter sources array checking isn't implemented. + "sourcesNotStringOrNull", + "sourcesAndSourcesContentBothNull", + // Stricter names array checking isn't implemented. + "namesMissing", + "namesNotString", + // This check isn't as strict in this library. + "invalidMappingNotAString1", + // A mapping segment with no fields is technically invalid in the spec. + "invalidMappingSegmentWithZeroFields", + // These tests fail due to imprecision in the spec about the 32-bit limit. + "invalidMappingSegmentWithColumnExceeding32Bits", + "invalidMappingSegmentWithOriginalLineExceeding32Bits", + "invalidMappingSegmentWithOriginalColumnExceeding32Bits", + // A large VLQ that should parse, but currently does not. + "validMappingLargeVLQ", + // The library currently doesn't check the types of offset lines/columns. + "indexMapOffsetLineWrongType", + "indexMapOffsetColumnWrongType", + // The spec is not totally clear about this case. + "indexMapInvalidBaseMappings", + // The spec's definition of overlap can be refined + "indexMapInvalidOverlap", + // Not clear if this test makes sense, but spec isn't clear on behavior + "validMappingNullSources" +] + +async function testMappingAction(assert, rawSourceMap, action) { + return SourceMapConsumer.with(rawSourceMap, null, (consumer) => { + let mappedPosition = consumer.generatedPositionFor({ + source: action.originalSource, + line: action.originalLine + 1, + column: action.originalColumn + }); + + assert.equal(mappedPosition.line, action.generatedLine + 1, `generated line didn't match, expected ${action.generatedLine + 1} got ${mappedPosition.line}`); + assert.equal(mappedPosition.column, action.generatedColumn, `generated column didn't match, expected ${action.generatedColumn} got ${mappedPosition.column}`); + + mappedPosition = consumer.originalPositionFor({ + line: action.generatedLine + 1, + column: action.generatedColumn, + }); + + assert.equal(mappedPosition.line, action.originalLine + 1, `original line didn't match, expected ${action.originalLine + 1} got ${mappedPosition.line}`); + assert.equal(mappedPosition.column, action.originalColumn, `original column didn't match, expected ${action.originalColumn} got ${mappedPosition.column}`); + assert.equal(mappedPosition.source, action.originalSource, `original source didn't match, expected ${action.originalSource} got ${mappedPosition.source}`); + if (action.mappedName) + assert.equal(mappedPosition.name, action.mappedName, `mapped name didn't match, expected ${action.mappedName} got ${mappedPosition.name}`); + }); +} + +for (let testCase of sourceMapSpecTests.tests) { + if (skippedTests.includes(testCase.name)) + continue; + exports[`test from source map spec tests, name: ${testCase.name}`] = + async function (assert) { + const json = await readJSON(`./source-map-tests/resources/${testCase.sourceMapFile}`); + let sourceMapFailed = false; + try { + const map = await new SourceMapConsumer(json); + map.eachMapping(() => {}); + map.destroy(); + } catch (exn) { + if (testCase.sourceMapIsValid) + assert.fail("Expected valid source map but failed to load successfully: " + exn.message); + return; + } + if (!testCase.sourceMapIsValid) + assert.fail("Expected invalid source map but loaded successfully"); + if (testCase.testActions) { + for (let testAction of testCase.testActions) { + if (testAction.actionType == "checkMapping") { + await testMappingAction(assert, json, testAction); + } + } + } + }; +}; From 1400b8c0725e075e724bfea8263ef4d2d0b626a0 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Thu, 9 May 2024 11:26:58 -0700 Subject: [PATCH 04/28] Add transitive mapping support in spec test harness --- test/source-map-tests | 2 +- test/test-spec-tests.js | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/test/source-map-tests b/test/source-map-tests index b2852261..ec5a471d 160000 --- a/test/source-map-tests +++ b/test/source-map-tests @@ -1 +1 @@ -Subproject commit b2852261baf54df31ac33e2ccc5c8fe246c9a4bb +Subproject commit ec5a471db6e3a736242e1e3d9a4aebea1472edf5 diff --git a/test/test-spec-tests.js b/test/test-spec-tests.js index bc169bbf..656da32c 100644 --- a/test/test-spec-tests.js +++ b/test/test-spec-tests.js @@ -73,6 +73,31 @@ async function testMappingAction(assert, rawSourceMap, action) { }); } +async function testTransitiveMappingAction(assert, rawSourceMap, action) { + return SourceMapConsumer.with(rawSourceMap, null, async (consumer) => { + assert.ok(Array.isArray(action.intermediateMaps), "transitive mapping case requires intermediate maps"); + + let mappedPosition = consumer.originalPositionFor({ + line: action.generatedLine + 1, + column: action.generatedColumn, + }); + + for (let intermediateMapPath of action.intermediateMaps) { + const intermediateMap = await readJSON(`./source-map-tests/resources/${intermediateMapPath}`); + await SourceMapConsumer.with(intermediateMap, null, (consumer) => { + mappedPosition = consumer.originalPositionFor({ + line: mappedPosition.line, + column: mappedPosition.column, + }); + }); + } + + assert.equal(mappedPosition.line, action.originalLine + 1, `original line didn't match, expected ${action.originalLine + 1} got ${mappedPosition.line}`); + assert.equal(mappedPosition.column, action.originalColumn, `original column didn't match, expected ${action.originalColumn} got ${mappedPosition.column}`); + assert.equal(mappedPosition.source, action.originalSource, `original source didn't match, expected ${action.originalSource} got ${mappedPosition.source}`); + }); +} + for (let testCase of sourceMapSpecTests.tests) { if (skippedTests.includes(testCase.name)) continue; @@ -95,6 +120,8 @@ for (let testCase of sourceMapSpecTests.tests) { for (let testAction of testCase.testActions) { if (testAction.actionType == "checkMapping") { await testMappingAction(assert, json, testAction); + } else if (testAction.actionType == "checkMappingTransitive") { + await testTransitiveMappingAction(assert, json, testAction); } } } From f1eb454e1af69b12a1e5a0b7403632677bc6876e Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 21 May 2024 14:59:41 -0700 Subject: [PATCH 05/28] Refine handling of null in the test harness * Don't do reverse lookup test if source is null * Allow "null" in cases where null is expected --- test/test-spec-tests.js | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/test/test-spec-tests.js b/test/test-spec-tests.js index 656da32c..a966c552 100644 --- a/test/test-spec-tests.js +++ b/test/test-spec-tests.js @@ -45,21 +45,19 @@ const skippedTests = [ "indexMapInvalidBaseMappings", // The spec's definition of overlap can be refined "indexMapInvalidOverlap", - // Not clear if this test makes sense, but spec isn't clear on behavior - "validMappingNullSources" ] +// The source-map library converts null sources to the "null" URL in its +// sources list, so for equality checking we accept this as null. +function nullish(nullOrString) { + if (nullOrString === "null") { + return null; + } + return nullOrString; +} + async function testMappingAction(assert, rawSourceMap, action) { return SourceMapConsumer.with(rawSourceMap, null, (consumer) => { - let mappedPosition = consumer.generatedPositionFor({ - source: action.originalSource, - line: action.originalLine + 1, - column: action.originalColumn - }); - - assert.equal(mappedPosition.line, action.generatedLine + 1, `generated line didn't match, expected ${action.generatedLine + 1} got ${mappedPosition.line}`); - assert.equal(mappedPosition.column, action.generatedColumn, `generated column didn't match, expected ${action.generatedColumn} got ${mappedPosition.column}`); - mappedPosition = consumer.originalPositionFor({ line: action.generatedLine + 1, column: action.generatedColumn, @@ -67,9 +65,23 @@ async function testMappingAction(assert, rawSourceMap, action) { assert.equal(mappedPosition.line, action.originalLine + 1, `original line didn't match, expected ${action.originalLine + 1} got ${mappedPosition.line}`); assert.equal(mappedPosition.column, action.originalColumn, `original column didn't match, expected ${action.originalColumn} got ${mappedPosition.column}`); - assert.equal(mappedPosition.source, action.originalSource, `original source didn't match, expected ${action.originalSource} got ${mappedPosition.source}`); + assert.equal(nullish(mappedPosition.source), action.originalSource, `original source didn't match, expected ${action.originalSource} got ${mappedPosition.source}`); if (action.mappedName) assert.equal(mappedPosition.name, action.mappedName, `mapped name didn't match, expected ${action.mappedName} got ${mappedPosition.name}`); + + // When the source is null, a reverse lookup may not make sense + // because there isn't a unique way to look it up. + if (action.originalSource !== null) { + let mappedPosition = consumer.generatedPositionFor({ + source: action.originalSource, + line: action.originalLine + 1, + column: action.originalColumn + }); + + assert.equal(mappedPosition.line, action.generatedLine + 1, `generated line didn't match, expected ${action.generatedLine + 1} got ${mappedPosition.line}`); + assert.equal(mappedPosition.column, action.generatedColumn, `generated column didn't match, expected ${action.generatedColumn} got ${mappedPosition.column}`); + } + }); } From 3a8af281ec4f0a3aa6576f32f83cb1b8f3a62018 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Thu, 6 Jun 2024 09:28:48 +0200 Subject: [PATCH 06/28] Update source map tests repo to official one --- .gitmodules | 2 +- test/source-map-tests | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 34cbd89f..163c0757 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "test/source-map-tests"] path = test/source-map-tests - url = https://github.com/takikawa/source-map-tests.git + url = https://github.com/tc39/source-map-tests.git diff --git a/test/source-map-tests b/test/source-map-tests index ec5a471d..14c89744 160000 --- a/test/source-map-tests +++ b/test/source-map-tests @@ -1 +1 @@ -Subproject commit ec5a471db6e3a736242e1e3d9a4aebea1472edf5 +Subproject commit 14c897444208365fc586a9c00c623bfb1955d731 From e04c5754cf0e67f551f2f60b96419e99c163d904 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Thu, 6 Jun 2024 09:56:18 +0200 Subject: [PATCH 07/28] Update skipped tests for ignoreList tests These aren't supported yet because the library doesn't support ignoreList yet and doesn't do any checking for it. --- test/test-spec-tests.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/test-spec-tests.js b/test/test-spec-tests.js index a966c552..dd1296ba 100644 --- a/test/test-spec-tests.js +++ b/test/test-spec-tests.js @@ -45,6 +45,11 @@ const skippedTests = [ "indexMapInvalidBaseMappings", // The spec's definition of overlap can be refined "indexMapInvalidOverlap", + // The library doesn't support the new ignoreList feature yet. + "ignoreListWrongType1", + "ignoreListWrongType2", + "ignoreListWrongType3", + "ignoreListOutOfBounds", ] // The source-map library converts null sources to the "null" URL in its From 00fb91bc0739fc8b9c1bdd3605d9ef7d5e118d75 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Thu, 6 Jun 2024 10:02:50 +0200 Subject: [PATCH 08/28] Address PR feedback --- package.json | 2 +- test/test-spec-tests.js | 23 +++++++++++++---------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 00077059..3301cbdd 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "license": "BSD-3-Clause", "scripts": { "lint": "eslint --fix *.js lib/ test/", - "test": "node test/run-tests.js", + "test": "git submodule update --init --recursive; node test/run-tests.js", "coverage": "c8 --reporter=text --reporter=html npm test", "prettier": "prettier --write .", "clean": "rm -rf coverage", diff --git a/test/test-spec-tests.js b/test/test-spec-tests.js index dd1296ba..12fc2cea 100644 --- a/test/test-spec-tests.js +++ b/test/test-spec-tests.js @@ -61,14 +61,18 @@ function nullish(nullOrString) { return nullOrString; } +function mapLine(line) { + return line + 1; +} + async function testMappingAction(assert, rawSourceMap, action) { return SourceMapConsumer.with(rawSourceMap, null, (consumer) => { mappedPosition = consumer.originalPositionFor({ - line: action.generatedLine + 1, + line: mapLine(action.generatedLine), column: action.generatedColumn, }); - assert.equal(mappedPosition.line, action.originalLine + 1, `original line didn't match, expected ${action.originalLine + 1} got ${mappedPosition.line}`); + assert.equal(mappedPosition.line, mapLine(action.originalLine), `original line didn't match, expected ${mapLine(action.originalLine)} got ${mappedPosition.line}`); assert.equal(mappedPosition.column, action.originalColumn, `original column didn't match, expected ${action.originalColumn} got ${mappedPosition.column}`); assert.equal(nullish(mappedPosition.source), action.originalSource, `original source didn't match, expected ${action.originalSource} got ${mappedPosition.source}`); if (action.mappedName) @@ -79,11 +83,11 @@ async function testMappingAction(assert, rawSourceMap, action) { if (action.originalSource !== null) { let mappedPosition = consumer.generatedPositionFor({ source: action.originalSource, - line: action.originalLine + 1, + line: mapLine(action.originalLine), column: action.originalColumn }); - assert.equal(mappedPosition.line, action.generatedLine + 1, `generated line didn't match, expected ${action.generatedLine + 1} got ${mappedPosition.line}`); + assert.equal(mappedPosition.line, mapLine(action.generatedLine), `generated line didn't match, expected ${mapLine(action.generatedLine)} got ${mappedPosition.line}`); assert.equal(mappedPosition.column, action.generatedColumn, `generated column didn't match, expected ${action.generatedColumn} got ${mappedPosition.column}`); } @@ -95,11 +99,11 @@ async function testTransitiveMappingAction(assert, rawSourceMap, action) { assert.ok(Array.isArray(action.intermediateMaps), "transitive mapping case requires intermediate maps"); let mappedPosition = consumer.originalPositionFor({ - line: action.generatedLine + 1, + line: mapLine(action.generatedLine), column: action.generatedColumn, }); - for (let intermediateMapPath of action.intermediateMaps) { + for (const intermediateMapPath of action.intermediateMaps) { const intermediateMap = await readJSON(`./source-map-tests/resources/${intermediateMapPath}`); await SourceMapConsumer.with(intermediateMap, null, (consumer) => { mappedPosition = consumer.originalPositionFor({ @@ -109,19 +113,18 @@ async function testTransitiveMappingAction(assert, rawSourceMap, action) { }); } - assert.equal(mappedPosition.line, action.originalLine + 1, `original line didn't match, expected ${action.originalLine + 1} got ${mappedPosition.line}`); + assert.equal(mappedPosition.line, mapLine(action.originalLine), `original line didn't match, expected ${mapLine(action.originalLine)} got ${mappedPosition.line}`); assert.equal(mappedPosition.column, action.originalColumn, `original column didn't match, expected ${action.originalColumn} got ${mappedPosition.column}`); assert.equal(mappedPosition.source, action.originalSource, `original source didn't match, expected ${action.originalSource} got ${mappedPosition.source}`); }); } -for (let testCase of sourceMapSpecTests.tests) { +for (const testCase of sourceMapSpecTests.tests) { if (skippedTests.includes(testCase.name)) continue; exports[`test from source map spec tests, name: ${testCase.name}`] = async function (assert) { const json = await readJSON(`./source-map-tests/resources/${testCase.sourceMapFile}`); - let sourceMapFailed = false; try { const map = await new SourceMapConsumer(json); map.eachMapping(() => {}); @@ -134,7 +137,7 @@ for (let testCase of sourceMapSpecTests.tests) { if (!testCase.sourceMapIsValid) assert.fail("Expected invalid source map but loaded successfully"); if (testCase.testActions) { - for (let testAction of testCase.testActions) { + for (const testAction of testCase.testActions) { if (testAction.actionType == "checkMapping") { await testMappingAction(assert, json, testAction); } else if (testAction.actionType == "checkMappingTransitive") { From 6c7c85a7ebafd50522750ba58d14a154218c6ea2 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Thu, 6 Jun 2024 10:09:55 +0200 Subject: [PATCH 09/28] Updates to satisfy linter Also makes the linter ignore the submodule --- package.json | 2 +- test/test-spec-tests.js | 123 +++++++++++++++++++++++++++++----------- 2 files changed, 92 insertions(+), 33 deletions(-) diff --git a/package.json b/package.json index 3301cbdd..ae0e6552 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ }, "license": "BSD-3-Clause", "scripts": { - "lint": "eslint --fix *.js lib/ test/", + "lint": "eslint --fix *.js lib/ test/ --ignore-pattern 'test/source-map-tests/**'", "test": "git submodule update --init --recursive; node test/run-tests.js", "coverage": "c8 --reporter=text --reporter=html npm test", "prettier": "prettier --write .", diff --git a/test/test-spec-tests.js b/test/test-spec-tests.js index 12fc2cea..fbe29117 100644 --- a/test/test-spec-tests.js +++ b/test/test-spec-tests.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/BSD-3-Clause */ -const fs = require('node:fs/promises'); +const fs = require("node:fs/promises"); const SourceMapConsumer = require("../lib/source-map-consumer").SourceMapConsumer; @@ -50,7 +50,7 @@ const skippedTests = [ "ignoreListWrongType2", "ignoreListWrongType3", "ignoreListOutOfBounds", -] +]; // The source-map library converts null sources to the "null" URL in its // sources list, so for equality checking we accept this as null. @@ -66,37 +66,68 @@ function mapLine(line) { } async function testMappingAction(assert, rawSourceMap, action) { - return SourceMapConsumer.with(rawSourceMap, null, (consumer) => { - mappedPosition = consumer.originalPositionFor({ + return SourceMapConsumer.with(rawSourceMap, null, consumer => { + let mappedPosition = consumer.originalPositionFor({ line: mapLine(action.generatedLine), column: action.generatedColumn, }); - assert.equal(mappedPosition.line, mapLine(action.originalLine), `original line didn't match, expected ${mapLine(action.originalLine)} got ${mappedPosition.line}`); - assert.equal(mappedPosition.column, action.originalColumn, `original column didn't match, expected ${action.originalColumn} got ${mappedPosition.column}`); - assert.equal(nullish(mappedPosition.source), action.originalSource, `original source didn't match, expected ${action.originalSource} got ${mappedPosition.source}`); - if (action.mappedName) - assert.equal(mappedPosition.name, action.mappedName, `mapped name didn't match, expected ${action.mappedName} got ${mappedPosition.name}`); + assert.equal( + mappedPosition.line, + mapLine(action.originalLine), + `original line didn't match, expected ${mapLine( + action.originalLine + )} got ${mappedPosition.line}` + ); + assert.equal( + mappedPosition.column, + action.originalColumn, + `original column didn't match, expected ${action.originalColumn} got ${mappedPosition.column}` + ); + assert.equal( + nullish(mappedPosition.source), + action.originalSource, + `original source didn't match, expected ${action.originalSource} got ${mappedPosition.source}` + ); + if (action.mappedName) { + assert.equal( + mappedPosition.name, + action.mappedName, + `mapped name didn't match, expected ${action.mappedName} got ${mappedPosition.name}` + ); + } // When the source is null, a reverse lookup may not make sense // because there isn't a unique way to look it up. if (action.originalSource !== null) { - let mappedPosition = consumer.generatedPositionFor({ + mappedPosition = consumer.generatedPositionFor({ source: action.originalSource, line: mapLine(action.originalLine), - column: action.originalColumn + column: action.originalColumn, }); - assert.equal(mappedPosition.line, mapLine(action.generatedLine), `generated line didn't match, expected ${mapLine(action.generatedLine)} got ${mappedPosition.line}`); - assert.equal(mappedPosition.column, action.generatedColumn, `generated column didn't match, expected ${action.generatedColumn} got ${mappedPosition.column}`); + assert.equal( + mappedPosition.line, + mapLine(action.generatedLine), + `generated line didn't match, expected ${mapLine( + action.generatedLine + )} got ${mappedPosition.line}` + ); + assert.equal( + mappedPosition.column, + action.generatedColumn, + `generated column didn't match, expected ${action.generatedColumn} got ${mappedPosition.column}` + ); } - }); } async function testTransitiveMappingAction(assert, rawSourceMap, action) { - return SourceMapConsumer.with(rawSourceMap, null, async (consumer) => { - assert.ok(Array.isArray(action.intermediateMaps), "transitive mapping case requires intermediate maps"); + return SourceMapConsumer.with(rawSourceMap, null, async consumer => { + assert.ok( + Array.isArray(action.intermediateMaps), + "transitive mapping case requires intermediate maps" + ); let mappedPosition = consumer.originalPositionFor({ line: mapLine(action.generatedLine), @@ -104,38 +135,66 @@ async function testTransitiveMappingAction(assert, rawSourceMap, action) { }); for (const intermediateMapPath of action.intermediateMaps) { - const intermediateMap = await readJSON(`./source-map-tests/resources/${intermediateMapPath}`); - await SourceMapConsumer.with(intermediateMap, null, (consumer) => { - mappedPosition = consumer.originalPositionFor({ - line: mappedPosition.line, - column: mappedPosition.column, - }); - }); + const intermediateMap = await readJSON( + `./source-map-tests/resources/${intermediateMapPath}` + ); + await SourceMapConsumer.with( + intermediateMap, + null, + consumerIntermediate => { + mappedPosition = consumerIntermediate.originalPositionFor({ + line: mappedPosition.line, + column: mappedPosition.column, + }); + } + ); } - assert.equal(mappedPosition.line, mapLine(action.originalLine), `original line didn't match, expected ${mapLine(action.originalLine)} got ${mappedPosition.line}`); - assert.equal(mappedPosition.column, action.originalColumn, `original column didn't match, expected ${action.originalColumn} got ${mappedPosition.column}`); - assert.equal(mappedPosition.source, action.originalSource, `original source didn't match, expected ${action.originalSource} got ${mappedPosition.source}`); + assert.equal( + mappedPosition.line, + mapLine(action.originalLine), + `original line didn't match, expected ${mapLine( + action.originalLine + )} got ${mappedPosition.line}` + ); + assert.equal( + mappedPosition.column, + action.originalColumn, + `original column didn't match, expected ${action.originalColumn} got ${mappedPosition.column}` + ); + assert.equal( + mappedPosition.source, + action.originalSource, + `original source didn't match, expected ${action.originalSource} got ${mappedPosition.source}` + ); }); } for (const testCase of sourceMapSpecTests.tests) { - if (skippedTests.includes(testCase.name)) + if (skippedTests.includes(testCase.name)) { continue; + } exports[`test from source map spec tests, name: ${testCase.name}`] = async function (assert) { - const json = await readJSON(`./source-map-tests/resources/${testCase.sourceMapFile}`); + const json = await readJSON( + `./source-map-tests/resources/${testCase.sourceMapFile}` + ); try { const map = await new SourceMapConsumer(json); map.eachMapping(() => {}); map.destroy(); } catch (exn) { - if (testCase.sourceMapIsValid) - assert.fail("Expected valid source map but failed to load successfully: " + exn.message); + if (testCase.sourceMapIsValid) { + assert.fail( + "Expected valid source map but failed to load successfully: " + + exn.message + ); + } return; } - if (!testCase.sourceMapIsValid) + if (!testCase.sourceMapIsValid) { assert.fail("Expected invalid source map but loaded successfully"); + } if (testCase.testActions) { for (const testAction of testCase.testActions) { if (testAction.actionType == "checkMapping") { @@ -146,4 +205,4 @@ for (const testCase of sourceMapSpecTests.tests) { } } }; -}; +} From aaf91da45a3dd3837421c9ce2dc1ff92a3d463f9 Mon Sep 17 00:00:00 2001 From: Hubert Boma Manilla Date: Sun, 9 Jun 2024 15:34:55 +0100 Subject: [PATCH 10/28] Update test/test-spec-tests.js Fix the require of the fs promises module --- test/test-spec-tests.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test-spec-tests.js b/test/test-spec-tests.js index fbe29117..8f113160 100644 --- a/test/test-spec-tests.js +++ b/test/test-spec-tests.js @@ -5,7 +5,7 @@ * http://opensource.org/licenses/BSD-3-Clause */ -const fs = require("node:fs/promises"); +const fs = require("fs").promises; const SourceMapConsumer = require("../lib/source-map-consumer").SourceMapConsumer; From b95ecf0e11b350448c69c490bb88f7e21c5b2e3c Mon Sep 17 00:00:00 2001 From: Nicolas Chevobbe Date: Tue, 8 Jul 2025 12:13:37 +0200 Subject: [PATCH 11/28] Remove whatwg-url module The native URL constructor does handle custom schemes just fine now, we don't need to have this module anymore. Fixes #400. --- lib/url-browser.js | 21 ---------------- package-lock.json | 63 +++------------------------------------------- package.json | 2 -- 3 files changed, 3 insertions(+), 83 deletions(-) delete mode 100644 lib/url-browser.js diff --git a/lib/url-browser.js b/lib/url-browser.js deleted file mode 100644 index c9da02a8..00000000 --- a/lib/url-browser.js +++ /dev/null @@ -1,21 +0,0 @@ -/* -*- Mode: js; js-indent-level: 2; -*- */ -/* - * Copyright 2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE or: - * http://opensource.org/licenses/BSD-3-Clause - */ -"use strict"; - -/** - * Browser 'URL' implementations have been found to handle non-standard URL - * schemes poorly, and schemes like - * - * webpack:///src/folder/file.js - * - * are very common in source maps. For the time being we use a JS - * implementation in these contexts instead. See - * - * * https://bugzilla.mozilla.org/show_bug.cgi?id=1374505 - * * https://bugs.chromium.org/p/chromium/issues/detail?id=734880 - */ -module.exports = require("whatwg-url").URL; diff --git a/package-lock.json b/package-lock.json index cab5273b..6dd43d16 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,9 +8,6 @@ "name": "source-map", "version": "0.8.0-beta.0", "license": "BSD-3-Clause", - "dependencies": { - "whatwg-url": "^7.0.0" - }, "devDependencies": { "c8": "^7.12.0", "doctoc": "^2.2.1", @@ -1264,11 +1261,6 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "node_modules/lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" - }, "node_modules/longest-streak": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", @@ -1766,6 +1758,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, "engines": { "node": ">=6" } @@ -2044,14 +2037,6 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "node_modules/tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", - "dependencies": { - "punycode": "^2.1.0" - } - }, "node_modules/traverse": { "version": "0.6.7", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz", @@ -2215,21 +2200,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" - }, - "node_modules/whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", - "dependencies": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -3259,11 +3229,6 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" - }, "longest-streak": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", @@ -3611,7 +3576,8 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true }, "queue-microtask": { "version": "1.2.3", @@ -3793,14 +3759,6 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", - "requires": { - "punycode": "^2.1.0" - } - }, "traverse": { "version": "0.6.7", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz", @@ -3921,21 +3879,6 @@ "unist-util-stringify-position": "^2.0.0" } }, - "webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" - }, - "whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", - "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index ae0e6552..3cb93281 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,6 @@ "main": "./source-map.js", "types": "./source-map.d.ts", "browser": { - "./lib/url.js": "./lib/url-browser.js", "./lib/read-wasm.js": "./lib/read-wasm-browser.js" }, "files": [ @@ -80,6 +79,5 @@ "prettier": "^2.7.1" }, "dependencies": { - "whatwg-url": "^7.0.0" } } From c9154ab60159ec8c8d94172b54debe1063f3ce90 Mon Sep 17 00:00:00 2001 From: Nicolas Chevobbe Date: Tue, 8 Jul 2025 12:33:11 +0200 Subject: [PATCH 12/28] run prettier --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index 3cb93281..874eb305 100644 --- a/package.json +++ b/package.json @@ -78,6 +78,5 @@ "eslint-config-prettier": "^8.5.0", "prettier": "^2.7.1" }, - "dependencies": { - } + "dependencies": {} } From 4b733667b0e231f41741b2d780c30fe89a1c4aa4 Mon Sep 17 00:00:00 2001 From: Nicolas Chevobbe Date: Thu, 24 Jul 2025 06:46:20 +0200 Subject: [PATCH 13/28] Bump package version to 0.7.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 874eb305..ed034578 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "source-map", "description": "Generates and consumes source maps", - "version": "0.8.0-beta.0", + "version": "0.7.5", "homepage": "https://github.com/mozilla/source-map", "author": "Nick Fitzgerald ", "contributors": [ From 330e4e08fb9309beed6086e3dc653fcb58bb1201 Mon Sep 17 00:00:00 2001 From: Nicolas Chevobbe Date: Thu, 24 Jul 2025 07:10:25 +0200 Subject: [PATCH 14/28] Bump package to 0.7.6 and remove publishConfig --- package.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/package.json b/package.json index ed034578..06d4f1a3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "source-map", "description": "Generates and consumes source maps", - "version": "0.7.5", + "version": "0.7.6", "homepage": "https://github.com/mozilla/source-map", "author": "Nick Fitzgerald ", "contributors": [ @@ -56,9 +56,6 @@ "source-map.d.ts", "lib/" ], - "publishConfig": { - "tag": "next" - }, "engines": { "node": ">= 12" }, From 641e3b4db7f6ead74b2979754b8869f73d9327c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Nison?= Date: Wed, 13 Aug 2025 21:40:17 +0100 Subject: [PATCH 15/28] Update source-map.d.ts --- source-map.d.ts | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/source-map.d.ts b/source-map.d.ts index 8bd5b6a1..45646052 100644 --- a/source-map.d.ts +++ b/source-map.d.ts @@ -84,18 +84,6 @@ export interface SourceMappings { } export interface SourceMapConsumer { - /** - * When using SourceMapConsumer outside of node.js, for example on the Web, it - * needs to know from what URL to load lib/mappings.wasm. You must inform it - * by calling initialize before constructing any SourceMapConsumers. - * - * @param mappings an object with the following property: - * - "lib/mappings.wasm": A String containing the URL of the - * lib/mappings.wasm file, or an ArrayBuffer with the contents of - * lib/mappings.wasm. - */ - initialize(mappings: SourceMappings): void; - /** * Compute the last column for each generated mapping. The last column is * inclusive. @@ -237,6 +225,18 @@ export interface SourceMapConsumerConstructor { sourceMapUrl?: SourceMapUrl ): Promise; + /** + * When using SourceMapConsumer outside of node.js, for example on the Web, it + * needs to know from what URL to load lib/mappings.wasm. You must inform it + * by calling initialize before constructing any SourceMapConsumers. + * + * @param mappings an object with the following property: + * - "lib/mappings.wasm": A String containing the URL of the + * lib/mappings.wasm file, or an ArrayBuffer with the contents of + * lib/mappings.wasm. + */ + initialize(mappings: SourceMappings): void; + /** * Create a BasicSourceMapConsumer from a SourceMapGenerator. * From 28012156fce032d02c4b2c3d4b696164a379b221 Mon Sep 17 00:00:00 2001 From: Nicolas Chevobbe Date: Wed, 30 Jul 2025 16:01:09 +0200 Subject: [PATCH 16/28] Update CHANGELOG.md Add information for 0.7.4 , 0.7.5 and 0.7.6 --- CHANGELOG.md | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 35f97a9e..56b01dc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,96 @@ # Change Log -## 0.8.0-beta.0 +## 0.7.6 + +- Bump package to 0.7.6 and remove `publishConfig` property in package.json ([801be934007c3ed0ef66c620641b1668e92c891d](https://github.com/mozilla/source-map/commit/801be934007c3ed0ef66c620641b1668e92c891d)) + +## 0.7.5 + +- [#364](https://github.com/mozilla/source-map/pull/364) - + Pass through the implementation of more index map operations. +- [#362](https://github.com/mozilla/source-map/pull/362) - + Remove the bundled dist/ directory? +- [#363](https://github.com/mozilla/source-map/pull/363) - + Split up wasm loading based on compilation target. +- [#371](https://github.com/mozilla/source-map/pull/371) - + Use WHATWG's URL to implement all of source-map's URL operations. +- [#378](https://github.com/mozilla/source-map/pull/378) - + Fix typo +- [#384](https://github.com/mozilla/source-map/pull/384) - + Add Mozilla Code of Conduct in +- [#402](https://github.com/mozilla/source-map/pull/402) - + Remove unused fromVLQSigned function +- [#374](https://github.com/mozilla/source-map/pull/374) - + Add lastGeneratedColumn to typing for MappingItem +- [#395](https://github.com/mozilla/source-map/pull/395) - + `addMapping()`: ensure that `originalLine` and `originalColumn` are `null` when `original` argument was undefined/`null` +- [#394](https://github.com/mozilla/source-map/pull/394) - + fix crash in url util function due to undefined root value +- [#393](https://github.com/mozilla/source-map/pull/393) - + minor binary-search code/comment fixes +- [#407](https://github.com/mozilla/source-map/pull/407) - + use Travis CI svg badge +- [#397](https://github.com/mozilla/source-map/pull/397) - + add `prettier` task for standardized code formatting => easier cross-branch/fork code comparison and merging +- [#415](https://github.com/mozilla/source-map/pull/415) - + Syntax highlight README HTML sample +- [#439](https://github.com/mozilla/source-map/pull/439) - + Add function to SourceMapConsumer TS interface +- [#448](https://github.com/mozilla/source-map/pull/448) - + Include types file extension in package.json +- [#464](https://github.com/mozilla/source-map/pull/464) - + Require Node.js 12 or later & switch CI to GitHub Actions +- [#466](https://github.com/mozilla/source-map/pull/466) - + Skip updating coveralls.io coverage +- [#465](https://github.com/mozilla/source-map/pull/465) - + Update WASM binary and Land WASM rust sources in this repository +- [#463](https://github.com/mozilla/source-map/pull/463) - + Update ESLint & Prettier to latest +- [#467](https://github.com/mozilla/source-map/pull/467) - + Adopt & enforce the mozilla-central Prettier config +- [#468](https://github.com/mozilla/source-map/pull/468) - + Simplify coverage tooling +- [#469](https://github.com/mozilla/source-map/pull/469) - + Update to doctoc v2 & simplify call pattern +- [#470](https://github.com/mozilla/source-map/pull/470) - + Filter out unnecessary rust tasks +- [#471](https://github.com/mozilla/source-map/pull/471) - + Improve coverage +- [#472](https://github.com/mozilla/source-map/pull/472) - + Include package-lock.json in repo +- [#473](https://github.com/mozilla/source-map/pull/473) - + fix: convert result of allocate_mappings from signed to unsigned +- [#481](https://github.com/mozilla/source-map/pull/481) - + Add support for the sourcemaps ignorelist +- [#485](https://github.com/mozilla/source-map/pull/485) - + Remove .DS_Store +- [#488](https://github.com/mozilla/source-map/pull/488) - + Fix reference to LICENSE file +- [#507](https://github.com/mozilla/source-map/pull/507) - + Fix an off-by-1 error in section lookup +- [#505](https://github.com/mozilla/source-map/pull/505) - + Add source map spec tests +- [#517](https://github.com/mozilla/source-map/pull/517) - + Remove whatwg-url module + +## 0.7.4 + +- [#341](https://github.com/mozilla/source-map/pull/341) - + Make async change. Fixes mozilla#337. +- [#339](https://github.com/mozilla/source-map/pull/339) - + Add option to initialize mappings wasm via ArrayBuffer +- [#347](https://github.com/mozilla/source-map/pull/347) - + Add expected arguments to assert.throws calls +- [#352](https://github.com/mozilla/source-map/pull/352) - + Update node version +- [#350](https://github.com/mozilla/source-map/pull/350) - + Use top level context to determine node vs browser environment +- [#361](https://github.com/mozilla/source-map/pull/361) - + Bump webpack-cli to v3.1 +- [#456](https://github.com/mozilla/source-map/pull/456) - + Regenerate dist due to running `npm test` + +## [DEPRECATED] 0.8.0-beta.0 ### Breaking changes From 833d6764f14bbc5a838645f45d258e0134738f93 Mon Sep 17 00:00:00 2001 From: Nicolas Chevobbe Date: Wed, 30 Jul 2025 16:27:54 +0200 Subject: [PATCH 17/28] prettier --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56b01dc7..4ea0eafa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,7 @@ - [#378](https://github.com/mozilla/source-map/pull/378) - Fix typo - [#384](https://github.com/mozilla/source-map/pull/384) - - Add Mozilla Code of Conduct in + Add Mozilla Code of Conduct in - [#402](https://github.com/mozilla/source-map/pull/402) - Remove unused fromVLQSigned function - [#374](https://github.com/mozilla/source-map/pull/374) - From 7368a7a7e7451d84bd665a0db4b0d729c6ea73ba Mon Sep 17 00:00:00 2001 From: Shay Molcho <152275799+shaymolcho@users.noreply.github.com> Date: Fri, 24 Apr 2026 13:04:53 +0300 Subject: [PATCH 18/28] Added missing periods for consistency and correctness (#514) Added missing periods in various parts of the text to ensure consistency and correctness in writing style. This revision maintains uniform formatting throughout the document, improves readability, and aligns the punctuation with the rest of the content for a more polished and structured appearance. --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 72402e35..3e78caf0 100644 --- a/README.md +++ b/README.md @@ -492,7 +492,7 @@ Iterate over each mapping between an original source/line/column and a generated line/column in this source map. - `callback`: The function that is called with each mapping. Mappings have the - form `{ source, generatedLine, generatedColumn, originalLine, originalColumn, name }` + form `{ source, generatedLine, generatedColumn, originalLine, originalColumn, name }`. - `context`: Optional. If specified, this object will be the value of `this` every time that `callback` is called. @@ -665,9 +665,9 @@ var node = new SourceNode(1, 2, "a.cpp", [ Creates a SourceNode from generated code and a SourceMapConsumer. -- `code`: The generated code +- `code`: The generated code. -- `sourceMapConsumer` The SourceMap for the generated code +- `sourceMapConsumer` The SourceMap for the generated code. - `relativePath` The optional path that relative sources in `sourceMapConsumer` should be relative to. @@ -711,9 +711,9 @@ node.prepend("/** Build Id: f783haef86324gf **/\n\n"); Set the source content for a source file. This will be added to the `SourceMap` in the `sourcesContent` field. -- `sourceFile`: The filename of the source file +- `sourceFile`: The filename of the source file. -- `sourceContent`: The content of the source file +- `sourceContent`: The content of the source file. ```js node.setSourceContent( From 27ec6f61653f769ae7b6d74640c0cbd209605f8b Mon Sep 17 00:00:00 2001 From: Hubert Boma Manilla Date: Mon, 27 Apr 2026 09:55:21 +0100 Subject: [PATCH 19/28] Use Object.create for sourceContents (#525) --- lib/source-node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/source-node.js b/lib/source-node.js index ecee1ae6..4d7cd3ed 100644 --- a/lib/source-node.js +++ b/lib/source-node.js @@ -35,7 +35,7 @@ const isSourceNode = "$$$isSourceNode$$$"; class SourceNode { constructor(aLine, aColumn, aSource, aChunks, aName) { this.children = []; - this.sourceContents = {}; + this.sourceContents = Object.create(null); this.line = aLine == null ? null : aLine; this.column = aColumn == null ? null : aColumn; this.source = aSource == null ? null : aSource; From 997ec082d6820ddbc436b67fc89a673480f4901a Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Fri, 29 May 2026 14:46:41 +0100 Subject: [PATCH 20/28] Adding security policy --- SECURITY.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index 14b14fab..6899b0d6 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,23 +1,28 @@ # Sourcemap Security Policy -Mozilla takes the security of our software seriously. If you believe you have found a security + +Mozilla takes the security of our software seriously. If you believe you have found a security vulnerability in the [source-map](https://github.com/mozilla/source-map) library, please report it to us as described below. ## Report a security bug! + Please report source-map security vulnerabilities at [bugzilla.mozilla.org](https://bugzilla.mozilla.org/enter_bug.cgi?format=__default__&product=DevTools&short_desc=[source-map%20security]) and make sure that the checkbox in the "Security" section is checked so the required access controls are automatically configured: ![Security section in Bugzilla](bugzilla-security-section.png) ## Bounty program? -There is not a bug bounty program for this library ([source-map](https://github.com/mozilla/source-map)) as a whole, but security -vulnerabilities may be eligible for a bug bounty if they can be exploited as used by Firefox. + +There is not a bug bounty program for this library ([source-map](https://github.com/mozilla/source-map)) as a whole, but security +vulnerabilities may be eligible for a bug bounty if they can be exploited as used by Firefox. Please see the [Firefox bug bounty program](https://www.mozilla.org/en-US/security/client-bug-bounty/) for more details and how to submit bugs to that program. ## I have a question! Who can help? + Questions regarding security bugs or our bounty programs can be directed to security@mozilla.com. An encryption key for sending [GPG encrypted mails](https://www.mozilla.org/en-US/security/#pgpkey) is also available. ## Where can I find security advisories? + We publish security advisories for all released versions of the library as part of the release notes. -General information about security at Mozilla is available at [https://www.mozilla.org/en-US/security/](https://www.mozilla.org/en-US/security/). \ No newline at end of file +General information about security at Mozilla is available at [https://www.mozilla.org/en-US/security/](https://www.mozilla.org/en-US/security/). From b4fa0ca2847de55b14a81ad6bb7d6d65503f470b Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Fri, 29 May 2026 14:46:41 +0100 Subject: [PATCH 21/28] Adding security policy --- lib/source-map-consumer.js | 5 +---- lib/source-node.js | 6 +++--- lib/url-browser.js | 21 +++++++++++++++++++++ 3 files changed, 25 insertions(+), 7 deletions(-) create mode 100644 lib/url-browser.js diff --git a/lib/source-map-consumer.js b/lib/source-map-consumer.js index 7381a668..be1289d9 100644 --- a/lib/source-map-consumer.js +++ b/lib/source-map-consumer.js @@ -842,11 +842,8 @@ 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 - 1) + aNeedle.generatedColumn - section.generatedOffset.generatedColumn ); } ); diff --git a/lib/source-node.js b/lib/source-node.js index 4d7cd3ed..eaee1bd2 100644 --- a/lib/source-node.js +++ b/lib/source-node.js @@ -35,7 +35,7 @@ const isSourceNode = "$$$isSourceNode$$$"; class SourceNode { constructor(aLine, aColumn, aSource, aChunks, aName) { this.children = []; - this.sourceContents = Object.create(null); + this.sourceContents = {}; this.line = aLine == null ? null : aLine; this.column = aColumn == null ? null : aColumn; this.source = aSource == null ? null : aSource; @@ -197,7 +197,7 @@ class SourceNode { } else { throw new TypeError( "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + - aChunk + aChunk ); } return this; @@ -219,7 +219,7 @@ class SourceNode { } else { throw new TypeError( "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + - aChunk + aChunk ); } return this; diff --git a/lib/url-browser.js b/lib/url-browser.js new file mode 100644 index 00000000..97b22f20 --- /dev/null +++ b/lib/url-browser.js @@ -0,0 +1,21 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ +"use strict"; + +/** + * Browser 'URL' implementations have been found to handle non-standard URL + * schemes poorly, and schemes like + * + * webpack:///src/folder/file.js + * + * are very common in source maps. For the time being we use a JS + * implementation in these contexts instead. See + * + * * https://bugzilla.mozilla.org/show_bug.cgi?id=1374505 + * * https://bugs.chromium.org/p/chromium/issues/detail?id=734880 + */ +module.exports = require("whatwg-url").URL; \ No newline at end of file From 42b8261da36596d13d46c1afc2fe35877eb620cf Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Fri, 29 May 2026 14:46:41 +0100 Subject: [PATCH 22/28] Adding security policy --- .gitmodules | 3 - CHANGELOG.md | 92 -------------- README.md | 10 +- lib/url-browser.js | 6 +- package-lock.json | 65 +++++++++- package.json | 16 ++- source-map.d.ts | 24 ++-- test/test-source-map-consumer.js | 19 +-- test/test-spec-tests.js | 208 ------------------------------- test/util.js | 105 ++++++---------- 10 files changed, 139 insertions(+), 409 deletions(-) delete mode 100644 .gitmodules delete mode 100644 test/test-spec-tests.js diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 163c0757..00000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "test/source-map-tests"] - path = test/source-map-tests - url = https://github.com/tc39/source-map-tests.git diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ea0eafa..cd000774 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,97 +1,5 @@ # Change Log -## 0.7.6 - -- Bump package to 0.7.6 and remove `publishConfig` property in package.json ([801be934007c3ed0ef66c620641b1668e92c891d](https://github.com/mozilla/source-map/commit/801be934007c3ed0ef66c620641b1668e92c891d)) - -## 0.7.5 - -- [#364](https://github.com/mozilla/source-map/pull/364) - - Pass through the implementation of more index map operations. -- [#362](https://github.com/mozilla/source-map/pull/362) - - Remove the bundled dist/ directory? -- [#363](https://github.com/mozilla/source-map/pull/363) - - Split up wasm loading based on compilation target. -- [#371](https://github.com/mozilla/source-map/pull/371) - - Use WHATWG's URL to implement all of source-map's URL operations. -- [#378](https://github.com/mozilla/source-map/pull/378) - - Fix typo -- [#384](https://github.com/mozilla/source-map/pull/384) - - Add Mozilla Code of Conduct in -- [#402](https://github.com/mozilla/source-map/pull/402) - - Remove unused fromVLQSigned function -- [#374](https://github.com/mozilla/source-map/pull/374) - - Add lastGeneratedColumn to typing for MappingItem -- [#395](https://github.com/mozilla/source-map/pull/395) - - `addMapping()`: ensure that `originalLine` and `originalColumn` are `null` when `original` argument was undefined/`null` -- [#394](https://github.com/mozilla/source-map/pull/394) - - fix crash in url util function due to undefined root value -- [#393](https://github.com/mozilla/source-map/pull/393) - - minor binary-search code/comment fixes -- [#407](https://github.com/mozilla/source-map/pull/407) - - use Travis CI svg badge -- [#397](https://github.com/mozilla/source-map/pull/397) - - add `prettier` task for standardized code formatting => easier cross-branch/fork code comparison and merging -- [#415](https://github.com/mozilla/source-map/pull/415) - - Syntax highlight README HTML sample -- [#439](https://github.com/mozilla/source-map/pull/439) - - Add function to SourceMapConsumer TS interface -- [#448](https://github.com/mozilla/source-map/pull/448) - - Include types file extension in package.json -- [#464](https://github.com/mozilla/source-map/pull/464) - - Require Node.js 12 or later & switch CI to GitHub Actions -- [#466](https://github.com/mozilla/source-map/pull/466) - - Skip updating coveralls.io coverage -- [#465](https://github.com/mozilla/source-map/pull/465) - - Update WASM binary and Land WASM rust sources in this repository -- [#463](https://github.com/mozilla/source-map/pull/463) - - Update ESLint & Prettier to latest -- [#467](https://github.com/mozilla/source-map/pull/467) - - Adopt & enforce the mozilla-central Prettier config -- [#468](https://github.com/mozilla/source-map/pull/468) - - Simplify coverage tooling -- [#469](https://github.com/mozilla/source-map/pull/469) - - Update to doctoc v2 & simplify call pattern -- [#470](https://github.com/mozilla/source-map/pull/470) - - Filter out unnecessary rust tasks -- [#471](https://github.com/mozilla/source-map/pull/471) - - Improve coverage -- [#472](https://github.com/mozilla/source-map/pull/472) - - Include package-lock.json in repo -- [#473](https://github.com/mozilla/source-map/pull/473) - - fix: convert result of allocate_mappings from signed to unsigned -- [#481](https://github.com/mozilla/source-map/pull/481) - - Add support for the sourcemaps ignorelist -- [#485](https://github.com/mozilla/source-map/pull/485) - - Remove .DS_Store -- [#488](https://github.com/mozilla/source-map/pull/488) - - Fix reference to LICENSE file -- [#507](https://github.com/mozilla/source-map/pull/507) - - Fix an off-by-1 error in section lookup -- [#505](https://github.com/mozilla/source-map/pull/505) - - Add source map spec tests -- [#517](https://github.com/mozilla/source-map/pull/517) - - Remove whatwg-url module - -## 0.7.4 - -- [#341](https://github.com/mozilla/source-map/pull/341) - - Make async change. Fixes mozilla#337. -- [#339](https://github.com/mozilla/source-map/pull/339) - - Add option to initialize mappings wasm via ArrayBuffer -- [#347](https://github.com/mozilla/source-map/pull/347) - - Add expected arguments to assert.throws calls -- [#352](https://github.com/mozilla/source-map/pull/352) - - Update node version -- [#350](https://github.com/mozilla/source-map/pull/350) - - Use top level context to determine node vs browser environment -- [#361](https://github.com/mozilla/source-map/pull/361) - - Bump webpack-cli to v3.1 -- [#456](https://github.com/mozilla/source-map/pull/456) - - Regenerate dist due to running `npm test` - -## [DEPRECATED] 0.8.0-beta.0 - ### Breaking changes - [#350](https://github.com/mozilla/source-map/pull/350) - diff --git a/README.md b/README.md index 3e78caf0..72402e35 100644 --- a/README.md +++ b/README.md @@ -492,7 +492,7 @@ Iterate over each mapping between an original source/line/column and a generated line/column in this source map. - `callback`: The function that is called with each mapping. Mappings have the - form `{ source, generatedLine, generatedColumn, originalLine, originalColumn, name }`. + form `{ source, generatedLine, generatedColumn, originalLine, originalColumn, name }` - `context`: Optional. If specified, this object will be the value of `this` every time that `callback` is called. @@ -665,9 +665,9 @@ var node = new SourceNode(1, 2, "a.cpp", [ Creates a SourceNode from generated code and a SourceMapConsumer. -- `code`: The generated code. +- `code`: The generated code -- `sourceMapConsumer` The SourceMap for the generated code. +- `sourceMapConsumer` The SourceMap for the generated code - `relativePath` The optional path that relative sources in `sourceMapConsumer` should be relative to. @@ -711,9 +711,9 @@ node.prepend("/** Build Id: f783haef86324gf **/\n\n"); Set the source content for a source file. This will be added to the `SourceMap` in the `sourcesContent` field. -- `sourceFile`: The filename of the source file. +- `sourceFile`: The filename of the source file -- `sourceContent`: The content of the source file. +- `sourceContent`: The content of the source file ```js node.setSourceContent( diff --git a/lib/url-browser.js b/lib/url-browser.js index 97b22f20..63d0c579 100644 --- a/lib/url-browser.js +++ b/lib/url-browser.js @@ -18,4 +18,8 @@ * * https://bugzilla.mozilla.org/show_bug.cgi?id=1374505 * * https://bugs.chromium.org/p/chromium/issues/detail?id=734880 */ -module.exports = require("whatwg-url").URL; \ No newline at end of file +<<<<<<< HEAD +module.exports = require("whatwg-url").URL; +======= +module.exports = require("whatwg-url").URL; +>>>>>>> e2197e6 (Adding security policy) diff --git a/package-lock.json b/package-lock.json index 6dd43d16..86b21ab5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,9 @@ "name": "source-map", "version": "0.8.0-beta.0", "license": "BSD-3-Clause", + "dependencies": { + "whatwg-url": "^7.0.0" + }, "devDependencies": { "c8": "^7.12.0", "doctoc": "^2.2.1", @@ -1261,6 +1264,11 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" + }, "node_modules/longest-streak": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", @@ -1758,7 +1766,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, "engines": { "node": ">=6" } @@ -2037,6 +2044,14 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/traverse": { "version": "0.6.7", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz", @@ -2200,6 +2215,21 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -3229,6 +3259,11 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" + }, "longest-streak": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", @@ -3576,8 +3611,7 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "queue-microtask": { "version": "1.2.3", @@ -3759,6 +3793,14 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "requires": { + "punycode": "^2.1.0" + } + }, "traverse": { "version": "0.6.7", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz", @@ -3879,6 +3921,21 @@ "unist-util-stringify-position": "^2.0.0" } }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -3951,4 +4008,4 @@ "dev": true } } -} +} \ No newline at end of file diff --git a/package.json b/package.json index 06d4f1a3..553538cc 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "source-map", "description": "Generates and consumes source maps", - "version": "0.7.6", + "version": "0.8.0-beta.0", "homepage": "https://github.com/mozilla/source-map", "author": "Nick Fitzgerald ", "contributors": [ @@ -49,6 +49,7 @@ "main": "./source-map.js", "types": "./source-map.d.ts", "browser": { + "./lib/url.js": "./lib/url-browser.js", "./lib/read-wasm.js": "./lib/read-wasm-browser.js" }, "files": [ @@ -56,13 +57,16 @@ "source-map.d.ts", "lib/" ], + "publishConfig": { + "tag": "next" + }, "engines": { "node": ">= 12" }, "license": "BSD-3-Clause", "scripts": { - "lint": "eslint --fix *.js lib/ test/ --ignore-pattern 'test/source-map-tests/**'", - "test": "git submodule update --init --recursive; node test/run-tests.js", + "lint": "eslint --fix *.js lib/ test/", + "test": "node test/run-tests.js", "coverage": "c8 --reporter=text --reporter=html npm test", "prettier": "prettier --write .", "clean": "rm -rf coverage", @@ -75,5 +79,7 @@ "eslint-config-prettier": "^8.5.0", "prettier": "^2.7.1" }, - "dependencies": {} -} + "dependencies": { + "whatwg-url": "^7.0.0" + } +} \ No newline at end of file diff --git a/source-map.d.ts b/source-map.d.ts index 45646052..94f45604 100644 --- a/source-map.d.ts +++ b/source-map.d.ts @@ -84,6 +84,18 @@ export interface SourceMappings { } export interface SourceMapConsumer { + /** + * When using SourceMapConsumer outside of node.js, for example on the Web, it + * needs to know from what URL to load lib/mappings.wasm. You must inform it + * by calling initialize before constructing any SourceMapConsumers. + * + * @param mappings an object with the following property: + * - "lib/mappings.wasm": A String containing the URL of the + * lib/mappings.wasm file, or an ArrayBuffer with the contents of + * lib/mappings.wasm. + */ + initialize(mappings: SourceMappings): void; + /** * Compute the last column for each generated mapping. The last column is * inclusive. @@ -225,18 +237,6 @@ export interface SourceMapConsumerConstructor { sourceMapUrl?: SourceMapUrl ): Promise; - /** - * When using SourceMapConsumer outside of node.js, for example on the Web, it - * needs to know from what URL to load lib/mappings.wasm. You must inform it - * by calling initialize before constructing any SourceMapConsumers. - * - * @param mappings an object with the following property: - * - "lib/mappings.wasm": A String containing the URL of the - * lib/mappings.wasm file, or an ArrayBuffer with the contents of - * lib/mappings.wasm. - */ - initialize(mappings: SourceMappings): void; - /** * Create a BasicSourceMapConsumer from a SourceMapGenerator. * diff --git a/test/test-source-map-consumer.js b/test/test-source-map-consumer.js index dc40ba28..d67494a0 100644 --- a/test/test-source-map-consumer.js +++ b/test/test-source-map-consumer.js @@ -709,7 +709,7 @@ exports["test eachMapping"] = async function (assert) { assert.ok( mapping.source === "/the/root/one.js" || - mapping.source === "/the/root/two.js" + mapping.source === "/the/root/two.js" ); if (mapping.generatedLine === previousLine) { @@ -738,8 +738,8 @@ exports["test eachMapping"] = async function (assert) { map.eachMapping(function (mapping) { assert.ok( mapping.source === null || - (typeof mapping.originalColumn === "number" && - typeof mapping.originalLine === "number") + (typeof mapping.originalColumn === "number" && + typeof mapping.originalLine === "number") ); }); map.destroy(); @@ -2146,7 +2146,7 @@ exports["test SourceMapConsumer.with"] = async function (assert) { assert.equal(c._mappingsPtr, 0); // Force the mappings to be parsed and assert that we allocated mappings. - c.eachMapping(_ => {}); + c.eachMapping(_ => { }); assert.ok(c._mappingsPtr != 0); return 6; @@ -2171,7 +2171,7 @@ exports["test SourceMapConsumer.with and exceptions"] = async function ( consumer = c; assert.equal(c._mappingsPtr, 0); - c.eachMapping(_ => {}); + c.eachMapping(_ => { }); assert.ok(c._mappingsPtr != 0); throw 6; @@ -2183,12 +2183,3 @@ 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/test-spec-tests.js b/test/test-spec-tests.js deleted file mode 100644 index 8f113160..00000000 --- a/test/test-spec-tests.js +++ /dev/null @@ -1,208 +0,0 @@ -/* -*- Mode: js; js-indent-level: 2; -*- */ -/* - * Copyright 2024 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE or: - * http://opensource.org/licenses/BSD-3-Clause - */ - -const fs = require("fs").promises; -const SourceMapConsumer = - require("../lib/source-map-consumer").SourceMapConsumer; - -const sourceMapSpecTests = require("./source-map-tests/source-map-spec-tests.json"); - -async function readJSON(path) { - const file = await fs.open(require.resolve(path)); - const json = JSON.parse(await file.readFile()); - file.close(); - return json; -} - -// Known failures due to intentional implementation choices or due to bugs. -const skippedTests = [ - // Versions are explicitly checked a bit loosely. - "versionNumericString", - // Stricter sources array checking isn't implemented. - "sourcesNotStringOrNull", - "sourcesAndSourcesContentBothNull", - // Stricter names array checking isn't implemented. - "namesMissing", - "namesNotString", - // This check isn't as strict in this library. - "invalidMappingNotAString1", - // A mapping segment with no fields is technically invalid in the spec. - "invalidMappingSegmentWithZeroFields", - // These tests fail due to imprecision in the spec about the 32-bit limit. - "invalidMappingSegmentWithColumnExceeding32Bits", - "invalidMappingSegmentWithOriginalLineExceeding32Bits", - "invalidMappingSegmentWithOriginalColumnExceeding32Bits", - // A large VLQ that should parse, but currently does not. - "validMappingLargeVLQ", - // The library currently doesn't check the types of offset lines/columns. - "indexMapOffsetLineWrongType", - "indexMapOffsetColumnWrongType", - // The spec is not totally clear about this case. - "indexMapInvalidBaseMappings", - // The spec's definition of overlap can be refined - "indexMapInvalidOverlap", - // The library doesn't support the new ignoreList feature yet. - "ignoreListWrongType1", - "ignoreListWrongType2", - "ignoreListWrongType3", - "ignoreListOutOfBounds", -]; - -// The source-map library converts null sources to the "null" URL in its -// sources list, so for equality checking we accept this as null. -function nullish(nullOrString) { - if (nullOrString === "null") { - return null; - } - return nullOrString; -} - -function mapLine(line) { - return line + 1; -} - -async function testMappingAction(assert, rawSourceMap, action) { - return SourceMapConsumer.with(rawSourceMap, null, consumer => { - let mappedPosition = consumer.originalPositionFor({ - line: mapLine(action.generatedLine), - column: action.generatedColumn, - }); - - assert.equal( - mappedPosition.line, - mapLine(action.originalLine), - `original line didn't match, expected ${mapLine( - action.originalLine - )} got ${mappedPosition.line}` - ); - assert.equal( - mappedPosition.column, - action.originalColumn, - `original column didn't match, expected ${action.originalColumn} got ${mappedPosition.column}` - ); - assert.equal( - nullish(mappedPosition.source), - action.originalSource, - `original source didn't match, expected ${action.originalSource} got ${mappedPosition.source}` - ); - if (action.mappedName) { - assert.equal( - mappedPosition.name, - action.mappedName, - `mapped name didn't match, expected ${action.mappedName} got ${mappedPosition.name}` - ); - } - - // When the source is null, a reverse lookup may not make sense - // because there isn't a unique way to look it up. - if (action.originalSource !== null) { - mappedPosition = consumer.generatedPositionFor({ - source: action.originalSource, - line: mapLine(action.originalLine), - column: action.originalColumn, - }); - - assert.equal( - mappedPosition.line, - mapLine(action.generatedLine), - `generated line didn't match, expected ${mapLine( - action.generatedLine - )} got ${mappedPosition.line}` - ); - assert.equal( - mappedPosition.column, - action.generatedColumn, - `generated column didn't match, expected ${action.generatedColumn} got ${mappedPosition.column}` - ); - } - }); -} - -async function testTransitiveMappingAction(assert, rawSourceMap, action) { - return SourceMapConsumer.with(rawSourceMap, null, async consumer => { - assert.ok( - Array.isArray(action.intermediateMaps), - "transitive mapping case requires intermediate maps" - ); - - let mappedPosition = consumer.originalPositionFor({ - line: mapLine(action.generatedLine), - column: action.generatedColumn, - }); - - for (const intermediateMapPath of action.intermediateMaps) { - const intermediateMap = await readJSON( - `./source-map-tests/resources/${intermediateMapPath}` - ); - await SourceMapConsumer.with( - intermediateMap, - null, - consumerIntermediate => { - mappedPosition = consumerIntermediate.originalPositionFor({ - line: mappedPosition.line, - column: mappedPosition.column, - }); - } - ); - } - - assert.equal( - mappedPosition.line, - mapLine(action.originalLine), - `original line didn't match, expected ${mapLine( - action.originalLine - )} got ${mappedPosition.line}` - ); - assert.equal( - mappedPosition.column, - action.originalColumn, - `original column didn't match, expected ${action.originalColumn} got ${mappedPosition.column}` - ); - assert.equal( - mappedPosition.source, - action.originalSource, - `original source didn't match, expected ${action.originalSource} got ${mappedPosition.source}` - ); - }); -} - -for (const testCase of sourceMapSpecTests.tests) { - if (skippedTests.includes(testCase.name)) { - continue; - } - exports[`test from source map spec tests, name: ${testCase.name}`] = - async function (assert) { - const json = await readJSON( - `./source-map-tests/resources/${testCase.sourceMapFile}` - ); - try { - const map = await new SourceMapConsumer(json); - map.eachMapping(() => {}); - map.destroy(); - } catch (exn) { - if (testCase.sourceMapIsValid) { - assert.fail( - "Expected valid source map but failed to load successfully: " + - exn.message - ); - } - return; - } - if (!testCase.sourceMapIsValid) { - assert.fail("Expected invalid source map but loaded successfully"); - } - if (testCase.testActions) { - for (const testAction of testCase.testActions) { - if (testAction.actionType == "checkMapping") { - await testMappingAction(assert, json, testAction); - } else if (testAction.actionType == "checkMappingTransitive") { - await testTransitiveMappingAction(assert, json, testAction); - } - } - } - }; -} diff --git a/test/util.js b/test/util.js index 665e70e2..7f471bca 100644 --- a/test/util.js +++ b/test/util.js @@ -226,31 +226,6 @@ 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", @@ -315,25 +290,25 @@ function assertMapping( origMapping.name, name, "Incorrect name, expected " + - JSON.stringify(name) + - ", got " + - JSON.stringify(origMapping.name) + JSON.stringify(name) + + ", got " + + JSON.stringify(origMapping.name) ); assert.equal( origMapping.line, originalLine, "Incorrect line, expected " + - JSON.stringify(originalLine) + - ", got " + - JSON.stringify(origMapping.line) + JSON.stringify(originalLine) + + ", got " + + JSON.stringify(origMapping.line) ); assert.equal( origMapping.column, originalColumn, "Incorrect column, expected " + - JSON.stringify(originalColumn) + - ", got " + - JSON.stringify(origMapping.column) + JSON.stringify(originalColumn) + + ", got " + + JSON.stringify(origMapping.column) ); let expectedSource; @@ -356,9 +331,9 @@ function assertMapping( origMapping.source, expectedSource, "Incorrect source, expected " + - JSON.stringify(expectedSource) + - ", got " + - JSON.stringify(origMapping.source) + JSON.stringify(expectedSource) + + ", got " + + JSON.stringify(origMapping.source) ); } @@ -373,17 +348,17 @@ function assertMapping( genMapping.line, generatedLine, "Incorrect line, expected " + - JSON.stringify(generatedLine) + - ", got " + - JSON.stringify(genMapping.line) + JSON.stringify(generatedLine) + + ", got " + + JSON.stringify(genMapping.line) ); assert.equal( genMapping.column, generatedColumn, "Incorrect column, expected " + - JSON.stringify(generatedColumn) + - ", got " + - JSON.stringify(genMapping.column) + JSON.stringify(generatedColumn) + + ", got " + + JSON.stringify(genMapping.column) ); } } @@ -396,57 +371,57 @@ function assertEqualMaps(assert, actualMap, expectedMap) { actualMap.names.length, expectedMap.names.length, "names length mismatch: " + - actualMap.names.join(", ") + - " != " + - expectedMap.names.join(", ") + actualMap.names.join(", ") + + " != " + + expectedMap.names.join(", ") ); for (let i = 0; i < actualMap.names.length; i++) { assert.equal( actualMap.names[i], expectedMap.names[i], "names[" + - i + - "] mismatch: " + - actualMap.names.join(", ") + - " != " + - expectedMap.names.join(", ") + i + + "] mismatch: " + + actualMap.names.join(", ") + + " != " + + expectedMap.names.join(", ") ); } assert.equal( actualMap.sources.length, expectedMap.sources.length, "sources length mismatch: " + - actualMap.sources.join(", ") + - " != " + - expectedMap.sources.join(", ") + actualMap.sources.join(", ") + + " != " + + expectedMap.sources.join(", ") ); for (let i = 0; i < actualMap.sources.length; i++) { assert.equal( actualMap.sources[i], expectedMap.sources[i], "sources[" + - i + - "] length mismatch: " + - actualMap.sources.join(", ") + - " != " + - expectedMap.sources.join(", ") + i + + "] length mismatch: " + + actualMap.sources.join(", ") + + " != " + + expectedMap.sources.join(", ") ); } assert.equal( actualMap.sourceRoot, expectedMap.sourceRoot, "sourceRoot mismatch: " + - actualMap.sourceRoot + - " != " + - expectedMap.sourceRoot + actualMap.sourceRoot + + " != " + + expectedMap.sourceRoot ); assert.equal( actualMap.mappings, expectedMap.mappings, "mappings mismatch:\nActual: " + - actualMap.mappings + - "\nExpected: " + - expectedMap.mappings + actualMap.mappings + + "\nExpected: " + + expectedMap.mappings ); if (actualMap.sourcesContent) { assert.equal( From fb669aa91f48ec3df511bd192e75993ed2d98f78 Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Fri, 29 May 2026 14:46:41 +0100 Subject: [PATCH 23/28] Adding security policy --- lib/url-browser.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/url-browser.js b/lib/url-browser.js index 63d0c579..80e942f3 100644 --- a/lib/url-browser.js +++ b/lib/url-browser.js @@ -18,8 +18,5 @@ * * https://bugzilla.mozilla.org/show_bug.cgi?id=1374505 * * https://bugs.chromium.org/p/chromium/issues/detail?id=734880 */ -<<<<<<< HEAD -module.exports = require("whatwg-url").URL; -======= + module.exports = require("whatwg-url").URL; ->>>>>>> e2197e6 (Adding security policy) From beacee1099ae5fc46703f3b17d375f7ecfbaf802 Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Fri, 29 May 2026 14:46:41 +0100 Subject: [PATCH 24/28] Adding security policy --- lib/source-node.js | 4 ++-- test/test-source-map-consumer.js | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/source-node.js b/lib/source-node.js index eaee1bd2..ecee1ae6 100644 --- a/lib/source-node.js +++ b/lib/source-node.js @@ -197,7 +197,7 @@ class SourceNode { } else { throw new TypeError( "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + - aChunk + aChunk ); } return this; @@ -219,7 +219,7 @@ class SourceNode { } else { throw new TypeError( "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + - aChunk + aChunk ); } return this; diff --git a/test/test-source-map-consumer.js b/test/test-source-map-consumer.js index d67494a0..1bc09b85 100644 --- a/test/test-source-map-consumer.js +++ b/test/test-source-map-consumer.js @@ -709,7 +709,7 @@ exports["test eachMapping"] = async function (assert) { assert.ok( mapping.source === "/the/root/one.js" || - mapping.source === "/the/root/two.js" + mapping.source === "/the/root/two.js" ); if (mapping.generatedLine === previousLine) { @@ -738,8 +738,8 @@ exports["test eachMapping"] = async function (assert) { map.eachMapping(function (mapping) { assert.ok( mapping.source === null || - (typeof mapping.originalColumn === "number" && - typeof mapping.originalLine === "number") + (typeof mapping.originalColumn === "number" && + typeof mapping.originalLine === "number") ); }); map.destroy(); @@ -2146,7 +2146,7 @@ exports["test SourceMapConsumer.with"] = async function (assert) { assert.equal(c._mappingsPtr, 0); // Force the mappings to be parsed and assert that we allocated mappings. - c.eachMapping(_ => { }); + c.eachMapping(_ => {}); assert.ok(c._mappingsPtr != 0); return 6; @@ -2171,7 +2171,7 @@ exports["test SourceMapConsumer.with and exceptions"] = async function ( consumer = c; assert.equal(c._mappingsPtr, 0); - c.eachMapping(_ => { }); + c.eachMapping(_ => {}); assert.ok(c._mappingsPtr != 0); throw 6; From 275feb9e7e31510f82b9721b5fcbda4a4de17862 Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Fri, 29 May 2026 14:46:41 +0100 Subject: [PATCH 25/28] Adding security policy --- CHANGELOG.md | 2 ++ package.json | 2 +- source-map.d.ts | 2 +- test/util.js | 80 ++++++++++++++++++++++++------------------------- 4 files changed, 44 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd000774..35f97a9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Change Log +## 0.8.0-beta.0 + ### Breaking changes - [#350](https://github.com/mozilla/source-map/pull/350) - diff --git a/package.json b/package.json index 553538cc..00077059 100644 --- a/package.json +++ b/package.json @@ -82,4 +82,4 @@ "dependencies": { "whatwg-url": "^7.0.0" } -} \ No newline at end of file +} diff --git a/source-map.d.ts b/source-map.d.ts index 94f45604..8bd5b6a1 100644 --- a/source-map.d.ts +++ b/source-map.d.ts @@ -95,7 +95,7 @@ export interface SourceMapConsumer { * lib/mappings.wasm. */ initialize(mappings: SourceMappings): void; - + /** * Compute the last column for each generated mapping. The last column is * inclusive. diff --git a/test/util.js b/test/util.js index 7f471bca..d99669c3 100644 --- a/test/util.js +++ b/test/util.js @@ -290,25 +290,25 @@ function assertMapping( origMapping.name, name, "Incorrect name, expected " + - JSON.stringify(name) + - ", got " + - JSON.stringify(origMapping.name) + JSON.stringify(name) + + ", got " + + JSON.stringify(origMapping.name) ); assert.equal( origMapping.line, originalLine, "Incorrect line, expected " + - JSON.stringify(originalLine) + - ", got " + - JSON.stringify(origMapping.line) + JSON.stringify(originalLine) + + ", got " + + JSON.stringify(origMapping.line) ); assert.equal( origMapping.column, originalColumn, "Incorrect column, expected " + - JSON.stringify(originalColumn) + - ", got " + - JSON.stringify(origMapping.column) + JSON.stringify(originalColumn) + + ", got " + + JSON.stringify(origMapping.column) ); let expectedSource; @@ -331,9 +331,9 @@ function assertMapping( origMapping.source, expectedSource, "Incorrect source, expected " + - JSON.stringify(expectedSource) + - ", got " + - JSON.stringify(origMapping.source) + JSON.stringify(expectedSource) + + ", got " + + JSON.stringify(origMapping.source) ); } @@ -348,17 +348,17 @@ function assertMapping( genMapping.line, generatedLine, "Incorrect line, expected " + - JSON.stringify(generatedLine) + - ", got " + - JSON.stringify(genMapping.line) + JSON.stringify(generatedLine) + + ", got " + + JSON.stringify(genMapping.line) ); assert.equal( genMapping.column, generatedColumn, "Incorrect column, expected " + - JSON.stringify(generatedColumn) + - ", got " + - JSON.stringify(genMapping.column) + JSON.stringify(generatedColumn) + + ", got " + + JSON.stringify(genMapping.column) ); } } @@ -371,57 +371,57 @@ function assertEqualMaps(assert, actualMap, expectedMap) { actualMap.names.length, expectedMap.names.length, "names length mismatch: " + - actualMap.names.join(", ") + - " != " + - expectedMap.names.join(", ") + actualMap.names.join(", ") + + " != " + + expectedMap.names.join(", ") ); for (let i = 0; i < actualMap.names.length; i++) { assert.equal( actualMap.names[i], expectedMap.names[i], "names[" + - i + - "] mismatch: " + - actualMap.names.join(", ") + - " != " + - expectedMap.names.join(", ") + i + + "] mismatch: " + + actualMap.names.join(", ") + + " != " + + expectedMap.names.join(", ") ); } assert.equal( actualMap.sources.length, expectedMap.sources.length, "sources length mismatch: " + - actualMap.sources.join(", ") + - " != " + - expectedMap.sources.join(", ") + actualMap.sources.join(", ") + + " != " + + expectedMap.sources.join(", ") ); for (let i = 0; i < actualMap.sources.length; i++) { assert.equal( actualMap.sources[i], expectedMap.sources[i], "sources[" + - i + - "] length mismatch: " + - actualMap.sources.join(", ") + - " != " + - expectedMap.sources.join(", ") + i + + "] length mismatch: " + + actualMap.sources.join(", ") + + " != " + + expectedMap.sources.join(", ") ); } assert.equal( actualMap.sourceRoot, expectedMap.sourceRoot, "sourceRoot mismatch: " + - actualMap.sourceRoot + - " != " + - expectedMap.sourceRoot + actualMap.sourceRoot + + " != " + + expectedMap.sourceRoot ); assert.equal( actualMap.mappings, expectedMap.mappings, "mappings mismatch:\nActual: " + - actualMap.mappings + - "\nExpected: " + - expectedMap.mappings + actualMap.mappings + + "\nExpected: " + + expectedMap.mappings ); if (actualMap.sourcesContent) { assert.equal( From 1924d34bb810fce1b8e04beb9766f32ae38dcba8 Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Fri, 29 May 2026 14:46:41 +0100 Subject: [PATCH 26/28] Adding security policy --- lib/url-browser.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/url-browser.js b/lib/url-browser.js index 80e942f3..c9da02a8 100644 --- a/lib/url-browser.js +++ b/lib/url-browser.js @@ -18,5 +18,4 @@ * * https://bugzilla.mozilla.org/show_bug.cgi?id=1374505 * * https://bugs.chromium.org/p/chromium/issues/detail?id=734880 */ - module.exports = require("whatwg-url").URL; From ae5fdba799861b13924c213873ee1fbc55fbc742 Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Fri, 29 May 2026 14:46:41 +0100 Subject: [PATCH 27/28] Adding security policy --- test/source-map-tests | 1 - 1 file changed, 1 deletion(-) delete mode 160000 test/source-map-tests diff --git a/test/source-map-tests b/test/source-map-tests deleted file mode 160000 index 14c89744..00000000 --- a/test/source-map-tests +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 14c897444208365fc586a9c00c623bfb1955d731 From 7c767436e327a2f305fe6e74d41018d2a11a4681 Mon Sep 17 00:00:00 2001 From: Hubert B Manilla Date: Fri, 29 May 2026 14:46:41 +0100 Subject: [PATCH 28/28] Adding security policy --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 86b21ab5..cab5273b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4008,4 +4008,4 @@ "dev": true } } -} \ No newline at end of file +}