fix sleb serializer

This commit is contained in:
Jean-Marie 'Histausse' Mineau 2024-02-06 19:37:12 +01:00
parent e4532f9e3c
commit fcfe2dc6e9
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2
5 changed files with 70 additions and 21 deletions

View file

@ -19,5 +19,5 @@ where
V: Deserialize<'de>, V: Deserialize<'de>,
{ {
let container: Vec<_> = serde::Deserialize::deserialize(des)?; let container: Vec<_> = serde::Deserialize::deserialize(des)?;
Ok(T::from_iter(container.into_iter())) Ok(T::from_iter(container))
} }

View file

@ -23,12 +23,10 @@ impl Sleb128 {
let mut bytes = vec![]; let mut bytes = vec![];
loop { loop {
let byte = val as u8 & 0b0111_1111; let byte = val as u8 & 0b0111_1111;
val /= 64; val >>= 7;
if val == 0 || val == -1 { if (val == 0 && (byte & 0b0100_0000) == 0) || (val == -1 && (byte & 0b0100_0000) != 0) {
bytes.push(byte); bytes.push(byte);
return bytes; return bytes;
} else {
val /= 2;
} }
bytes.push(byte | 0b1000_0000); bytes.push(byte | 0b1000_0000);
} }
@ -202,6 +200,7 @@ mod test {
assert_eq!(Sleb128(0).serialize_to_vec().unwrap(), vec![0x00u8]); assert_eq!(Sleb128(0).serialize_to_vec().unwrap(), vec![0x00u8]);
assert_eq!(Sleb128(1).serialize_to_vec().unwrap(), vec![0x01u8]); assert_eq!(Sleb128(1).serialize_to_vec().unwrap(), vec![0x01u8]);
assert_eq!(Sleb128(-1).serialize_to_vec().unwrap(), vec![0x7Fu8]); assert_eq!(Sleb128(-1).serialize_to_vec().unwrap(), vec![0x7Fu8]);
assert_eq!(Sleb128(-1551).serialize_to_vec().unwrap(), vec![0xf1, 0x73]);
assert_eq!( assert_eq!(
Sleb128(-128).serialize_to_vec().unwrap(), Sleb128(-128).serialize_to_vec().unwrap(),
vec![0x80u8, 0x7F] vec![0x80u8, 0x7F]
@ -222,6 +221,10 @@ mod test {
Sleb128::deserialize_from_slice(&[0x7Fu8]).unwrap(), Sleb128::deserialize_from_slice(&[0x7Fu8]).unwrap(),
Sleb128(-1) Sleb128(-1)
); );
assert_eq!(
Sleb128::deserialize_from_slice(&[0xf1, 0x73]).unwrap(),
Sleb128(-1551)
);
assert_eq!( assert_eq!(
Sleb128::deserialize_from_slice(&[0x80u8, 0x7Fu8]).unwrap(), Sleb128::deserialize_from_slice(&[0x80u8, 0x7Fu8]).unwrap(),
Sleb128(-128) Sleb128(-128)

View file

@ -44,9 +44,7 @@ impl Ord for StringDataItem {
impl PartialOrd for StringDataItem { impl PartialOrd for StringDataItem {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.data Some(self.cmp(other))
.partial_cmp(&other.data)
.map(|ord| ord.then(self.utf16_size.cmp(&other.utf16_size)))
} }
} }

View file

@ -92,3 +92,42 @@ impl Serializable for DebugInfoItem {
+ self.bytecode.size(DbgBytecode::EndSequence) + self.bytecode.size(DbgBytecode::EndSequence)
} }
} }
#[cfg(test)]
mod test {
use super::DbgBytecode::*;
use super::*;
#[test]
fn test_debug_reserialize() {
let debug = DebugInfoItem {
line_start: Uleb128(2902),
parameter_names: vec![],
bytecode: vec![
SpecialOpcode(14),
AdvanceLine {
line_diff: Sleb128(-1551),
},
AdvancePC {
addr_diff: Uleb128(51),
},
SpecialOpcode(14),
],
};
assert_eq!(
debug,
DebugInfoItem::deserialize_from_slice(&debug.serialize_to_vec().unwrap()).unwrap()
);
}
#[test]
fn test_advance_line_reserialize() {
let advance_line = AdvanceLine {
line_diff: Sleb128(-1551),
};
assert_eq!(
advance_line,
DbgBytecode::deserialize_from_slice(&advance_line.serialize_to_vec().unwrap()).unwrap()
);
}
}

35
test.py
View file

@ -106,12 +106,19 @@ def cmp(a, b, req=0):
cmp_other(a, b, req) cmp_other(a, b, req)
def nice_bool(b) -> str:
if b:
return "\033[32mTrue\033[0m"
else:
return "\033[31mFalse\033[0m"
def cmp_other(a, b, req=0): def cmp_other(a, b, req=0):
ident = " " * req ident = " " * req
for f in dir(a): for f in dir(a):
if getattr(getattr(a, f), "__call__", None) is None: if getattr(getattr(a, f), "__call__", None) is None:
eq = getattr(a, f) == getattr(b, f) eq = getattr(a, f) == getattr(b, f)
print(f"{f'{ident}{f}: ':<150}{eq}") print(f"{f'{ident}{f}: ':<150}{nice_bool(eq)}")
if not eq: if not eq:
cmp(getattr(a, f), getattr(b, f), req + 1) cmp(getattr(a, f), getattr(b, f), req + 1)
@ -124,7 +131,7 @@ def cmp_dict(a, b, req=0):
print(f"{ident}a.keys() != b.keys()") print(f"{ident}a.keys() != b.keys()")
for key in keys_a & keys_b: for key in keys_a & keys_b:
eq = a[key] == b[key] eq = a[key] == b[key]
print(f"{f'{ident}{str(key)}: ':<150}{eq}") print(f"{f'{ident}{str(key)}: ':<150}{nice_bool(eq)}")
if not eq: if not eq:
cmp(a[key], b[key], req + 1) cmp(a[key], b[key], req + 1)
@ -137,7 +144,7 @@ def cmp_list(a, b, req=0):
print(f"{ident}len(a) != len(b)") print(f"{ident}len(a) != len(b)")
for i in range(min(la, lb)): for i in range(min(la, lb)):
eq = a[i] == b[i] eq = a[i] == b[i]
print(f"{f'{ident}{str(i)}: ':<150}{eq}") print(f"{f'{ident}{str(i)}: ':<150}{nice_bool(eq)}")
if not eq: if not eq:
cmp(a[i], b[i], req + 1) cmp(a[i], b[i], req + 1)
@ -147,13 +154,15 @@ print(f"apk are equals: {apk_eq}")
if not apk_eq: if not apk_eq:
cmp(new_apk, apk) cmp(new_apk, apk)
mid = IdMethod( # Landroidx/constraintlayout/core/widgets/ConstraintWidget$1;.<clinit>()V
"setAction", # mid = IdMethod(
IdMethodType( # "<clinit>",
IdType("Landroidx/navigation/NavDeepLink$Builder;"), # IdMethodType(
[IdType("Ljava/lang/String;")], # IdType.void(),
), # [],
IdType("Landroidx/navigation/NavDeepLink$Builder;"), # ),
) # IdType("Landroidx/constraintlayout/core/widgets/ConstraintWidget$1;"),
m = apk.classes[mid.class_].virtual_methods[mid] # )
nm = new_apk.classes[mid.class_].virtual_methods[mid] # m = apk.classes[mid.class_].direct_methods[mid]
# nm = new_apk.classes[mid.class_].direct_methods[mid]
#