diff --git a/Cargo.lock b/Cargo.lock index 5cc9001..cc179a4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -98,12 +98,6 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "block-buffer" version = "0.10.4" @@ -242,9 +236,9 @@ checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "indoc" @@ -264,16 +258,6 @@ version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" -[[package]] -name = "lock_api" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" -dependencies = [ - "autocfg", - "scopeguard", -] - [[package]] name = "log" version = "0.4.20" @@ -319,29 +303,6 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" -[[package]] -name = "parking_lot" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets", -] - [[package]] name = "portable-atomic" version = "1.6.0" @@ -366,25 +327,25 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] [[package]] name = "pyo3" -version = "0.21.2" +version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e00b96a521718e08e03b1a622f01c8a8deb50719335de3f60b3b3950f069d8" +checksum = "57fe09249128b3173d092de9523eaa75136bf7ba85e0d69eca241c7939c933cc" dependencies = [ "anyhow", "cfg-if", "indoc", "libc", "memoffset", - "parking_lot", + "once_cell", "portable-atomic", "pyo3-build-config", "pyo3-ffi", @@ -394,9 +355,9 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.21.2" +version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7883df5835fafdad87c0d888b266c8ec0f4c9ca48a5bed6bbb592e8dedee1b50" +checksum = "1cd3927b5a78757a0d71aa9dff669f903b1eb64b54142a9bd9f757f8fde65fd7" dependencies = [ "once_cell", "target-lexicon", @@ -404,9 +365,9 @@ dependencies = [ [[package]] name = "pyo3-ffi" -version = "0.21.2" +version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01be5843dc60b916ab4dad1dca6d20b9b4e6ddc8e15f50c47fe6d85f1fb97403" +checksum = "dab6bb2102bd8f991e7749f130a70d05dd557613e39ed2deeee8e9ca0c4d548d" dependencies = [ "libc", "pyo3-build-config", @@ -414,9 +375,9 @@ dependencies = [ [[package]] name = "pyo3-log" -version = "0.10.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af49834b8d2ecd555177e63b273b708dea75150abc6f5341d0a6e1a9623976c" +checksum = "be5bb22b77965a7b5394e9aae9897a0607b51df5167561ffc3b02643b4200bc7" dependencies = [ "arc-swap", "log", @@ -425,9 +386,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.21.2" +version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77b34069fc0682e11b31dbd10321cbf94808394c56fd996796ce45217dfac53c" +checksum = "91871864b353fd5ffcb3f91f2f703a22a9797c91b9ab497b1acac7b07ae509c7" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -437,9 +398,9 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.21.2" +version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08260721f32db5e1a5beae69a55553f56b99bd0e1c3e6e0a5e8851a9d0f5a85c" +checksum = "43abc3b80bc20f3facd86cd3c60beed58c3e2aa26213f3cda368de39c60a27e4" dependencies = [ "heck", "proc-macro2", @@ -507,15 +468,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags", -] - [[package]] name = "rustc-demangle" version = "0.1.23" @@ -528,12 +480,6 @@ version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - [[package]] name = "serde" version = "1.0.195" @@ -576,17 +522,11 @@ dependencies = [ "digest", ] -[[package]] -name = "smallvec" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" - [[package]] name = "syn" -version = "2.0.48" +version = "2.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" dependencies = [ "proc-macro2", "quote", @@ -595,9 +535,9 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.11" +version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "typenum" @@ -629,63 +569,6 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "yansi" version = "1.0.1" diff --git a/androscalpel/Cargo.toml b/androscalpel/Cargo.toml index 795ce66..d224f54 100644 --- a/androscalpel/Cargo.toml +++ b/androscalpel/Cargo.toml @@ -14,8 +14,8 @@ androscalpel_serializer = { version = "0.1.0", path = "../androscalpel_serialize anyhow = { version = "1.0.75", features = ["backtrace"] } apk_frauder = { version = "0.1.0", path = "../apk_frauder" } log = "0.4.20" -pyo3 = { version = "0.21.0", features = ["anyhow", "abi3-py38"] } -pyo3-log = "0.10.0" +pyo3 = { version = "0.23.4", features = ["anyhow", "abi3-py38"] } +pyo3-log = "0.12.1" rayon = "1.9.0" serde = { version = "1.0.195", features = ["derive"] } serde_json = "1.0.111" diff --git a/androscalpel/src/apk.rs b/androscalpel/src/apk.rs index 1b80e11..7da2c16 100644 --- a/androscalpel/src/apk.rs +++ b/androscalpel/src/apk.rs @@ -35,46 +35,6 @@ pub struct Apk { } impl Apk { - /// Add the content of a dex file to the apk. - /// - /// # Parameters - /// - `name`: the name of the dex file - /// - `data`: the dex file binary - /// - `label_each_ins`: if set to true, insert a label before each instruction - /// indicating the instruction address - /// - `cache`: if set to true, copy and cache the binary data format. - pub fn add_dex_file( - &mut self, - name: &str, - data: &[u8], - label_each_ins: bool, - cache: bool, - ) -> Result<()> { - let name: String = name.into(); - if self.dex_files.contains_key(&name) { - bail!("{name} already exist in the application") - } - let mut dex = DexFileReader::new(data)?; - let classes = dex - .get_class_defs() - .par_iter() - .enumerate() - .map(|(idx, class)| self.get_class_from_dex_file(class, idx, &dex, label_each_ins)) - .map(|class| class.map(|class| (class.descriptor.clone(), class))) - .collect::, _>>()?; - let dex_file = DexFile { - classes, - not_referenced_strings: dex - .get_not_resolved_strings()? - .into_iter() - .map(DexString) - .collect(), - bin_cache: if cache { Some(data.to_vec()) } else { None }, - }; - self.dex_files.insert(name, dex_file); - Ok(()) - } - /// Extract a class from a dex file reader. /// `class_item_idx` if the index of the `class_def_item` of the class, **not** the /// `class_idx`. @@ -3026,20 +2986,46 @@ impl Apk { } } - #[pyo3(name = "add_dex_file")] - pub fn py_add_dex_file( + // TODO: change cache to true when cache invalidation is setup + /// Add the content of a dex file to the apk. + /// + /// # Parameters + /// - `name`: the name of the dex file + /// - `data`: the dex file binary + /// - `label_each_ins`: if set to true, insert a label before each instruction + /// indicating the instruction address + /// - `cache`: if set to true, copy and cache the binary data format. + #[pyo3(signature = (name, data, label_each_ins=false, cache=false))] + pub fn add_dex_file( &mut self, name: &str, data: &[u8], - label_each_ins: Option, - cache: Option, + label_each_ins: bool, + cache: bool, ) -> Result<()> { - self.add_dex_file( - name, - data, - label_each_ins.unwrap_or(false), - cache.unwrap_or(false), // TODO: change to true when cache invalidation is setup - ) + let name: String = name.into(); + if self.dex_files.contains_key(&name) { + bail!("{name} already exist in the application") + } + let mut dex = DexFileReader::new(data)?; + let classes = dex + .get_class_defs() + .par_iter() + .enumerate() + .map(|(idx, class)| self.get_class_from_dex_file(class, idx, &dex, label_each_ins)) + .map(|class| class.map(|class| (class.descriptor.clone(), class))) + .collect::, _>>()?; + let dex_file = DexFile { + classes, + not_referenced_strings: dex + .get_not_resolved_strings()? + .into_iter() + .map(DexString) + .collect(), + bin_cache: if cache { Some(data.to_vec()) } else { None }, + }; + self.dex_files.insert(name, dex_file); + Ok(()) } pub fn add_class(&mut self, dex_file: &str, class: Class) -> Result<()> { @@ -3066,6 +3052,7 @@ impl Apk { Ok(()) } + #[pyo3(signature = (method_id, code=None, dex_file=None))] pub fn set_method_code( &mut self, method_id: IdMethod, @@ -3109,7 +3096,7 @@ impl Apk { Ok(self .gen_raw_dex()? .into_iter() - .map(|(file_name, bytes)| (file_name, PyBytes::new_bound(py, &bytes).into())) + .map(|(file_name, bytes)| (file_name, PyBytes::new(py, &bytes).into())) .collect()) } @@ -3122,6 +3109,7 @@ impl Apk { Ok(serde_json::from_str(json)?) } + #[pyo3(signature = (class, dex_file=None))] pub fn remove_class(&mut self, class: &IdType, dex_file: Option<&str>) -> Result<()> { if let Some(dex_file) = dex_file { self.dex_files diff --git a/androscalpel/src/code.rs b/androscalpel/src/code.rs index cfb9ca8..2df1cfd 100644 --- a/androscalpel/src/code.rs +++ b/androscalpel/src/code.rs @@ -64,6 +64,7 @@ impl Code { } #[new] + #[pyo3(signature = (registers_size, ins_size, outs_size, insns, parameter_names=None))] pub fn new( registers_size: u16, ins_size: u16, diff --git a/androscalpel/src/field.rs b/androscalpel/src/field.rs index 522dcf9..c887089 100644 --- a/androscalpel/src/field.rs +++ b/androscalpel/src/field.rs @@ -50,7 +50,7 @@ pub struct Field { } /// Represent the visibility of a field -#[pyclass] +#[pyclass(eq, eq_int)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)] pub enum FieldVisibility { Public, diff --git a/androscalpel/src/lib.rs b/androscalpel/src/lib.rs index a58d495..41c5c75 100644 --- a/androscalpel/src/lib.rs +++ b/androscalpel/src/lib.rs @@ -79,10 +79,10 @@ fn androscalpel(py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> { m.add_class::()?; m.add_class::()?; - let ins_module = PyModule::new_bound(py, "ins")?; + let ins_module = PyModule::new(py, "ins")?; androscalpel_ins(py, &ins_module)?; m.add_submodule(&ins_module)?; - let utils_module = PyModule::new_bound(py, "utils")?; + let utils_module = PyModule::new(py, "utils")?; py_utils::export_module(py, &utils_module)?; m.add_submodule(&utils_module)?; diff --git a/androscalpel/src/method.rs b/androscalpel/src/method.rs index 08944af..b95c0e6 100644 --- a/androscalpel/src/method.rs +++ b/androscalpel/src/method.rs @@ -13,7 +13,7 @@ use androscalpel_serializer::consts::*; /// Represent a method. #[pyclass] -#[derive(Debug, Clone, Deserialize, Serialize)] //, PartialEq)] +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)] pub struct Method { /// The structure used to reference this method. #[pyo3(get)] @@ -70,18 +70,9 @@ pub struct Method { #[pyo3(get)] pub code: Option, } -impl PartialEq for Method { - fn eq(&self, other: &Self) -> bool { - let res = self.code.eq(&other.code); - if !res { - //panic!("{} code don't match", self.descriptor.__str__()); - } - return res; - } -} /// Represent the visibility of a field -#[pyclass] +#[pyclass(eq, eq_int)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)] pub enum MethodVisibility { Public, diff --git a/androscalpel/src/py_utils.rs b/androscalpel/src/py_utils.rs index 2a40367..d9344d3 100644 --- a/androscalpel/src/py_utils.rs +++ b/androscalpel/src/py_utils.rs @@ -1,7 +1,7 @@ //! Function that are can be usefull on the python side. use pyo3::prelude::*; -use pyo3::types::PyBytes; +use pyo3::types::{PyBytes, PyBytesMethods}; use std::collections::{HashMap, HashSet}; use std::fs::File; @@ -17,18 +17,18 @@ use apk_frauder::{end_of_central_directory::EndCentralDirectory, ZipFileReader}; /// Convert an integer to the uleb128 byte encoding #[pyfunction] pub fn int_to_uleb128(py: Python, x: u32) -> Result { - Ok(PyBytes::new_bound(py, &Uleb128(x).serialize_to_vec()?).into()) + Ok(PyBytes::new(py, &Uleb128(x).serialize_to_vec()?).into()) } /// Convert an integer to the uleb128p1 byte encoding #[pyfunction] pub fn int_to_uleb128p1(py: Python, x: u32) -> Result { - Ok(PyBytes::new_bound(py, &Uleb128p1(x).serialize_to_vec()?).into()) + Ok(PyBytes::new(py, &Uleb128p1(x).serialize_to_vec()?).into()) } /// Convert an integer to the sleb128 byte encoding #[pyfunction] pub fn int_to_sleb128(py: Python, x: i32) -> Result { - Ok(PyBytes::new_bound(py, &Sleb128(x).serialize_to_vec()?).into()) + Ok(PyBytes::new(py, &Sleb128(x).serialize_to_vec()?).into()) } /// Decode an uleb128 encoded integer @@ -109,26 +109,36 @@ pub fn is_zip(file: PathBuf) -> bool { /// The keys are the file names and the values are `None` to remove the file, or /// `bytes` for the content of the file. #[pyfunction] +#[pyo3(signature = ( + apk, + dst, + dexfiles, + keystore, + zipalign=None, + apksigner=None, + additionnal_files=None +))] pub fn replace_dex( apk: PathBuf, dst: PathBuf, - dexfiles: Vec<&PyBytes>, + dexfiles: Vec>, keystore: PathBuf, zipalign: Option, apksigner: Option, - additionnal_files: Option>>, + additionnal_files: Option>>>, ) { let mut dexfiles: Vec<_> = dexfiles - .into_iter() - .map(PyBytes::as_bytes) + .iter() + .map(PyBytesMethods::as_bytes) .map(Cursor::new) .collect(); - let additionnal_files: Option> = additionnal_files.map(|additionnal_files| { - additionnal_files - .into_iter() - .map(|(k, v)| (k, v.map(PyBytes::as_bytes).map(Cursor::new))) - .collect() - }); + let additionnal_files: Option> = additionnal_files.as_ref().map(|additionnal_files| + additionnal_files.iter() + .map(|(k, v)| ( + k.clone(), + v.as_ref().map(|bytes| bytes.as_bytes()).map(Cursor::new) + )).collect() + ); apk_frauder::replace_dex( apk, dst, diff --git a/androscalpel/src/value.rs b/androscalpel/src/value.rs index 5ad4c4f..e25d857 100644 --- a/androscalpel/src/value.rs +++ b/androscalpel/src/value.rs @@ -84,42 +84,42 @@ impl VisitableMut for DexValue { } impl<'source> FromPyObject<'source> for DexValue { - fn extract(ob: &'source PyAny) -> PyResult { - if let Ok(val) = DexByte::extract(ob) { + fn extract_bound(ob: &Bound<'source, PyAny>) -> PyResult { + if let Ok(val) = DexByte::extract_bound(ob) { Ok(Self::Byte(val)) - } else if let Ok(val) = DexShort::extract(ob) { + } else if let Ok(val) = DexShort::extract_bound(ob) { Ok(Self::Short(val)) - } else if let Ok(val) = DexChar::extract(ob) { + } else if let Ok(val) = DexChar::extract_bound(ob) { Ok(Self::Char(val)) - } else if let Ok(val) = DexInt::extract(ob) { + } else if let Ok(val) = DexInt::extract_bound(ob) { Ok(Self::Int(val)) - } else if let Ok(val) = DexLong::extract(ob) { + } else if let Ok(val) = DexLong::extract_bound(ob) { Ok(Self::Long(val)) - } else if let Ok(val) = DexFloat::extract(ob) { + } else if let Ok(val) = DexFloat::extract_bound(ob) { Ok(Self::Float(val)) - } else if let Ok(val) = DexDouble::extract(ob) { + } else if let Ok(val) = DexDouble::extract_bound(ob) { Ok(Self::Double(val)) - } else if let Ok(val) = DexString::extract(ob) { + } else if let Ok(val) = DexString::extract_bound(ob) { Ok(Self::String(val)) - } else if let Ok(val) = IdType::extract(ob) { + } else if let Ok(val) = IdType::extract_bound(ob) { Ok(Self::Type(val)) - } else if let Ok(val) = IdField::extract(ob) { + } else if let Ok(val) = IdField::extract_bound(ob) { Ok(Self::Field(val)) - } else if let Ok(val) = IdMethod::extract(ob) { + } else if let Ok(val) = IdMethod::extract_bound(ob) { Ok(Self::Method(val)) - } else if let Ok(val) = IdEnum::extract(ob) { + } else if let Ok(val) = IdEnum::extract_bound(ob) { Ok(Self::Enum(val)) - } else if let Ok(val) = DexArray::extract(ob) { + } else if let Ok(val) = DexArray::extract_bound(ob) { Ok(Self::Array(val)) - } else if let Ok(val) = DexAnnotation::extract(ob) { + } else if let Ok(val) = DexAnnotation::extract_bound(ob) { Ok(Self::Annotation(val)) - } else if let Ok(val) = DexNull::extract(ob) { + } else if let Ok(val) = DexNull::extract_bound(ob) { Ok(Self::Null(val)) - } else if let Ok(val) = DexBoolean::extract(ob) { + } else if let Ok(val) = DexBoolean::extract_bound(ob) { Ok(Self::Boolean(val)) - } else if let Ok(val) = IdMethodType::extract(ob) { + } else if let Ok(val) = IdMethodType::extract_bound(ob) { Ok(Self::MethodType(val)) - } else if let Ok(val) = MethodHandle::extract(ob) { + } else if let Ok(val) = MethodHandle::extract_bound(ob) { Ok(Self::MethodHandle(val)) } else { Err(PyErr::new::(format!( @@ -306,27 +306,31 @@ impl DexValue { } } -impl IntoPy for DexValue { - fn into_py(self, py: Python<'_>) -> PyObject { +impl<'py> IntoPyObject<'py> for DexValue { + type Target = PyAny; + type Output = Bound<'py, Self::Target>; + type Error = PyErr; + + fn into_pyobject(self, py: Python<'py>) -> Result { match self { - DexValue::Byte(val) => val.into_py(py), - DexValue::Short(val) => val.into_py(py), - DexValue::Char(val) => val.into_py(py), - DexValue::Int(val) => val.into_py(py), - DexValue::Long(val) => val.into_py(py), - DexValue::Float(val) => val.into_py(py), - DexValue::Double(val) => val.into_py(py), - DexValue::MethodType(val) => val.into_py(py), - DexValue::MethodHandle(val) => val.into_py(py), - DexValue::String(val) => val.into_py(py), - DexValue::Type(val) => val.into_py(py), - DexValue::Field(val) => val.into_py(py), - DexValue::Method(val) => val.into_py(py), - DexValue::Enum(val) => val.into_py(py), - DexValue::Array(val) => val.into_py(py), - DexValue::Annotation(val) => val.into_py(py), - DexValue::Null(val) => val.into_py(py), - DexValue::Boolean(val) => val.into_py(py), + DexValue::Byte(val) => Bound::new(py, val).map(Bound::<_>::into_any), + DexValue::Short(val) => Bound::new(py, val).map(Bound::<_>::into_any), + DexValue::Char(val) => Bound::new(py, val).map(Bound::<_>::into_any), + DexValue::Int(val) => Bound::new(py, val).map(Bound::<_>::into_any), + DexValue::Long(val) => Bound::new(py, val).map(Bound::<_>::into_any), + DexValue::Float(val) => Bound::new(py, val).map(Bound::<_>::into_any), + DexValue::Double(val) => Bound::new(py, val).map(Bound::<_>::into_any), + DexValue::MethodType(val) => Bound::new(py, val).map(Bound::<_>::into_any), + DexValue::MethodHandle(val) => Bound::new(py, val).map(Bound::<_>::into_any), + DexValue::String(val) => Bound::new(py, val).map(Bound::<_>::into_any), + DexValue::Type(val) => Bound::new(py, val).map(Bound::<_>::into_any), + DexValue::Field(val) => Bound::new(py, val).map(Bound::<_>::into_any), + DexValue::Method(val) => Bound::new(py, val).map(Bound::<_>::into_any), + DexValue::Enum(val) => Bound::new(py, val).map(Bound::<_>::into_any), + DexValue::Array(val) => Bound::new(py, val).map(Bound::<_>::into_any), + DexValue::Annotation(val) => Bound::new(py, val).map(Bound::<_>::into_any), + DexValue::Null(val) => Bound::new(py, val).map(Bound::<_>::into_any), + DexValue::Boolean(val) => Bound::new(py, val).map(Bound::<_>::into_any), } } }