Skip to content

Commit f6ed5b4

Browse files
committed
fix(proguard): handle jar module prefixes in retrace lookups
1 parent 3cf716b commit f6ed5b4

File tree

1 file changed

+37
-2
lines changed

1 file changed

+37
-2
lines changed

apps/backend/src/mappings/proguard.rs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ impl ProguardMapping {
148148
};
149149
let qualified = &rest[..paren_start];
150150
let location = &rest[paren_start..];
151+
let (class_prefix, qualified) = split_container_prefix(qualified);
151152

152153
// Split into class + method on last '.'
153154
let Some(dot_pos) = qualified.rfind('.') else {
@@ -180,7 +181,7 @@ impl ProguardMapping {
180181
None => format!("({source_file})"),
181182
};
182183

183-
format!("{prefix}at {original_class}.{method_name}{location_str}")
184+
format!("{prefix}at {class_prefix}{original_class}.{method_name}{location_str}")
184185
}
185186

186187
fn retrace_exception_line(&self, line: &str) -> String {
@@ -200,9 +201,13 @@ impl ProguardMapping {
200201
.split_once(": ")
201202
.map(|(c, m)| (c, format!(": {m}")))
202203
.unwrap_or((class_and_rest, String::new()));
204+
let (class_prefix, obf_class) = split_container_prefix(obf_class);
203205

204206
if let Some(class) = self.classes.get(obf_class) {
205-
format!("{prefix}{before_class}{}{suffix}", class.original_name)
207+
format!(
208+
"{prefix}{before_class}{class_prefix}{}{suffix}",
209+
class.original_name
210+
)
206211
} else {
207212
line.to_string()
208213
}
@@ -277,6 +282,14 @@ fn parse_class_line(line: &str) -> Option<(String, String)> {
277282
Some((original.trim().to_string(), obfuscated.trim().to_string()))
278283
}
279284

285+
fn split_container_prefix(qualified: &str) -> (&str, &str) {
286+
if let Some(slash_pos) = qualified.rfind('/') {
287+
(&qualified[..=slash_pos], &qualified[slash_pos + 1..])
288+
} else {
289+
("", qualified)
290+
}
291+
}
292+
280293
/// Parse member lines (methods and fields) and add to class mapping
281294
fn parse_member_line(line: &str, class: &mut ClassMapping) {
282295
// Try to parse as method with line numbers: "startLine:endLine:returnType method(params) -> obfuscated"
@@ -589,6 +602,28 @@ java.lang.RuntimeException: oops
589602
assert_eq!(output, "\tat core.file.FileIO.load(FileIO.java)");
590603
}
591604

605+
#[test]
606+
fn retrace_stacktrace_with_container_prefix() {
607+
let mapping = parse_test_mapping(SAMPLE_MAPPING);
608+
let input = "\tat tweaks-3.3.6-obfuscated.jar//a.a.a.c(SourceFile:92)";
609+
let output = mapping.retrace(input);
610+
assert_eq!(
611+
output,
612+
"\tat tweaks-3.3.6-obfuscated.jar//core.file.FileIO.reload(FileIO.java:92)"
613+
);
614+
}
615+
616+
#[test]
617+
fn retrace_caused_by_with_container_prefix() {
618+
let mapping = parse_test_mapping(SAMPLE_MAPPING);
619+
let input = "Caused by: tweaks-3.3.6-obfuscated.jar//a.a.a: some message";
620+
let output = mapping.retrace(input);
621+
assert_eq!(
622+
output,
623+
"Caused by: tweaks-3.3.6-obfuscated.jar//core.file.FileIO: some message"
624+
);
625+
}
626+
592627
#[test]
593628
fn parse_many_combines_split_mapping_files() {
594629
const PART_ONE: &str = r#"core.file.FileIO -> a.a.a:

0 commit comments

Comments
 (0)