Skip to content

Commit f8c46b3

Browse files
feat(sourcemaps): Support injecting indexed sourcemaps
Closes #2463 Closes #2466
1 parent b51e4f7 commit f8c46b3

File tree

9 files changed

+495
-27
lines changed

9 files changed

+495
-27
lines changed

Cargo.lock

Lines changed: 1 addition & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ openssl-probe = "0.1.5"
108108
[target."cfg(windows)".dependencies]
109109
windows-sys = { version = "0.59.0", features = ["Win32_Storage_FileSystem"] }
110110

111+
[patch.crates-io]
112+
sourcemap = { git = "https://github.com/getsentry/rust-sourcemap.git", rev = "e8dff4fbb74f346d0f13a2f547cedf4b5fb4e83f" }
113+
111114
# We optimize the release build for size.
112115
[profile.release]
113116
opt-level = 2 # I obtained the smallest binary size with opt-level 2 on my system.

src/utils/sourcemaps.rs

Lines changed: 104 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use indicatif::ProgressStyle;
1414
use log::{debug, info, warn};
1515
use sentry::types::DebugId;
1616
use sha1_smol::Digest;
17-
use sourcemap::SourceMap;
17+
use sourcemap::{DecodedMap, SourceMap};
1818
use symbolic::debuginfo::js::{
1919
discover_debug_id, discover_sourcemap_embedded_debug_id, discover_sourcemaps_location,
2020
};
@@ -947,20 +947,54 @@ impl SourceMapProcessor {
947947
bail!("Invalid embedded sourcemap in source file {source_url}");
948948
};
949949

950-
let mut sourcemap = SourceMap::from_slice(&decoded).with_context(|| {
951-
format!("Invalid embedded sourcemap in source file {source_url}")
952-
})?;
950+
let mut sourcemap =
951+
sourcemap::decode_slice(&decoded).with_context(|| {
952+
format!("Invalid embedded sourcemap in source file {source_url}")
953+
})?;
953954

954955
let debug_id = sourcemap
955-
.get_debug_id()
956+
.debug_id()
956957
.unwrap_or_else(|| inject::debug_id_from_bytes_hashed(&decoded));
957958

958959
let source_file = self.sources.get_mut(source_url).unwrap();
959-
let source_file_contents = Arc::make_mut(&mut source_file.contents);
960-
let adjustment_map = inject::fixup_js_file(source_file_contents, debug_id)
961-
.context(format!("Failed to process {}", source_file.path.display()))?;
962960

963-
sourcemap.adjust_mappings(&adjustment_map);
961+
match &mut sourcemap {
962+
DecodedMap::Regular(sourcemap) => {
963+
adjust_regular_sourcemap(sourcemap, source_file, debug_id)?;
964+
}
965+
DecodedMap::Hermes(sourcemap) => {
966+
adjust_regular_sourcemap(sourcemap, source_file, debug_id)?;
967+
}
968+
DecodedMap::Index(sourcemap) => {
969+
let source_file_contents = Arc::make_mut(&mut source_file.contents);
970+
if sourcemap.adjust_sections_offset_rows(1) {
971+
let injected = inject::inject_at_start(
972+
str::from_utf8(source_file_contents).with_context(
973+
|| {
974+
format!(
975+
"{} is not UTF-8",
976+
source_file.path.display()
977+
)
978+
},
979+
)?,
980+
debug_id,
981+
);
982+
983+
source_file_contents.clear();
984+
source_file_contents.extend(injected.as_bytes());
985+
} else {
986+
// We can't adjust the section offset rows, so we have to inject at the end
987+
inject::fixup_js_file_end(source_file_contents, debug_id)
988+
.with_context(|| {
989+
format!(
990+
"Failed to inject debug id into {}",
991+
source_file.path.display()
992+
)
993+
})?;
994+
}
995+
}
996+
}
997+
964998
sourcemap.set_debug_id(Some(debug_id));
965999

9661000
decoded.clear();
@@ -969,7 +1003,10 @@ impl SourceMapProcessor {
9691003
let encoded = data_encoding::BASE64.encode(&decoded);
9701004
let new_sourcemap_url = format!("{DATA_PREAMBLE}{encoded}");
9711005

972-
inject::replace_sourcemap_url(source_file_contents, &new_sourcemap_url)?;
1006+
inject::replace_sourcemap_url(
1007+
Arc::make_mut(&mut source_file.contents),
1008+
&new_sourcemap_url,
1009+
)?;
9731010
*sourcemap_url = Some(SourceMapReference::from_url(new_sourcemap_url));
9741011

9751012
debug_id
@@ -1000,11 +1037,12 @@ impl SourceMapProcessor {
10001037
let (mut sourcemap, debug_id, debug_id_fresh) = {
10011038
let sourcemap_file = &self.sources[&sourcemap_url];
10021039

1003-
let sm = SourceMap::from_slice(&sourcemap_file.contents).context(
1004-
format!("Invalid sourcemap at {}", sourcemap_file.url),
1005-
)?;
1040+
let sm =
1041+
sourcemap::decode_slice(&sourcemap_file.contents).context(
1042+
format!("Invalid sourcemap at {}", sourcemap_file.url),
1043+
)?;
10061044

1007-
match sm.get_debug_id() {
1045+
match sm.debug_id() {
10081046
Some(debug_id) => (sm, debug_id, false),
10091047
None => {
10101048
let debug_id = inject::debug_id_from_bytes_hashed(
@@ -1016,13 +1054,45 @@ impl SourceMapProcessor {
10161054
};
10171055

10181056
let source_file = self.sources.get_mut(source_url).unwrap();
1019-
let adjustment_map = inject::fixup_js_file(
1020-
Arc::make_mut(&mut source_file.contents),
1021-
debug_id,
1022-
)
1023-
.context(format!("Failed to process {}", source_file.path.display()))?;
10241057

1025-
sourcemap.adjust_mappings(&adjustment_map);
1058+
match &mut sourcemap {
1059+
DecodedMap::Regular(sourcemap) => {
1060+
adjust_regular_sourcemap(sourcemap, source_file, debug_id)?;
1061+
}
1062+
DecodedMap::Hermes(sourcemap) => {
1063+
adjust_regular_sourcemap(sourcemap, source_file, debug_id)?;
1064+
}
1065+
DecodedMap::Index(sourcemap) => {
1066+
let source_file_contents =
1067+
Arc::make_mut(&mut source_file.contents);
1068+
if sourcemap.adjust_sections_offset_rows(1) {
1069+
let injected = inject::inject_at_start(
1070+
str::from_utf8(source_file_contents).with_context(
1071+
|| {
1072+
format!(
1073+
"{} is not UTF-8",
1074+
source_file.path.display()
1075+
)
1076+
},
1077+
)?,
1078+
debug_id,
1079+
);
1080+
1081+
source_file_contents.clear();
1082+
source_file_contents.extend(injected.as_bytes());
1083+
} else {
1084+
// We can't adjust the section offset rows, so we have to inject at the end
1085+
inject::fixup_js_file_end(source_file_contents, debug_id)
1086+
.with_context(|| {
1087+
format!(
1088+
"Failed to inject debug id into {}",
1089+
source_file.path.display()
1090+
)
1091+
})?;
1092+
}
1093+
}
1094+
}
1095+
10261096
sourcemap.set_debug_id(Some(debug_id));
10271097

10281098
let sourcemap_file = self.sources.get_mut(&sourcemap_url).unwrap();
@@ -1103,6 +1173,20 @@ impl SourceMapProcessor {
11031173
}
11041174
}
11051175

1176+
fn adjust_regular_sourcemap(
1177+
sourcemap: &mut SourceMap,
1178+
source_file: &mut SourceFile,
1179+
debug_id: DebugId,
1180+
) -> Result<()> {
1181+
#[expect(deprecated)]
1182+
let adjustment_map = inject::fixup_js_file(Arc::make_mut(&mut source_file.contents), debug_id)
1183+
.context(format!("Failed to process {}", source_file.path.display()))?;
1184+
1185+
sourcemap.adjust_mappings(&adjustment_map);
1186+
1187+
Ok(())
1188+
}
1189+
11061190
fn validate_script(source: &mut SourceFile) -> Result<()> {
11071191
if let Some(sm_ref) = get_sourcemap_ref(source) {
11081192
if let sourcemap::SourceMapRef::LegacyRef(_) = sm_ref {

0 commit comments

Comments
 (0)