implement annotation

This commit is contained in:
Jean-Marie Mineau 2023-08-25 11:26:16 +02:00
parent 1b503549b3
commit d5b8222491
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2
3 changed files with 65 additions and 14 deletions

View file

@ -1,18 +1,69 @@
use crate::{ReadSeek, Result, Serializable}; use crate::{EncodedValue, Error, ReadSeek, Result, Serializable, Uleb128};
use std::io::Write; use std::io::Write;
// To derive Serializable
use crate as androscalpel_serializer;
/// Encoded Annotation https://source.android.com/docs/core/runtime/dex-format#encoded-annotation
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct EncodedAnnotation; pub struct EncodedAnnotation {
/// Type of the annotation. This must be a class (not array or primitive) type.
pub type_idx: Uleb128, // TODO: check it's a class
//pub size: Uleb128,
pub elements: Vec<AnnotationElement>,
}
impl EncodedAnnotation {
/// Return the size field
pub fn size_field(&self) -> Uleb128 {
Uleb128(self.elements.len() as u32)
}
}
/// Annotation: https://source.android.com/docs/core/runtime/dex-format#annotation-element
#[derive(Serializable, Debug, Clone, PartialEq, Eq)]
pub struct AnnotationElement {
pub name_idx: Uleb128,
pub value: EncodedValue,
}
impl Serializable for EncodedAnnotation { impl Serializable for EncodedAnnotation {
fn serialize(&self, _output: &mut dyn Write) -> Result<()> { fn serialize(&self, output: &mut dyn Write) -> Result<()> {
todo!() let Self { type_idx, elements } = self;
// Check if the element are sorted
if !elements.is_empty() {
let mut idx_0 = elements[0].name_idx;
for idx_1 in elements.iter().map(|elt| elt.name_idx).skip(1) {
if idx_0 > idx_1 {
return Err(Error::SerializationError(format!(
"Failed to serialize EncodedAnnotation: element must be sorted in increasing order by string_id index, found {idx_0:?} before {idx_1:?}"
)));
}
idx_0 = idx_1;
}
}
type_idx.serialize(output)?;
self.size_field().serialize(output)?;
for elt in elements {
elt.serialize(output)?;
}
Ok(())
} }
fn deserialize(_input: &mut dyn ReadSeek) -> Result<Self> { fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
todo!() let type_idx = Uleb128::deserialize(input)?;
let Uleb128(size) = Uleb128::deserialize(input)?;
let mut elements = vec![];
for _ in 0..size {
elements.push(AnnotationElement::deserialize(input)?);
}
Ok(Self { type_idx, elements })
} }
fn size(&self) -> usize { fn size(&self) -> usize {
todo!() self.type_idx.size()
+ self.size_field().size()
+ self.elements.iter().map(|val| val.size()).sum::<usize>()
} }
} }
// TODO: add tests

View file

@ -11,15 +11,15 @@ pub struct EncodedArray {
impl EncodedArray { impl EncodedArray {
/// Return the size field /// Return the size field
pub fn size(&self) -> Uleb128 { pub fn size_field(&self) -> Uleb128 {
Uleb128(self.values.len() as u32) Uleb128(self.values.len() as u32)
} }
} }
impl Serializable for EncodedArray { impl Serializable for EncodedArray {
fn serialize(&self, output: &mut dyn Write) -> Result<()> { fn serialize(&self, output: &mut dyn Write) -> Result<()> {
self.size().serialize(output)?; self.size_field().serialize(output)?;
for value in self.values { for value in &self.values {
value.serialize(output)?; value.serialize(output)?;
} }
Ok(()) Ok(())
@ -38,6 +38,6 @@ impl Serializable for EncodedArray {
} }
fn size(&self) -> usize { fn size(&self) -> usize {
self.size().size() + self.values.iter().map(|val| val.size()).sum::<usize>() self.size_field().size() + self.values.iter().map(|val| val.size()).sum::<usize>()
} }
} }

View file

@ -5,15 +5,15 @@ use std::io::Write;
use crate::{Error, ReadSeek, Result, Serializable}; use crate::{Error, ReadSeek, Result, Serializable};
/// Signed LEB128, variable-length /// Signed LEB128, variable-length
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Sleb128(pub i32); pub struct Sleb128(pub i32);
/// Unsigned LEB128, variable-length /// Unsigned LEB128, variable-length
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Uleb128(pub u32); pub struct Uleb128(pub u32);
/// Unsigned LEB128 plus 1, variable-length /// Unsigned LEB128 plus 1, variable-length
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Uleb128p1(pub u32); pub struct Uleb128p1(pub u32);
impl Sleb128 { impl Sleb128 {