Skip to content

Commit f2118cb

Browse files
authored
Merge pull request #737 from Emurgo/evgenii/pointer_adress_deser_fix
Pointer adress deser fix
2 parents 0ad8175 + a77c006 commit f2118cb

File tree

6 files changed

+30
-15
lines changed

6 files changed

+30
-15
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "cardano-serialization-lib",
3-
"version": "15.0.0",
3+
"version": "15.0.1",
44
"description": "(De)serialization functions for the Cardano blockchain along with related utility functions",
55
"scripts": {
66
"publish-all:prod": "node scripts/build-helper.js publish-all --env prod",

rust/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "cardano-serialization-lib"
3-
version = "15.0.0"
3+
version = "15.0.1"
44
edition = "2018"
55
authors = ["EMURGO"]
66
license = "MIT"

rust/json-gen/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/src/protocol_types/address.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,19 @@ use ed25519_bip32::XPub;
55

66
// returns (Number represented, bytes read) if valid encoding
77
// or None if decoding prematurely finished
8-
pub(crate) fn variable_nat_decode(bytes: &[u8]) -> Option<(u64, usize)> {
8+
pub(crate) fn variable_nat_decode(bytes: &[u8], fallback_to_max: bool) -> Option<(u64, usize)> {
99
let mut output = 0u128;
1010
let mut bytes_read = 0;
1111
for byte in bytes {
12-
output = (output << 7) | (byte & 0x7F) as u128;
13-
if output > u64::MAX.into() {
14-
return None;
12+
if output < u64::MAX.into() || !fallback_to_max {
13+
output = (output << 7) | (byte & 0x7F) as u128;
14+
}
15+
//Since Conway era forbids pointer addresses, technically such large numbers would not make sense on mainnet
16+
if output > u64::MAX.into(){
17+
if !fallback_to_max {
18+
return None;
19+
}
20+
output = u64::MAX.into();
1521
}
1622
bytes_read += 1;
1723
if (byte & 0x80) == 0 {
@@ -399,7 +405,10 @@ impl Address {
399405
fn from_bytes_impl_unsafe(data: &[u8]) -> Address {
400406
match Self::from_bytes_internal_impl(data, true) {
401407
Ok(addr) => addr,
402-
Err(_) => Address(AddrType::Malformed(MalformedAddress(data.to_vec())))
408+
Err(err) => {
409+
println!("Address deserialization error: {:?}", err);
410+
return Address(AddrType::Malformed(MalformedAddress(data.to_vec())));
411+
}
403412
}
404413
}
405414

@@ -540,19 +549,19 @@ impl Address {
540549

541550
fn decode_pointer(data: &[u8]) -> Result<(Pointer, usize), DeserializeError> {
542551
let mut offset = 0;
543-
let (slot, slot_bytes) = variable_nat_decode(&data).ok_or(DeserializeError::new(
552+
let (slot, slot_bytes) = variable_nat_decode(&data, true).ok_or(DeserializeError::new(
544553
"Address.Pointer.slot",
545554
DeserializeFailure::VariableLenNatDecodeFailed,
546555
))?;
547556
offset += slot_bytes;
548557
let (tx_index, tx_bytes) =
549-
variable_nat_decode(&data[offset..]).ok_or(DeserializeError::new(
558+
variable_nat_decode(&data[offset..], true).ok_or(DeserializeError::new(
550559
"Address.Pointer.tx_index",
551560
DeserializeFailure::VariableLenNatDecodeFailed,
552561
))?;
553562
offset += tx_bytes;
554563
let (cert_index, cert_bytes) =
555-
variable_nat_decode(&data[offset..]).ok_or(DeserializeError::new(
564+
variable_nat_decode(&data[offset..], true).ok_or(DeserializeError::new(
556565
"Address.Pointer.cert_index",
557566
DeserializeFailure::VariableLenNatDecodeFailed,
558567
))?;

rust/src/tests/address.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,21 @@ fn variable_nat_encoding() {
77
let cases = [0u64, 127u64, 128u64, 255u64, 256275757658493284u64];
88
for case in cases.iter() {
99
let encoded = variable_nat_encode(*case);
10-
let decoded = variable_nat_decode(&encoded).unwrap().0;
10+
let decoded = variable_nat_decode(&encoded, true).unwrap().0;
1111
assert_eq!(*case, decoded);
1212
}
1313
}
1414

1515
#[test]
1616
fn variable_nat_decode_too_big() {
1717
let too_big = [129, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127];
18-
assert_eq!(None, variable_nat_decode(&too_big));
18+
assert_eq!(None, variable_nat_decode(&too_big, false));
19+
}
20+
21+
#[test]
22+
fn variable_nat_decode_too_big_fallback() {
23+
let too_big = [129, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127];
24+
assert_eq!(Some((u64::MAX, 11usize)), variable_nat_decode(&too_big, true));
1925
}
2026

2127
#[test]

0 commit comments

Comments
 (0)