Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 12 additions & 17 deletions src/mapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,13 +161,7 @@ impl<'s> ProguardMapping<'s> {
/// let valid = ProguardMapping::new(b"a -> b:\n void method() -> b");
/// assert_eq!(valid.is_valid(), true);
///
/// let invalid = ProguardMapping::new(
/// br#"
/// # looks: like
/// a -> proguard:
/// mapping but(is) -> not
/// "#,
/// );
/// let invalid = ProguardMapping::new(b"a -> proguard:\n not a valid proguard member line");
/// assert_eq!(invalid.is_valid(), false);
/// ```
pub fn is_valid(&self) -> bool {
Expand Down Expand Up @@ -505,7 +499,7 @@ fn parse_proguard_record(bytes: &[u8]) -> (Result<ProguardRecord<'_>, ParseError
} else {
parse_proguard_header(bytes)
}
} else if bytes.starts_with(b" ") {
} else if matches!(bytes.first(), Some(b' ' | b'\t')) {
parse_proguard_field_or_method(bytes)
} else {
parse_proguard_class(bytes)
Expand Down Expand Up @@ -568,7 +562,7 @@ fn parse_proguard_field_or_method(
// field line or method line:
// `originalfieldtype originalfieldname -> obfuscatedfieldname`
// `[startline:endline:]originalreturntype [originalclassname.]originalmethodname(originalargumenttype,...)[:originalstartline[:originalendline]] -> obfuscatedmethodname`
let bytes = parse_prefix(bytes, b" ")?;
let bytes = bytes.trim_ascii_start();

let (startline, bytes) = match parse_usize(bytes) {
Ok((startline, bytes)) => (Some(startline), bytes),
Expand Down Expand Up @@ -1063,15 +1057,15 @@ mod tests {
}

#[test]
fn try_parse_field_insufficient_leading_spaces() {
// only 2 leading spaces instead of 4
fn try_parse_field_with_two_space_indentation() {
let bytes = b" android.app.Activity mActivity -> a";
let parsed = ProguardRecord::try_parse(bytes);
assert_eq!(
parsed,
Err(ParseError {
line: bytes,
kind: ParseErrorKind::ParseError("line is not a valid proguard record"),
Ok(ProguardRecord::Field {
ty: "android.app.Activity",
original: "mActivity",
obfuscated: "a",
}),
);
}
Expand Down Expand Up @@ -1145,9 +1139,10 @@ androidx.activity.OnBackPressedCallback
original: "mEnabled",
obfuscated: "a",
}),
Err(ParseError {
line: b" boolean mEnabled -> a\n",
kind: ParseErrorKind::ParseError("line is not a valid proguard record"),
Ok(ProguardRecord::Field {
ty: "boolean",
original: "mEnabled",
obfuscated: "a",
}),
Ok(ProguardRecord::Field {
ty: "java.util.ArrayDeque",
Expand Down
55 changes: 54 additions & 1 deletion tests/retrace.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use proguard::{ProguardMapper, StackFrame};
use proguard::{ProguardCache, ProguardMapper, ProguardMapping, StackFrame};

#[test]
fn test_remap() {
Expand Down Expand Up @@ -130,3 +130,56 @@ fn test_remap_just_method() {
let ambiguous = mapper.remap_method("a.b.c.d", "buttonClicked");
assert_eq!(ambiguous, None);
}

#[test]
fn test_remap_compose_stacktrace_group_keys() {
let mapping = r#"ComposeStackTrace -> $$compose:
1:1:androidx.compose.runtime.State androidx.compose.animation.core.AnimateAsStateKt.animateFloatAsState(float,androidx.compose.animation.core.AnimationSpec,float,java.lang.String,kotlin.jvm.functions.Function1,androidx.compose.runtime.Composer,int,int):71:71 -> m$1125598679
1:1:androidx.compose.runtime.State androidx.compose.animation.core.AnimateAsStateKt.animateFloatAsState(float,androidx.compose.animation.core.AnimationSpec,float,java.lang.String,kotlin.jvm.functions.Function1,androidx.compose.runtime.Composer,int,int):73:73 -> m$1125708605"#;
let mapper = ProguardMapper::from(mapping);

let mapped = mapper
.remap_stacktrace(
r#"androidx.compose.runtime.ComposeTraceException:
at $$compose.m$1125598679(SourceFile:1)
at $$compose.m$1125708605(SourceFile:1)"#,
)
.unwrap();

assert_eq!(
mapped.trim(),
r#"androidx.compose.runtime.ComposeTraceException:
at androidx.compose.animation.core.AnimateAsStateKt.animateFloatAsState(AnimateAsState.kt:71)
at androidx.compose.animation.core.AnimateAsStateKt.animateFloatAsState(AnimateAsState.kt:73)"#
.trim()
);
}

#[test]
fn test_remap_compose_stacktrace_group_keys_cache() {
let mapping = ProguardMapping::new(
br#"ComposeStackTrace -> $$compose:
1:1:androidx.compose.runtime.State androidx.compose.animation.core.AnimateAsStateKt.animateFloatAsState(float,androidx.compose.animation.core.AnimationSpec,float,java.lang.String,kotlin.jvm.functions.Function1,androidx.compose.runtime.Composer,int,int):71:71 -> m$1125598679
1:1:androidx.compose.runtime.State androidx.compose.animation.core.AnimateAsStateKt.animateFloatAsState(float,androidx.compose.animation.core.AnimationSpec,float,java.lang.String,kotlin.jvm.functions.Function1,androidx.compose.runtime.Composer,int,int):73:73 -> m$1125708605"#,
);

let mut buf = Vec::new();
ProguardCache::write(&mapping, &mut buf).unwrap();
let cache = ProguardCache::parse(&buf).unwrap();

let mapped = cache
.remap_stacktrace(
r#"androidx.compose.runtime.ComposeTraceException:
at $$compose.m$1125598679(SourceFile:1)
at $$compose.m$1125708605(SourceFile:1)"#,
)
.unwrap();

assert_eq!(
mapped.trim(),
r#"androidx.compose.runtime.ComposeTraceException:
at androidx.compose.animation.core.AnimateAsStateKt.animateFloatAsState(AnimateAsState.kt:71)
at androidx.compose.animation.core.AnimateAsStateKt.animateFloatAsState(AnimateAsState.kt:73)"#
.trim()
);
}
Loading