From cf557666536a2e04d7ec92c1fbc1984a280a706c Mon Sep 17 00:00:00 2001 From: Jean-Marie Mineau Date: Tue, 28 Nov 2023 19:06:28 +0100 Subject: [PATCH] fix stuff, add class annotation --- androscalpel/src/annotation.rs | 54 ++++++++--- androscalpel/src/apk.rs | 39 +++++--- androscalpel/src/class.rs | 8 +- androscalpel/src/dex_id.rs | 23 ----- androscalpel/src/lib.rs | 23 +++-- androscalpel/src/scalar.rs | 2 +- androscalpel/src/value.rs | 6 +- .../src/annotation/encoded_annotation.rs | 11 +++ androscalpel_serializer/src/annotation/mod.rs | 20 ++++ androscalpel_serializer/src/value.rs | 95 ++++++++----------- 10 files changed, 164 insertions(+), 117 deletions(-) diff --git a/androscalpel/src/annotation.rs b/androscalpel/src/annotation.rs index 01bf49d..5fc273c 100644 --- a/androscalpel/src/annotation.rs +++ b/androscalpel/src/annotation.rs @@ -5,18 +5,14 @@ use std::collections::HashMap; use crate::{dex_id::IdType, value::DexValue, DexString}; -/// An annotation. +/// Annotation with a visibility #[pyclass] #[derive(Debug, Clone)] -pub struct Annotation { - // TODO: check the relation between type and encoded_value. - /// The type of the annotation. - #[pyo3(get, set)] - pub type_: IdType, +pub struct DexAnnotationItem { // TODO: the get/set will probably be wonky on the python side when edditing - /// The annotation elements. + /// The actual annotation #[pyo3(get, set)] - pub elements: HashMap, // TODO: check MemberName syntax? + pub annotation: DexAnnotation, // TODO: enforce exclusivity /// If the annotation visibility is set to build #[pyo3(get, set)] @@ -30,12 +26,11 @@ pub struct Annotation { } #[pymethods] -impl Annotation { +impl DexAnnotationItem { #[new] - pub fn new(type_: IdType, elements: HashMap) -> Self { + pub fn new(annotation: DexAnnotation) -> Self { Self { - type_, - elements, + annotation, visibility_build: false, visibility_runtime: false, visibility_system: false, @@ -47,7 +42,6 @@ impl Annotation { } pub fn __repr__(&self) -> String { - let type_ = self.type_.__str__(); let visibility = if !(self.visibility_build || self.visibility_runtime || self.visibility_system) { "none".into() @@ -64,11 +58,43 @@ impl Annotation { } visibility }; + let annotation = self.annotation.__repr__(); + format!("AnnotationItem(visibility: {visibility}, {annotation})") + } +} + +/// An annotation. +#[pyclass] +#[derive(Debug, Clone)] +pub struct DexAnnotation { + // TODO: check the relation between type and encoded_value. + /// The type of the annotation. + #[pyo3(get, set)] + pub type_: IdType, + // TODO: the get/set will probably be wonky on the python side when edditing + /// The annotation elements. + #[pyo3(get, set)] + pub elements: HashMap, // TODO: check MemberName syntax? +} + +#[pymethods] +impl DexAnnotation { + #[new] + pub fn new(type_: IdType, elements: HashMap) -> Self { + Self { type_, elements } + } + + pub fn __str__(&self) -> String { + self.__repr__() + } + + pub fn __repr__(&self) -> String { + let type_ = self.type_.__str__(); let mut elts: String = "{".into(); for (key, val) in self.elements.iter() { elts += &format!("{}: {}, ", key.__str__(), val.__str__()); } elts += "}"; - format!("Annotation({type_}, visibility: {visibility}, {elts})") + format!("Annotation({type_}, {elts})") } } diff --git a/androscalpel/src/apk.rs b/androscalpel/src/apk.rs index be7ae30..588bf34 100644 --- a/androscalpel/src/apk.rs +++ b/androscalpel/src/apk.rs @@ -94,7 +94,7 @@ impl Apk { let mut annotations = vec![]; if let Some(annotations_directory) = annotations_directory { if annotations_directory.class_annotations_off != 0 { - annotations = Self::get_annotations_from_annotation_set_off( + annotations = Self::get_annotation_items_from_annotation_set_off( annotations_directory.class_annotations_off, dex, )?; @@ -164,10 +164,11 @@ impl Apk { )) } - pub fn get_annotations_from_annotation_set_off( + /// Return a [`Vec`] for the offset of an [`AnnotationSet`]. + pub fn get_annotation_items_from_annotation_set_off( annotations_set_off: u32, dex: &DexFileReader, - ) -> Result> { + ) -> Result> { let mut annotations = vec![]; for annotation_off in dex .get_struct_at_offset::(annotations_set_off)? @@ -181,16 +182,9 @@ impl Apk { AnnotationVisibility::Runtime => (false, true, false), AnnotationVisibility::System => (false, false, true), }; - let type_ = Self::get_id_type_from_idx(item.annotation.type_idx.0 as usize, dex)?; - let mut elements = HashMap::new(); - for elt in item.annotation.elements { - let name: DexString = dex.get_string(elt.name_idx.0)?.into(); - let value = Self::encoded_value_to_dex_value(&elt.value, dex)?; - elements.insert(name, value); - } - annotations.push(Annotation { - type_, - elements, + let annotation = Self::get_annotations_from_encoded_annotation(&item.annotation, dex)?; + annotations.push(DexAnnotationItem { + annotation, visibility_build, visibility_runtime, visibility_system, @@ -199,6 +193,21 @@ impl Apk { Ok(annotations) } + /// Return a [`DexAnnotation`] from [`EncodedAnnotation`] + pub fn get_annotations_from_encoded_annotation( + encoded_annotation: &EncodedAnnotation, + dex: &DexFileReader, + ) -> Result { + let type_ = Self::get_id_type_from_idx(encoded_annotation.type_idx.0 as usize, dex)?; + let mut elements = HashMap::new(); + for elt in &encoded_annotation.elements { + let name: DexString = dex.get_string(elt.name_idx.0)?.into(); + let value = Self::encoded_value_to_dex_value(&elt.value, dex)?; + elements.insert(name, value); + } + Ok(DexAnnotation { type_, elements }) + } + /// Return a [`IdMethodType`] from its idx. pub fn get_id_method_type_from_idx(idx: usize, dex: &DexFileReader) -> Result { let proto = dex.get_proto_id(idx)?; @@ -340,7 +349,9 @@ impl Apk { .map(|val| Self::encoded_value_to_dex_value(val, dex)) .collect::>()?, ))), - EncodedValue::Annotation(_val) => todo!(), //Ok(DexValue::Annotation(DexAnnotation(*val))), + EncodedValue::Annotation(val) => Ok(DexValue::Annotation( + Self::get_annotations_from_encoded_annotation(val, dex)?, + )), EncodedValue::Null => Ok(DexValue::Null(DexNull)), EncodedValue::Boolean(val) => Ok(DexValue::Boolean(DexBoolean(*val))), } diff --git a/androscalpel/src/class.rs b/androscalpel/src/class.rs index ef46c73..abc7b8f 100644 --- a/androscalpel/src/class.rs +++ b/androscalpel/src/class.rs @@ -2,7 +2,7 @@ use pyo3::prelude::*; -use crate::{Annotation, DexString, Field, Method}; +use crate::{DexAnnotationItem, DexString, Field, Method}; /// Represent an apk #[pyclass] @@ -61,7 +61,11 @@ pub struct Class { pub virtual_methods: Vec, // Do we need to distinguish direct and virtual (all the other) methods? // Maybe overlapping descriptor (same name, class and proto?) - pub annotations: Vec, + /// The annotation related to this class (note: this does not include the + /// methods/field/parameters annotations, they are stored in the methods and fields + /// structutres) + #[pyo3(get, set)] + pub annotations: Vec, // TODO: mix annotation data to fields / methods / class to make it more practicle } diff --git a/androscalpel/src/dex_id.rs b/androscalpel/src/dex_id.rs index 3aaefb0..480229c 100644 --- a/androscalpel/src/dex_id.rs +++ b/androscalpel/src/dex_id.rs @@ -418,26 +418,3 @@ impl IdEnum { format!("DexEnum({})", self.__str__()) } } - -#[pyclass] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct IdAnnotation; -#[pymethods] -impl IdAnnotation { - #[new] - pub fn _new() -> Self { - Self - } - - pub fn get_value(&self) { - todo!() - } - - pub fn __str__(&self) -> String { - self.__repr__() - } - - pub fn __repr__(&self) -> String { - "DexAnnotation".into() - } -} diff --git a/androscalpel/src/lib.rs b/androscalpel/src/lib.rs index 895364f..318a5d7 100644 --- a/androscalpel/src/lib.rs +++ b/androscalpel/src/lib.rs @@ -1,3 +1,6 @@ +use std::collections::hash_map::DefaultHasher; +use std::hash::{Hash, Hasher}; + use anyhow::Result; use pyo3::class::basic::CompareOp; @@ -65,6 +68,13 @@ impl From for DexString { } } +impl Hash for DexString { + fn hash(&self, state: &mut H) { + self.get_utf16_size().hash(state); + self.get_bytes().hash(state); + } +} + #[pymethods] impl DexString { #[new] @@ -99,12 +109,11 @@ impl DexString { pub fn __repr__(&self) -> String { self.into() } -} -impl std::hash::Hash for DexString { - fn hash(&self, state: &mut H) { - self.get_utf16_size().hash(state); - self.get_bytes().hash(state); + fn __hash__(&self) -> u64 { + let mut hasher = DefaultHasher::new(); + self.hash(&mut hasher); + hasher.finish() } } @@ -139,9 +148,9 @@ fn androscalpel(_py: Python, m: &PyModule) -> PyResult<()> { m.add_class::()?; m.add_class::()?; - m.add_class::()?; + m.add_class::()?; + m.add_class::()?; m.add_class::()?; - m.add_class::()?; m.add_class::()?; m.add_class::()?; m.add_class::()?; diff --git a/androscalpel/src/scalar.rs b/androscalpel/src/scalar.rs index ac602a2..db07b8b 100644 --- a/androscalpel/src/scalar.rs +++ b/androscalpel/src/scalar.rs @@ -259,6 +259,6 @@ impl DexArray { } pub fn __repr__(&self) -> String { - "DexArray()".into() + "DexArray(...)".into() } } diff --git a/androscalpel/src/value.rs b/androscalpel/src/value.rs index f905d0b..aa0e969 100644 --- a/androscalpel/src/value.rs +++ b/androscalpel/src/value.rs @@ -3,7 +3,7 @@ use pyo3::exceptions::PyTypeError; use pyo3::prelude::*; -use crate::{dex_id::*, scalar::*, DexString, MethodHandle}; +use crate::{dex_id::*, scalar::*, DexAnnotation, DexString, MethodHandle}; #[derive(Debug, Clone)] pub enum DexValue { @@ -22,7 +22,7 @@ pub enum DexValue { Method(IdMethod), Enum(IdEnum), Array(DexArray), - Annotation(IdAnnotation), + Annotation(DexAnnotation), Null(DexNull), Boolean(DexBoolean), } @@ -55,7 +55,7 @@ impl<'source> FromPyObject<'source> for DexValue { Ok(Self::Enum(val)) } else if let Ok(val) = DexArray::extract(ob) { Ok(Self::Array(val)) - } else if let Ok(val) = IdAnnotation::extract(ob) { + } else if let Ok(val) = DexAnnotation::extract(ob) { Ok(Self::Annotation(val)) } else if let Ok(val) = DexNull::extract(ob) { Ok(Self::Null(val)) diff --git a/androscalpel_serializer/src/annotation/encoded_annotation.rs b/androscalpel_serializer/src/annotation/encoded_annotation.rs index 5763da1..e43de91 100644 --- a/androscalpel_serializer/src/annotation/encoded_annotation.rs +++ b/androscalpel_serializer/src/annotation/encoded_annotation.rs @@ -87,6 +87,7 @@ mod test { 0xbe, 0x37, 0x01, 0xa8, 0x9f, 0x03, 0x1d, 0xf6, 0x33, 0x01, 0xd3, 0xe8, 0x02, 0x3f, ]; const ENCODED_ANNOTATION_RAW_2: &[u8] = &[0xf6, 0x33, 0x01, 0xd3, 0xe8, 0x02, 0x3f]; + const ENCODED_ANNOTATION_RAW_3: &[u8] = &[0xbf, 0x37, 0x01, 0xa8, 0x9f, 0x03, 0x38, 0x38, 0x02]; const ANNOTATION_ELEMENT_RAW: &[u8] = &[ 0xa8, 0x9f, 0x03, 0x1d, 0xf6, 0x33, 0x01, 0xd3, 0xe8, 0x02, 0x3f, ]; @@ -94,6 +95,16 @@ mod test { #[test] fn deserialize_encoded_annotation() { + assert_eq!( + EncodedAnnotation::deserialize_from_slice(ENCODED_ANNOTATION_RAW_3).unwrap(), + EncodedAnnotation { + type_idx: Uleb128(7103), + elements: vec![AnnotationElement { + name_idx: Uleb128(53160), + value: EncodedValue::Type(0x0238) + }], + } + ); assert_eq!( EncodedAnnotation::deserialize_from_slice(ENCODED_ANNOTATION_RAW_2).unwrap(), EncodedAnnotation { diff --git a/androscalpel_serializer/src/annotation/mod.rs b/androscalpel_serializer/src/annotation/mod.rs index 96e8fae..5992cfe 100644 --- a/androscalpel_serializer/src/annotation/mod.rs +++ b/androscalpel_serializer/src/annotation/mod.rs @@ -241,6 +241,7 @@ mod test { const ANNOTATION_ITEM: &[u8] = &[ 0x02, 0xbe, 0x37, 0x01, 0xa8, 0x9f, 0x03, 0x1d, 0xf6, 0x33, 0x01, 0xd3, 0xe8, 0x02, 0x3f, ]; + const ANNOTATION_ITEM_2: &[u8] = &[0x02, 0xbf, 0x37, 0x01, 0xa8, 0x9f, 0x03, 0x38, 0x38, 0x02]; #[test] fn deserialize_annotation_item() { @@ -252,6 +253,14 @@ mod test { .unwrap(), } ); + assert_eq!( + AnnotationItem::deserialize_from_slice(ANNOTATION_ITEM_2).unwrap(), + AnnotationItem { + visibility: AnnotationVisibility::System, + annotation: EncodedAnnotation::deserialize_from_slice(&ANNOTATION_ITEM_2[1..]) + .unwrap(), + } + ); } #[test] @@ -267,5 +276,16 @@ mod test { .unwrap() .as_slice() ); + assert_eq!( + ANNOTATION_ITEM_2, + AnnotationItem { + visibility: AnnotationVisibility::System, + annotation: EncodedAnnotation::deserialize_from_slice(&ANNOTATION_ITEM_2[1..]) + .unwrap(), + } + .serialize_to_vec() + .unwrap() + .as_slice() + ); } } diff --git a/androscalpel_serializer/src/value.rs b/androscalpel_serializer/src/value.rs index 87c27a7..759cf04 100644 --- a/androscalpel_serializer/src/value.rs +++ b/androscalpel_serializer/src/value.rs @@ -104,7 +104,7 @@ impl Serializable for EncodedValue { } Self::Short(val) => { let size = self.size(); - let bytes: [u8; 2] = val.to_be_bytes(); + let bytes: [u8; 2] = val.to_le_bytes(); output .write_all(&[((size as u8 - 2) << 5) | VALUE_SHORT.0]) .map_err(|err| { @@ -112,7 +112,7 @@ impl Serializable for EncodedValue { "Failed to write serialized Short to output: {err}" )) })?; - output.write_all(&bytes[(2 - size + 1)..]).map_err(|err| { + output.write_all(&bytes[..(size - 1)]).map_err(|err| { Error::SerializationError(format!( "Failed to write serialized Short to output: {err}" )) @@ -121,7 +121,7 @@ impl Serializable for EncodedValue { } Self::Char(val) => { let size = self.size(); - let bytes: [u8; 2] = val.to_be_bytes(); + let bytes: [u8; 2] = val.to_le_bytes(); output .write_all(&[((size as u8 - 2) << 5) | VALUE_CHAR.0]) .map_err(|err| { @@ -129,7 +129,7 @@ impl Serializable for EncodedValue { "Failed to write serialized Char to output: {err}" )) })?; - output.write_all(&bytes[(2 - size + 1)..]).map_err(|err| { + output.write_all(&bytes[..(size - 1)]).map_err(|err| { Error::SerializationError(format!( "Failed to write serialized Char to output: {err}" )) @@ -138,7 +138,7 @@ impl Serializable for EncodedValue { } Self::Int(val) => { let size = self.size(); - let bytes: [u8; 4] = val.to_be_bytes(); + let bytes: [u8; 4] = val.to_le_bytes(); output .write_all(&[((size as u8 - 2) << 5) | VALUE_INT.0]) .map_err(|err| { @@ -146,7 +146,7 @@ impl Serializable for EncodedValue { "Failed to write serialized Int to output: {err}" )) })?; - output.write_all(&bytes[(2 - size + 1)..]).map_err(|err| { + output.write_all(&bytes[..(size - 1)]).map_err(|err| { Error::SerializationError(format!( "Failed to write serialized Int to output: {err}" )) @@ -155,7 +155,7 @@ impl Serializable for EncodedValue { } Self::Long(val) => { let size = self.size(); - let bytes: [u8; 8] = val.to_be_bytes(); + let bytes: [u8; 8] = val.to_le_bytes(); output .write_all(&[((size as u8 - 2) << 5) | VALUE_LONG.0]) .map_err(|err| { @@ -163,7 +163,7 @@ impl Serializable for EncodedValue { "Failed to write serialized Long to output: {err}" )) })?; - output.write_all(&bytes[(2 - size + 1)..]).map_err(|err| { + output.write_all(&bytes[..(size - 1)]).map_err(|err| { Error::SerializationError(format!( "Failed to write serialized Long to output: {err}" )) @@ -172,7 +172,7 @@ impl Serializable for EncodedValue { } Self::Float(val) => { let size = self.size(); - let bytes = val.to_be_bytes(); + let bytes = val.to_le_bytes(); // TODO: check LE/BE output .write_all(&[((size as u8 - 2) << 5) | VALUE_FLOAT.0]) .map_err(|err| { @@ -189,7 +189,7 @@ impl Serializable for EncodedValue { } Self::Double(val) => { let size = self.size(); - let bytes = val.to_be_bytes(); + let bytes = val.to_le_bytes(); // TODO: check LE/BE output .write_all(&[((size as u8 - 2) << 5) | VALUE_DOUBLE.0]) .map_err(|err| { @@ -282,20 +282,19 @@ impl Serializable for EncodedValue { } else { let mut buffer = [0x00u8; 2]; let size = (arg + 1) as usize; - let first_byte = 2 - size; - input.read_exact(&mut buffer[first_byte..]).map_err(|_| { + input.read_exact(&mut buffer[..size]).map_err(|_| { Error::InputTooSmall( "Failed to read all bytes for the EncodedValue (Short) from the input" .into(), ) })?; // Sign extention - if (buffer[first_byte] & 0b1000_0000) != 0 { - for b in buffer.iter_mut().take(first_byte - 1) { + if (buffer[size - 1] & 0b1000_0000) != 0 { + for b in buffer.iter_mut().take(size) { *b = 0xff; } } - Ok(Self::Short(i16::from_be_bytes(buffer))) + Ok(Self::Short(i16::from_le_bytes(buffer))) } } VALUE_CHAR => { @@ -306,14 +305,13 @@ impl Serializable for EncodedValue { } else { let mut buffer = [0x00u8; 2]; let size = (arg + 1) as usize; - let first_byte = 2 - size; - input.read_exact(&mut buffer[first_byte..]).map_err(|_| { + input.read_exact(&mut buffer[..size]).map_err(|_| { Error::InputTooSmall( "Failed to read all bytes for the EncodedValue (Char) from the input" .into(), ) })?; - Ok(Self::Char(u16::from_be_bytes(buffer))) + Ok(Self::Char(u16::from_le_bytes(buffer))) } } VALUE_INT => { @@ -324,20 +322,19 @@ impl Serializable for EncodedValue { } else { let mut buffer = [0x00u8; 4]; let size = (arg + 1) as usize; - let first_byte = 4 - size; - input.read_exact(&mut buffer[first_byte..]).map_err(|_| { + input.read_exact(&mut buffer[..size]).map_err(|_| { Error::InputTooSmall( "Failed to read all bytes for the EncodedValue (Int) from the input" .into(), ) })?; // Sign extention - if (buffer[first_byte] & 0b1000_0000) != 0 { - for b in buffer.iter_mut().take(first_byte - 1) { + if (buffer[size - 1] & 0b1000_0000) != 0 { + for b in buffer.iter_mut().take(size) { *b = 0xff; } } - Ok(Self::Int(i32::from_be_bytes(buffer))) + Ok(Self::Int(i32::from_le_bytes(buffer))) } } VALUE_LONG => { @@ -348,20 +345,19 @@ impl Serializable for EncodedValue { } else { let mut buffer = [0x00u8; 8]; let size = (arg + 1) as usize; - let first_byte = 8 - size; - input.read_exact(&mut buffer[first_byte..]).map_err(|_| { + input.read_exact(&mut buffer[..size]).map_err(|_| { Error::InputTooSmall( "Failed to read all bytes for the EncodedValue (Long) from the input" .into(), ) })?; // Sign extention - if (buffer[first_byte] & 0b1000_0000) != 0 { - for b in buffer.iter_mut().take(first_byte - 1) { + if (buffer[size - 1] & 0b1000_0000) != 0 { + for b in buffer.iter_mut().take(size) { *b = 0xff; } } - Ok(Self::Long(i64::from_be_bytes(buffer))) + Ok(Self::Long(i64::from_le_bytes(buffer))) } } VALUE_FLOAT => { @@ -378,7 +374,7 @@ impl Serializable for EncodedValue { .into(), ) })?; - Ok(Self::Float(f32::from_be_bytes(buffer))) + Ok(Self::Float(f32::from_le_bytes(buffer))) } } VALUE_DOUBLE => { @@ -395,7 +391,7 @@ impl Serializable for EncodedValue { .into(), ) })?; - Ok(Self::Double(f64::from_be_bytes(buffer))) + Ok(Self::Double(f64::from_le_bytes(buffer))) } } VALUE_METHOD_TYPE => { @@ -406,14 +402,13 @@ impl Serializable for EncodedValue { } else { let mut buffer = [0x00u8; 4]; let size = (arg + 1) as usize; - let first_byte = 4 - size; - input.read_exact(&mut buffer[first_byte..]).map_err(|_| { + input.read_exact(&mut buffer[..size]).map_err(|_| { Error::InputTooSmall( "Failed to read all bytes for the EncodedValue (MethodType) from the input" .into(), ) })?; - Ok(Self::MethodType(u32::from_be_bytes(buffer))) + Ok(Self::MethodType(u32::from_le_bytes(buffer))) } } VALUE_METHOD_HANDLE => { @@ -424,14 +419,13 @@ impl Serializable for EncodedValue { } else { let mut buffer = [0x00u8; 4]; let size = (arg + 1) as usize; - let first_byte = 4 - size; - input.read_exact(&mut buffer[first_byte..]).map_err(|_| { + input.read_exact(&mut buffer[..size]).map_err(|_| { Error::InputTooSmall( "Failed to read all bytes for the EncodedValue (MethodHandle) from the input" .into(), ) })?; - Ok(Self::MethodHandle(u32::from_be_bytes(buffer))) + Ok(Self::MethodHandle(u32::from_le_bytes(buffer))) } } VALUE_STRING => { @@ -442,14 +436,13 @@ impl Serializable for EncodedValue { } else { let mut buffer = [0x00u8; 4]; let size = (arg + 1) as usize; - let first_byte = 4 - size; - input.read_exact(&mut buffer[first_byte..]).map_err(|_| { + input.read_exact(&mut buffer[..size]).map_err(|_| { Error::InputTooSmall( "Failed to read all bytes for the EncodedValue (String) from the input" .into(), ) })?; - Ok(Self::String(u32::from_be_bytes(buffer))) + Ok(Self::String(u32::from_le_bytes(buffer))) } } VALUE_TYPE => { @@ -460,14 +453,13 @@ impl Serializable for EncodedValue { } else { let mut buffer = [0x00u8; 4]; let size = (arg + 1) as usize; - let first_byte = 4 - size; - input.read_exact(&mut buffer[first_byte..]).map_err(|_| { + input.read_exact(&mut buffer[..size]).map_err(|_| { Error::InputTooSmall( "Failed to read all bytes for the EncodedValue (Type) from the input" .into(), ) })?; - Ok(Self::Type(u32::from_be_bytes(buffer))) + Ok(Self::Type(u32::from_le_bytes(buffer))) } } VALUE_FIELD => { @@ -478,14 +470,13 @@ impl Serializable for EncodedValue { } else { let mut buffer = [0x00u8; 4]; let size = (arg + 1) as usize; - let first_byte = 4 - size; - input.read_exact(&mut buffer[first_byte..]).map_err(|_| { + input.read_exact(&mut buffer[..size]).map_err(|_| { Error::InputTooSmall( "Failed to read all bytes for the EncodedValue (Field) from the input" .into(), ) })?; - Ok(Self::Field(u32::from_be_bytes(buffer))) + Ok(Self::Field(u32::from_le_bytes(buffer))) } } VALUE_METHOD => { @@ -496,14 +487,13 @@ impl Serializable for EncodedValue { } else { let mut buffer = [0x00u8; 4]; let size = (arg + 1) as usize; - let first_byte = 4 - size; - input.read_exact(&mut buffer[first_byte..]).map_err(|_| { + input.read_exact(&mut buffer[..size]).map_err(|_| { Error::InputTooSmall( "Failed to read all bytes for the EncodedValue (Method) from the input" .into(), ) })?; - Ok(Self::Method(u32::from_be_bytes(buffer))) + Ok(Self::Method(u32::from_le_bytes(buffer))) } } VALUE_ENUM => { @@ -514,14 +504,13 @@ impl Serializable for EncodedValue { } else { let mut buffer = [0x00u8; 4]; let size = (arg + 1) as usize; - let first_byte = 4 - size; - input.read_exact(&mut buffer[first_byte..]).map_err(|_| { + input.read_exact(&mut buffer[..size]).map_err(|_| { Error::InputTooSmall( "Failed to read all bytes for the EncodedValue (Enum) from the input" .into(), ) })?; - Ok(Self::Enum(u32::from_be_bytes(buffer))) + Ok(Self::Enum(u32::from_le_bytes(buffer))) } } VALUE_ARRAY => { @@ -643,8 +632,8 @@ impl Serializable for Idx { fn serialize(&self, output: &mut dyn Write) -> Result<()> { let Idx(idx, ValueType(vt)) = self; let size = self.size() - 2; - let bytes: [u8; 4] = idx.to_be_bytes(); - let vec = &bytes[(4 - size + 1)..]; + let bytes: [u8; 4] = idx.to_le_bytes(); + let vec = &bytes[..(size + 1)]; output .write_all(&[((size as u8) << 5) | vt]) .map_err(|err| {