diff --git a/Cargo.lock b/Cargo.lock index 7765341..23debbb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -334,7 +334,7 @@ dependencies = [ [[package]] name = "proguard" -version = "5.6.2" +version = "5.7.0" dependencies = [ "criterion", "serde", diff --git a/src/cache/mod.rs b/src/cache/mod.rs index b681761..16308e9 100644 --- a/src/cache/mod.rs +++ b/src/cache/mod.rs @@ -400,56 +400,32 @@ impl<'data> ProguardCache<'data> { }) } - /// Determines if a frame refers to an outline method, either via the - /// method-level flag or via any matching mapping entry for the frame line. - fn is_outline_frame( - &self, - class: &str, - method: &str, - line: usize, - parameters: Option<&str>, - ) -> bool { + /// Determines if a frame refers to an outline method via the method-level flag. + /// Outline metadata is consistent across all mapping entries for a method, so + /// we only need to inspect the method metadata instead of individual lines. + pub fn is_outline_frame(&self, class: &str, method: &str) -> bool { let Some(class) = self.get_class(class) else { return false; }; - let candidates: &[raw::Member] = if let Some(params) = parameters { - let Some(members) = self.get_class_members_by_params(class) else { - return false; - }; - let Some(range) = Self::find_range_by_binary_search(members, |m| { - let Ok(obfuscated_name) = self.read_string(m.obfuscated_name_offset) else { - return Ordering::Greater; - }; - let p = self.read_string(m.params_offset).unwrap_or_default(); - (obfuscated_name, p).cmp(&(method, params)) - }) else { - return false; - }; - range - } else { - let Some(members) = self.get_class_members(class) else { - return false; - }; - let Some(range) = Self::find_range_by_binary_search(members, |m| { - let Ok(obfuscated_name) = self.read_string(m.obfuscated_name_offset) else { - return Ordering::Greater; - }; - obfuscated_name.cmp(method) - }) else { - return false; + let Some(members) = self.get_class_members(class) else { + return false; + }; + + let Some(candidates) = Self::find_range_by_binary_search(members, |m| { + let Ok(obfuscated_name) = self.read_string(m.obfuscated_name_offset) else { + return Ordering::Greater; }; - range + obfuscated_name.cmp(method) + }) else { + return false; }; - candidates.iter().any(|m| { - m.is_outline() - && (m.endline == 0 || (line >= m.startline as usize && line <= m.endline as usize)) - }) + candidates.first().is_some_and(|member| member.is_outline()) } /// Applies any carried outline position to the frame line and returns the adjusted frame. - fn prepare_frame_for_mapping<'a>( + pub fn prepare_frame_for_mapping<'a>( &self, frame: &StackFrame<'a>, carried_outline_pos: &mut Option, @@ -483,12 +459,7 @@ impl<'data> ProguardCache<'data> { None => match stacktrace::parse_frame(line) { None => writeln!(&mut stacktrace, "{line}")?, Some(frame) => { - if self.is_outline_frame( - frame.class, - frame.method, - frame.line, - frame.parameters, - ) { + if self.is_outline_frame(frame.class, frame.method) { carried_outline_pos = Some(frame.line); } else { let effective_frame = @@ -520,12 +491,7 @@ impl<'data> ProguardCache<'data> { } }, Some(frame) => { - if self.is_outline_frame( - frame.class, - frame.method, - frame.line, - frame.parameters, - ) { + if self.is_outline_frame(frame.class, frame.method) { carried_outline_pos = Some(frame.line); continue; } @@ -549,7 +515,7 @@ impl<'data> ProguardCache<'data> { let mut carried_outline_pos: Option = None; let mut frames: Vec> = Vec::with_capacity(trace.frames.len()); for f in trace.frames.iter() { - if self.is_outline_frame(f.class, f.method, f.line, f.parameters) { + if self.is_outline_frame(f.class, f.method) { carried_outline_pos = Some(f.line); continue; } diff --git a/src/mapper.rs b/src/mapper.rs index 0e8643c..421ab7f 100644 --- a/src/mapper.rs +++ b/src/mapper.rs @@ -359,32 +359,15 @@ impl<'s> ProguardMapper<'s> { }) } - /// Determines if a frame refers to an outline method, either via the - /// method-level flag or via any matching mapping entry for the frame line. - fn is_outline_frame( - &self, - class: &str, - method: &str, - line: usize, - parameters: Option<&str>, - ) -> bool { + /// Determines if a frame refers to an outline method via the method-level flag. + /// Outline metadata is consistent across all mappings for a method, so checking + /// a single mapping entry is sufficient. + fn is_outline_frame(&self, class: &str, method: &str) -> bool { self.classes .get(class) .and_then(|c| c.members.get(method)) - .map(|ms| { - let mappings: &[_] = if let Some(params) = parameters { - match ms.mappings_by_params.get(params) { - Some(v) => &v[..], - None => &[], - } - } else { - &ms.all_mappings[..] - }; - mappings.iter().any(|m| { - m.is_outline && (m.endline == 0 || (line >= m.startline && line <= m.endline)) - }) - }) - .unwrap_or(false) + .and_then(|ms| ms.all_mappings.first()) + .is_some_and(|m| m.is_outline) } /// Applies any carried outline position to the frame line and returns the adjusted frame. @@ -520,12 +503,7 @@ impl<'s> ProguardMapper<'s> { None => match stacktrace::parse_frame(line) { None => writeln!(&mut stacktrace, "{line}")?, Some(frame) => { - if self.is_outline_frame( - frame.class, - frame.method, - frame.line, - frame.parameters, - ) { + if self.is_outline_frame(frame.class, frame.method) { carried_outline_pos = Some(frame.line); } else { let effective_frame = @@ -557,12 +535,7 @@ impl<'s> ProguardMapper<'s> { } }, Some(frame) => { - if self.is_outline_frame( - frame.class, - frame.method, - frame.line, - frame.parameters, - ) { + if self.is_outline_frame(frame.class, frame.method) { carried_outline_pos = Some(frame.line); continue; } @@ -587,7 +560,7 @@ impl<'s> ProguardMapper<'s> { let mut carried_outline_pos: Option = None; let mut frames_out = Vec::with_capacity(trace.frames.len()); for f in trace.frames.iter() { - if self.is_outline_frame(f.class, f.method, f.line, f.parameters) { + if self.is_outline_frame(f.class, f.method) { carried_outline_pos = Some(f.line); continue; }