fix lints

This commit is contained in:
Jean-Marie Mineau 2025-02-05 11:37:52 +01:00
parent 88ecc534a2
commit ca31c41726
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2
12 changed files with 115 additions and 112 deletions

View file

@ -154,7 +154,7 @@ impl Apk {
{ {
info!( info!(
"Unexpected flags found in class_def_item.access_flags for {}: 0x{:x}", "Unexpected flags found in class_def_item.access_flags for {}: 0x{:x}",
String::from(descriptor.get_name()), descriptor.get_name().__str__(),
class_item.access_flags class_item.access_flags
); );
} }
@ -229,7 +229,7 @@ impl Apk {
"Inconsistant static_values array found in {}: \ "Inconsistant static_values array found in {}: \
|static_values| = {}, |static_fields| = {}, \ |static_values| = {}, |static_fields| = {}, \
|static_values| should be <= |static_fields|", |static_values| should be <= |static_fields|",
String::from(&descriptor.get_name()), &descriptor.get_name().__str__(),
values.len(), values.len(),
static_fields_list.len() static_fields_list.len()
)); ));
@ -266,7 +266,7 @@ impl Apk {
info!( info!(
"Annotation for field {} found in class {}, dropping it", "Annotation for field {} found in class {}, dropping it",
field_id.__str__(), field_id.__str__(),
String::from(descriptor.get_name()), descriptor.get_name().__str__(),
); );
} }
instance_fields instance_fields
@ -275,8 +275,8 @@ impl Apk {
static_fields static_fields
.entry(field_id.clone()) .entry(field_id.clone())
.and_modify(|field| field.annotations = annotations.clone()); .and_modify(|field| field.annotations = annotations.clone());
if instance_fields.get(&field_id).is_none() if !instance_fields.contains_key(&field_id)
&& static_fields.get(&field_id).is_none() && !static_fields.contains_key(&field_id)
{ {
info!( info!(
"Annotation found for field {} but could not find the field definition, dropping it", "Annotation found for field {} but could not find the field definition, dropping it",
@ -299,7 +299,7 @@ impl Apk {
info!( info!(
"Annotation for method {} found in class {}, dropping it", "Annotation for method {} found in class {}, dropping it",
method_id.__str__(), method_id.__str__(),
String::from(descriptor.get_name()), descriptor.get_name().__str__(),
); );
} }
direct_methods direct_methods
@ -308,8 +308,8 @@ impl Apk {
virtual_methods virtual_methods
.entry(method_id.clone()) .entry(method_id.clone())
.and_modify(|method| method.annotations = annotations.clone()); // TODO = or append? .and_modify(|method| method.annotations = annotations.clone()); // TODO = or append?
if direct_methods.get(&method_id).is_none() if !direct_methods.contains_key(&method_id)
&& virtual_methods.get(&method_id).is_none() && !virtual_methods.contains_key(&method_id)
{ {
info!( info!(
"Annotation found for method {} but could not find the method definition, dropping it", "Annotation found for method {} but could not find the method definition, dropping it",
@ -338,7 +338,7 @@ impl Apk {
info!( info!(
"Annotation for parameter of method {} found in class {}, dropping it", "Annotation for parameter of method {} found in class {}, dropping it",
method_id.__str__(), method_id.__str__(),
String::from(descriptor.get_name()), descriptor.get_name().__str__(),
); );
} }
direct_methods direct_methods
@ -347,8 +347,8 @@ impl Apk {
virtual_methods virtual_methods
.entry(method_id.clone()) .entry(method_id.clone())
.and_modify(|method| method.parameters_annotations = annotations_list.clone()); .and_modify(|method| method.parameters_annotations = annotations_list.clone());
if direct_methods.get(&method_id).is_none() if !direct_methods.contains_key(&method_id)
&& virtual_methods.get(&method_id).is_none() && !virtual_methods.contains_key(&method_id)
{ {
info!( info!(
"Annotation found for parameter of method {} but could not find the method definition, dropping it", "Annotation found for parameter of method {} but could not find the method definition, dropping it",
@ -654,8 +654,8 @@ impl Apk {
(false, false, true) => FieldVisibility::Protected, (false, false, true) => FieldVisibility::Protected,
(false, false, false) => FieldVisibility::None_, (false, false, false) => FieldVisibility::None_,
(pbl, prv, prt) => { (pbl, prv, prt) => {
let class: String = descriptor.class_.0.into(); let class: String = descriptor.class_.0.__str__();
let name: String = descriptor.name.into(); let name: String = descriptor.name.__str__();
return Err(anyhow!( return Err(anyhow!(
"Inconsistant visiblity found in {class}.{name}: \ "Inconsistant visiblity found in {class}.{name}: \
(public: {pbl}, private: {prv}, protected: {prt})" (public: {pbl}, private: {prv}, protected: {prt})"
@ -2812,7 +2812,7 @@ impl Apk {
.name_idx .name_idx
.map(|idx| dex.get_string(idx)) .map(|idx| dex.get_string(idx))
.transpose()? .transpose()?
.map(|str| DexString(str).into()), .map(DexString),
type_: val type_: val
.type_idx .type_idx
.map(|idx| Self::get_id_type_from_idx(idx as usize, dex)) .map(|idx| Self::get_id_type_from_idx(idx as usize, dex))
@ -2821,7 +2821,7 @@ impl Apk {
.sig_idx .sig_idx
.map(|idx| dex.get_string(idx)) .map(|idx| dex.get_string(idx))
.transpose()? .transpose()?
.map(|str| DexString(str).into()), .map(DexString),
}, },
DebugInfo::EndLocal { reg, .. } => Instruction::DebugEndLocal { reg }, DebugInfo::EndLocal { reg, .. } => Instruction::DebugEndLocal { reg },
DebugInfo::PrologueEnd { .. } => Instruction::DebugEndPrologue {}, DebugInfo::PrologueEnd { .. } => Instruction::DebugEndPrologue {},
@ -2832,7 +2832,7 @@ impl Apk {
file: source_file_idx file: source_file_idx
.map(|idx| dex.get_string(idx)) .map(|idx| dex.get_string(idx))
.transpose()? .transpose()?
.map(|str| DexString(str).into()), .map(DexString),
}, },
DebugInfo::SetLineNumber { line_num, .. } => Instruction::DebugLine { DebugInfo::SetLineNumber { line_num, .. } => Instruction::DebugLine {
number: line_num as usize, number: line_num as usize,
@ -3269,14 +3269,7 @@ impl Apk {
if !self.dex_files.contains_key(&file) { if !self.dex_files.contains_key(&file) {
self.dex_files.insert(file.clone(), DexFile::default()); self.dex_files.insert(file.clone(), DexFile::default());
} }
if self if self.dex_files.get(&file).unwrap().classes.contains_key(&id) {
.dex_files
.get(&file)
.unwrap()
.classes
.get(&id)
.is_some()
{
bail!("class {} already exists in {}", id.__str__(), &file); bail!("class {} already exists in {}", id.__str__(), &file);
} }
self.dex_files self.dex_files
@ -3298,7 +3291,7 @@ impl Apk {
let class = if let Some(dex_file) = dex_file { let class = if let Some(dex_file) = dex_file {
self.dex_files self.dex_files
.get_mut(&dex_file.to_string()) .get_mut(dex_file)
.with_context(|| format!("file {} not found in apk", dex_file))? .with_context(|| format!("file {} not found in apk", dex_file))?
.classes .classes
.get_mut(&method_id.class_) .get_mut(&method_id.class_)
@ -3345,7 +3338,7 @@ impl Apk {
pub fn remove_class(&mut self, class: &IdType, dex_file: Option<&str>) -> Result<()> { pub fn remove_class(&mut self, class: &IdType, dex_file: Option<&str>) -> Result<()> {
if let Some(dex_file) = dex_file { if let Some(dex_file) = dex_file {
self.dex_files self.dex_files
.get_mut(&dex_file.to_string()) .get_mut(dex_file)
.with_context(|| format!("file {} not found in apk", dex_file))? .with_context(|| format!("file {} not found in apk", dex_file))?
.classes .classes
.remove(class); .remove(class);

View file

@ -109,15 +109,15 @@ impl Class {
} }
pub fn __str__(&self) -> String { pub fn __str__(&self) -> String {
let name: String = (&self.descriptor.get_name()).into(); let name: String = self.descriptor.get_name().__str__();
let file = if let Some(file) = &self.source_file { let file = if let Some(file) = &self.source_file {
let file: String = file.into(); let file: String = file.__str__();
format!(" defined in {file}\n") format!(" defined in {file}\n")
} else { } else {
"".into() "".into()
}; };
let superclass = if let Some(spcl) = &self.superclass { let superclass = if let Some(spcl) = &self.superclass {
let spcl: String = spcl.get_name().into(); let spcl: String = spcl.get_name().__str__();
format!(" extends: {spcl}\n") format!(" extends: {spcl}\n")
} else { } else {
"".into() "".into()
@ -127,7 +127,7 @@ impl Class {
} else { } else {
let mut interfaces: String = " implements:\n".into(); let mut interfaces: String = " implements:\n".into();
for it in &self.interfaces { for it in &self.interfaces {
let it: String = it.get_name().into(); let it: String = it.get_name().__str__();
interfaces += &format!(" {it}\n"); interfaces += &format!(" {it}\n");
} }
interfaces interfaces
@ -137,7 +137,7 @@ impl Class {
} }
pub fn __repr__(&self) -> String { pub fn __repr__(&self) -> String {
let name: String = (&self.descriptor.get_name()).into(); let name: String = self.descriptor.get_name().__str__();
format!("Class({name})") format!("Class({name})")
} }

View file

@ -1,6 +1,7 @@
//! Representation of a method. //! Representation of a method.
use anyhow::anyhow; use anyhow::anyhow;
use log::debug;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
@ -232,7 +233,7 @@ impl Code {
for ins in &self.insns { for ins in &self.insns {
match ins { match ins {
Instruction::Label { name } => { Instruction::Label { name } => {
if used_labels.get(name).is_none() { if !used_labels.contains(name) {
continue; continue;
} }
let new_label_id = if last_ins_was_a_label { let new_label_id = if last_ins_was_a_label {
@ -250,8 +251,8 @@ impl Code {
} }
for label in &used_labels { for label in &used_labels {
if new_labels.get(label).is_none() { if !new_labels.contains_key(label) {
println!("{label} use but not in new_labels"); debug!("{label} use but not in new_labels");
} }
} }
@ -455,7 +456,7 @@ impl Code {
new_insns.push(Instruction::Switch { branches, reg }); new_insns.push(Instruction::Switch { branches, reg });
} }
Instruction::Label { name } => { Instruction::Label { name } => {
if used_labels.get(&name).is_none() { if !used_labels.contains(&name) {
//println!("{name} not used"); //println!("{name} not used");
continue; continue;
} }

View file

@ -216,9 +216,10 @@ impl IdMethodType {
/// Compute the format for the shorty as described in /// Compute the format for the shorty as described in
/// <https://source.android.com/docs/core/runtime/dex-format#shortydescriptor> /// <https://source.android.com/docs/core/runtime/dex-format#shortydescriptor>
pub fn compute_shorty(return_type: &IdType, parameters: &[IdType]) -> DexString { pub fn compute_shorty(return_type: &IdType, parameters: &[IdType]) -> DexString {
let mut shorty: String = return_type.get_shorty().into(); // TODO: computing on dex string instead of string? that a lot of doubious conversion
let mut shorty: String = return_type.get_shorty().__str__();
for ty in parameters { for ty in parameters {
let ty: String = ty.get_shorty().into(); let ty: String = ty.get_shorty().__str__();
shorty.push_str(&ty); shorty.push_str(&ty);
} }
shorty.into() shorty.into()
@ -441,11 +442,11 @@ impl IdType {
} }
pub fn __str__(&self) -> String { pub fn __str__(&self) -> String {
(&self.0).into() self.0.__str__()
} }
pub fn __repr__(&self) -> String { pub fn __repr__(&self) -> String {
let name: String = (&self.0).into(); let name: String = self.0.__str__();
format!("IdType(\"{name}\")") format!("IdType(\"{name}\")")
} }
@ -562,7 +563,7 @@ impl IdType {
{ {
Ok(()) Ok(())
} else { } else {
let format: String = (&self.0).into(); let format: String = self.0.__str__();
Err(anyhow!("{format} is not a valid type")) Err(anyhow!("{format} is not a valid type"))
} }
} }
@ -744,15 +745,15 @@ impl IdField {
} }
pub fn __str__(&self) -> String { pub fn __str__(&self) -> String {
let class: String = self.class_.get_name().into(); let class: String = self.class_.get_name().__str__();
let name: String = (&self.name).into(); let name: String = self.name.__str__();
let ty: String = self.type_.get_name().into(); let ty: String = self.type_.get_name().__str__();
format!("{class}->{name}:{ty}") format!("{class}->{name}:{ty}")
} }
pub fn __repr__(&self) -> String { pub fn __repr__(&self) -> String {
let class: String = self.class_.__repr__(); let class: String = self.class_.__repr__();
let name: String = (&self.name).into(); let name: String = self.name.__str__();
let ty: String = self.type_.__repr__(); let ty: String = self.type_.__repr__();
format!("IdField(\"{name}\", {ty}, {class})") format!("IdField(\"{name}\", {ty}, {class})")
} }

View file

@ -1,4 +1,5 @@
use crate::{Result, Visitable, VisitableMut, Visitor, VisitorMut}; use crate::{Result, Visitable, VisitableMut, Visitor, VisitorMut};
use anyhow::{Context, Error};
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::cmp::{Ord, PartialOrd}; use std::cmp::{Ord, PartialOrd};
use std::collections::HashSet; use std::collections::HashSet;
@ -26,7 +27,6 @@ impl<V: VisitorMut> VisitableMut<V> for DexString {
impl std::fmt::Debug for DexString { impl std::fmt::Debug for DexString {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
#[allow(clippy::unnecessary_fallible_conversions)]
if let Ok(string) = TryInto::<String>::try_into(self) { if let Ok(string) = TryInto::<String>::try_into(self) {
f.write_str(&format!( f.write_str(&format!(
"DexString({}, {:#x})", "DexString({}, {:#x})",
@ -117,17 +117,19 @@ impl From<androscalpel_serializer::StringDataItem> for DexString {
} }
} }
impl From<&DexString> for String { impl TryFrom<&DexString> for String {
fn from(DexString(string): &DexString) -> Self { type Error = Error;
fn try_from(DexString(string): &DexString) -> Result<Self> {
string string
.try_into() .try_into()
.unwrap_or(format!("InvalidEncoding:{:x?}", string.data)) .with_context(|| format!("InvalidEncoding:{:x?}", string.data))
} }
} }
impl From<DexString> for String { impl TryFrom<DexString> for String {
fn from(string: DexString) -> Self { type Error = Error;
(&string).into() fn try_from(string: DexString) -> Result<Self> {
(&string).try_into()
} }
} }
@ -191,11 +193,15 @@ impl DexString {
} }
pub fn __str__(&self) -> String { pub fn __str__(&self) -> String {
self.into() if let Ok(string) = TryInto::<String>::try_into(self) {
string
} else {
format!("string{:02x?}", self.0.data)
}
} }
pub fn __repr__(&self) -> String { pub fn __repr__(&self) -> String {
self.into() format!("{:?}", self)
} }
/// Return all strings references in the value. /// Return all strings references in the value.

View file

@ -192,7 +192,7 @@ impl DexWriter {
let new_nb_types = self.type_ids.len() let new_nb_types = self.type_ids.len()
+ new_types + new_types
.iter() .iter()
.filter(|ty| self.type_ids.get(ty).is_none()) .filter(|ty| !self.type_ids.contains_key(ty))
.count(); .count();
if new_nb_types >= u16::MAX as usize { if new_nb_types >= u16::MAX as usize {
return Err(DexWritterError::OutOfSpace( return Err(DexWritterError::OutOfSpace(
@ -204,7 +204,7 @@ impl DexWriter {
let new_nb_protos = self.proto_ids.len() let new_nb_protos = self.proto_ids.len()
+ new_protos + new_protos
.iter() .iter()
.filter(|proto| self.proto_ids.get(proto).is_none()) .filter(|proto| !self.proto_ids.contains_key(proto))
.count(); .count();
if new_nb_protos >= u16::MAX as usize { if new_nb_protos >= u16::MAX as usize {
return Err(DexWritterError::OutOfSpace( return Err(DexWritterError::OutOfSpace(
@ -216,7 +216,7 @@ impl DexWriter {
let new_nb_field_ids = self.field_ids.len() let new_nb_field_ids = self.field_ids.len()
+ new_field_ids + new_field_ids
.iter() .iter()
.filter(|field| self.field_ids.get(field).is_none()) .filter(|field| !self.field_ids.contains_key(field))
.count(); .count();
if new_nb_field_ids >= u16::MAX as usize { if new_nb_field_ids >= u16::MAX as usize {
return Err(DexWritterError::OutOfSpace( return Err(DexWritterError::OutOfSpace(
@ -228,7 +228,7 @@ impl DexWriter {
let new_nb_method_ids = self.method_ids.len() let new_nb_method_ids = self.method_ids.len()
+ new_method_ids + new_method_ids
.iter() .iter()
.filter(|meth| self.method_ids.get(meth).is_none()) .filter(|meth| !self.method_ids.contains_key(meth))
.count(); .count();
if new_nb_method_ids >= u16::MAX as usize { if new_nb_method_ids >= u16::MAX as usize {
return Err(DexWritterError::OutOfSpace( return Err(DexWritterError::OutOfSpace(
@ -737,7 +737,7 @@ impl DexWriter {
"Could not found type {} of local variable {} in debug info of {} \ "Could not found type {} of local variable {} in debug info of {} \
in the dex builder", in the dex builder",
ty.__repr__(), ty.__repr__(),
name.as_deref().unwrap_or(""), name.as_ref().map(DexString::__str__).unwrap_or_default(),
method_id.__repr__() method_id.__repr__()
)) ))
}) })
@ -745,10 +745,10 @@ impl DexWriter {
.map(|idx| *idx as u32), .map(|idx| *idx as u32),
name_idx: name.as_ref() name_idx: name.as_ref()
.map(|name| { .map(|name| {
self.strings.get(&name.as_str().into()).ok_or(anyhow!( self.strings.get(name).ok_or(anyhow!(
"Could not found string '{}' (name of local variable in debug info of {}) \ "Could not found string '{}' (name of local variable in debug info of {}) \
in the dex builder", in the dex builder",
name.as_str(), name.__str__(),
method_id.__repr__() method_id.__repr__()
)) ))
}) })
@ -756,11 +756,11 @@ impl DexWriter {
.map(|idx| *idx as u32), .map(|idx| *idx as u32),
sig_idx: signature.as_ref() sig_idx: signature.as_ref()
.map(|sig| { .map(|sig| {
self.strings.get(&sig.as_str().into()).ok_or(anyhow!( self.strings.get(sig).ok_or(anyhow!(
"Could not found string '{}' (signature of local variable {} in debug info of {}) \ "Could not found string '{}' (signature of local variable {} in debug info of {}) \
in the dex builder", in the dex builder",
sig, sig.__str__(),
name.as_deref().unwrap_or(""), name.as_ref().map(DexString::__str__).unwrap_or_default(),
method_id.__repr__() method_id.__repr__()
)) ))
}) })
@ -776,7 +776,7 @@ impl DexWriter {
addr: addr as u32, addr: addr as u32,
reg: *reg, reg: *reg,
}) })
.context("Failled to serialize DebugEndLocal information")?, .context("Failled to seri2846alize DebugEndLocal information")?,
Instruction::DebugEndPrologue {} => debug_builder Instruction::DebugEndPrologue {} => debug_builder
.add_info(&DebugInfo::PrologueEnd { addr: addr as u32 }) .add_info(&DebugInfo::PrologueEnd { addr: addr as u32 })
.context("Failled to serialize DebugEndPrologue information")?, .context("Failled to serialize DebugEndPrologue information")?,
@ -788,10 +788,10 @@ impl DexWriter {
addr: addr as u32, addr: addr as u32,
source_file_idx: file.as_ref() source_file_idx: file.as_ref()
.map(|file| { .map(|file| {
self.strings.get(&file.as_str().into()).ok_or(anyhow!( self.strings.get(file).ok_or(anyhow!(
"Could not found string '{}' (name of the source file of part of {}) \ "Could not found string '{}' (name of the source file of part of {}) \
in the dex builder", in the dex builder",
file, file.__str__(),
method_id.__repr__() method_id.__repr__()
)) ))
}) })
@ -874,7 +874,6 @@ impl DexWriter {
/// Insert annotation associated to a class. /// Insert annotation associated to a class.
/// ///
/// Insert a class_data_item in the class_data section (in data). /// Insert a class_data_item in the class_data section (in data).
/// ///
/// # Note /// # Note
@ -2273,12 +2272,12 @@ impl DexWriter {
for (ty, (def, _)) in &self.class_defs { for (ty, (def, _)) in &self.class_defs {
let mut edges_to = HashSet::new(); let mut edges_to = HashSet::new();
if let Some(sup) = def.superclass.as_ref() { if let Some(sup) = def.superclass.as_ref() {
if self.class_defs.get(sup).is_some() { if self.class_defs.contains_key(sup) {
edges_to.insert(sup); edges_to.insert(sup);
} }
} }
for sup in &def.interfaces { for sup in &def.interfaces {
if self.class_defs.get(sup).is_some() { if self.class_defs.contains_key(sup) {
edges_to.insert(sup); edges_to.insert(sup);
} }
} }

View file

@ -23,7 +23,7 @@ impl From<&androscalpel_serializer::HiddenApiFlags> for HiddenApiData {
} }
impl From<androscalpel_serializer::HiddenApiFlags> for HiddenApiData { impl From<androscalpel_serializer::HiddenApiFlags> for HiddenApiData {
fn from(flags: androscalpel_serializer::HiddenApiFlags) -> Self { fn from(flags: androscalpel_serializer::HiddenApiFlags) -> Self {
flags.into() (&flags).into()
} }
} }
@ -37,7 +37,7 @@ impl From<&HiddenApiData> for androscalpel_serializer::HiddenApiFlags {
} }
impl From<HiddenApiData> for androscalpel_serializer::HiddenApiFlags { impl From<HiddenApiData> for androscalpel_serializer::HiddenApiFlags {
fn from(flags: HiddenApiData) -> Self { fn from(flags: HiddenApiData) -> Self {
flags.into() (&flags).into()
} }
} }

View file

@ -638,9 +638,9 @@ pub enum Instruction {
/// Debug information. Define a local variable associated with a register. /// Debug information. Define a local variable associated with a register.
DebugLocal { DebugLocal {
reg: u32, reg: u32,
name: Option<String>, name: Option<DexString>,
type_: Option<IdType>, type_: Option<IdType>,
signature: Option<String>, signature: Option<DexString>,
}, },
/// Debug information. Undefine a local variable associated with a register. /// Debug information. Undefine a local variable associated with a register.
DebugEndLocal { reg: u32 }, DebugEndLocal { reg: u32 },
@ -649,7 +649,7 @@ pub enum Instruction {
/// Debug information. Indicate the beginning of the Epilogue /// Debug information. Indicate the beginning of the Epilogue
DebugBeginEpilogue {}, DebugBeginEpilogue {},
/// Debug information. Indicate the source file of the following instructions. /// Debug information. Indicate the source file of the following instructions.
DebugSourceFile { file: Option<String> }, DebugSourceFile { file: Option<DexString> },
/// Debug information. Indicate the line number of the following instructions. /// Debug information. Indicate the line number of the following instructions.
DebugLine { number: usize }, DebugLine { number: usize },
} }
@ -1216,20 +1216,25 @@ impl<V: Visitor> Visitable<V> for Instruction {
Self::Label { name: _ } => Ok(()), Self::Label { name: _ } => Ok(()),
Self::DebugLocal { Self::DebugLocal {
reg: _, reg: _,
name: _, name,
type_: Some(type_), type_,
signature: _, signature,
} => v.visit_type(type_), } => {
Self::DebugLocal { if let Some(name) = name {
reg: _, v.visit_string(name)?;
name: _, }
type_: None, if let Some(type_) = type_ {
signature: _, v.visit_type(type_)?;
} => Ok(()), }
if let Some(signature) = signature {
v.visit_string(signature)?;
}
Ok(())
}
Self::DebugEndLocal { reg: _ } => Ok(()), Self::DebugEndLocal { reg: _ } => Ok(()),
Self::DebugEndPrologue {} => Ok(()), Self::DebugEndPrologue {} => Ok(()),
Self::DebugBeginEpilogue {} => Ok(()), Self::DebugBeginEpilogue {} => Ok(()),
Self::DebugSourceFile { file: Some(file) } => v.visit_string(&(file.as_str().into())), Self::DebugSourceFile { file: Some(file) } => v.visit_string(file),
Self::DebugSourceFile { file: None } => Ok(()), Self::DebugSourceFile { file: None } => Ok(()),
Self::DebugLine { number: _ } => Ok(()), Self::DebugLine { number: _ } => Ok(()),
} }
@ -1883,19 +1888,18 @@ impl<V: VisitorMut> VisitableMut<V> for Instruction {
signature, signature,
} => Ok(Self::DebugLocal { } => Ok(Self::DebugLocal {
reg, reg,
name, name: name.map(|name| v.visit_string(name)).transpose()?,
type_: type_.map(|type_| v.visit_type(type_)).transpose()?, type_: type_.map(|type_| v.visit_type(type_)).transpose()?,
signature, signature: signature
.map(|signature| v.visit_string(signature))
.transpose()?,
}), }),
Self::DebugEndLocal { reg: _ } => Ok(self), Self::DebugEndLocal { reg: _ } => Ok(self),
Self::DebugEndPrologue {} => Ok(self), Self::DebugEndPrologue {} => Ok(self),
Self::DebugBeginEpilogue {} => Ok(self), Self::DebugBeginEpilogue {} => Ok(self),
Self::DebugSourceFile { file: Some(file) } => { Self::DebugSourceFile { file: Some(file) } => v
v.visit_string(file.as_str().into()) .visit_string(file)
.map(|file| Self::DebugSourceFile { .map(|file| Self::DebugSourceFile { file: Some(file) }),
file: Some(file.into()),
})
}
Self::DebugSourceFile { file: None } => Ok(self), Self::DebugSourceFile { file: None } => Ok(self),
Self::DebugLine { number: _ } => Ok(self), Self::DebugLine { number: _ } => Ok(self),
} }
@ -2081,7 +2085,7 @@ macro_rules! raw_ins_invoke {
}) })
} else if consec && len <= 255 { } else if consec && len <= 255 {
let a = $args.len() as u8; let a = $args.len() as u8;
let vc = if let Some(vc) = first { vc } else { 0 }; let vc = first.unwrap_or(0);
Ok(InsFormat::Format3RC { Ok(InsFormat::Format3RC {
op: $ins_op_3rc, op: $ins_op_3rc,
a, a,
@ -2833,10 +2837,10 @@ impl Instruction {
signature, signature,
} => { } => {
// TODO: check if/how apktool/smali handles empty name and type // TODO: check if/how apktool/smali handles empty name and type
let name = name.clone().unwrap_or(String::new()); let name = name.as_ref().map(DexString::__str__).unwrap_or_default();
let ty = type_.as_ref().map(IdType::__str__).unwrap_or(String::new()); let ty = type_.as_ref().map(IdType::__str__).unwrap_or(String::new());
if let Some(signature) = signature { if let Some(signature) = signature {
format!(".local {reg}, \"{name}\":{ty}, \"{signature}\"") format!(".local {reg}, \"{name}\":{ty}, \"{}\"", signature.__str__())
} else { } else {
format!(".local {reg}, \"{name}\":{ty}") format!(".local {reg}, \"{name}\":{ty}")
} }
@ -2845,7 +2849,9 @@ impl Instruction {
Self::DebugEndPrologue {} => ".prologue".into(), Self::DebugEndPrologue {} => ".prologue".into(),
Self::DebugBeginEpilogue {} => ".epilogue".into(), Self::DebugBeginEpilogue {} => ".epilogue".into(),
// TODO: check if/how apktool/smali handles empty change of src file // TODO: check if/how apktool/smali handles empty change of src file
Self::DebugSourceFile { file: Some(file) } => format!(".source_file {file}"), Self::DebugSourceFile { file: Some(file) } => {
format!(".source_file {}", file.__str__())
}
// TODO: find a better representation // TODO: find a better representation
Self::DebugSourceFile { file: None } => ".source_file unknown".into(), Self::DebugSourceFile { file: None } => ".source_file unknown".into(),
Self::DebugLine { number } => format!(".line {number}"), Self::DebugLine { number } => format!(".line {number}"),
@ -3643,12 +3649,12 @@ impl Instruction {
type_, type_,
signature, signature,
} => { } => {
let name = name.clone().unwrap_or("None".into()); let name = name.clone().unwrap_or("None".into()).__str__();
let type_ = type_ let type_ = type_
.as_ref() .as_ref()
.map(IdType::__repr__) .map(IdType::__repr__)
.unwrap_or("None".into()); .unwrap_or("None".into());
let signature = signature.clone().unwrap_or("None".into()); let signature = signature.clone().unwrap_or("None".into()).__str__();
format!("Instruction::DebugLoca({reg}, {name}, {type_}, {signature}") format!("Instruction::DebugLoca({reg}, {name}, {type_}, {signature}")
} }
Self::DebugEndLocal { reg } => format!("Instruction::DebugEndLocal({reg})"), Self::DebugEndLocal { reg } => format!("Instruction::DebugEndLocal({reg})"),
@ -3656,7 +3662,7 @@ impl Instruction {
Self::DebugBeginEpilogue {} => "Instruction::DebugBeginEpilogue".into(), Self::DebugBeginEpilogue {} => "Instruction::DebugBeginEpilogue".into(),
// TODO: check if/how apktool/smali handles empty change of src file // TODO: check if/how apktool/smali handles empty change of src file
Self::DebugSourceFile { file: Some(file) } => { Self::DebugSourceFile { file: Some(file) } => {
format!("Instruction::DebugSourceFile({file})") format!("Instruction::DebugSourceFile({})", file.__str__())
} }
Self::DebugSourceFile { file: None } => "Instruction::DebugSourceFile(None)".into(), Self::DebugSourceFile { file: None } => "Instruction::DebugSourceFile(None)".into(),
Self::DebugLine { number } => format!("Instruction::DebugLine({number})"), Self::DebugLine { number } => format!("Instruction::DebugLine({number})"),
@ -4464,7 +4470,7 @@ impl Instruction {
}) })
} else if consec && len <= 255 { } else if consec && len <= 255 {
let a = reg_values.len() as u8; let a = reg_values.len() as u8;
let vc = if let Some(vc) = first { vc } else { 0 }; let vc = first.unwrap_or(0);
Ok(InsFormat::Format3RC { Ok(InsFormat::Format3RC {
op: 0x25, op: 0x25,
a, a,
@ -5358,7 +5364,7 @@ impl Instruction {
}) })
} else if consec && len <= 255 { } else if consec && len <= 255 {
let a = args.len() as u8; let a = args.len() as u8;
let vc = if let Some(vc) = first { vc } else { 0 }; let vc = first.unwrap_or(0);
Ok(InsFormat::Format4RCC { Ok(InsFormat::Format4RCC {
op: 0xfb, op: 0xfb,
a, a,
@ -5435,7 +5441,7 @@ impl Instruction {
}) })
} else if consec && len <= 255 { } else if consec && len <= 255 {
let a = args.len() as u8; let a = args.len() as u8;
let vc = if let Some(vc) = first { vc } else { 0 }; let vc = first.unwrap_or(0);
Ok(InsFormat::Format3RC { Ok(InsFormat::Format3RC {
op: 0xfd, op: 0xfd,
a, a,

View file

@ -1,6 +1,3 @@
//#![allow(clippy::unnecessary_fallible_conversions)]
// DexString has Into<String> but it's only for
// python, TryInto should be prefered
use anyhow::Result; use anyhow::Result;
#[cfg(feature = "python")] #[cfg(feature = "python")]

View file

@ -100,8 +100,8 @@ impl CodeItem {
addresses.push(try_.start_addr); addresses.push(try_.start_addr);
addresses.push(try_.start_addr + try_.insn_count as u32); addresses.push(try_.start_addr + try_.insn_count as u32);
} }
for handler in &self.handlers { if let Some(handlers) = &self.handlers {
for catch in &handler.list { for catch in &handlers.list {
for EncodedTypeAddrPair { for EncodedTypeAddrPair {
addr: Uleb128(addr), addr: Uleb128(addr),
.. ..

View file

@ -1,8 +1,8 @@
use apk_frauder::ZipFileReader; use apk_frauder::ZipFileReader;
use std::collections::HashMap; //use std::collections::HashMap;
use std::env; //use std::env;
use std::fs::File; use std::fs::File;
use std::io::Cursor; //use std::io::Cursor;
fn main() { fn main() {
/* /*