From 402fd2ea2f8c56beba866fd7e640e98249dc57de Mon Sep 17 00:00:00 2001 From: "Ilya (Marshal)" Date: Tue, 24 Jun 2025 12:48:31 +0200 Subject: [PATCH] Fix bignum encoding --- pytests/test_dag_cbor.py | 18 ++++++++++++++++++ src/lib.rs | 8 ++++++++ 2 files changed, 26 insertions(+) diff --git a/pytests/test_dag_cbor.py b/pytests/test_dag_cbor.py index e8a73d7..fee7708 100644 --- a/pytests/test_dag_cbor.py +++ b/pytests/test_dag_cbor.py @@ -246,3 +246,21 @@ def test_decode_dag_cbor_multi() -> None: assert len(decoded) == 2 assert decoded[0] == 0 assert decoded[1] == 0 + + +def test_encode_tag_positive_bignum() -> None: + bignum = 18446744073709551616 + + with pytest.raises(ValueError) as exc_info: + libipld.encode_dag_cbor(bignum) + + assert 'number out of range' in str(exc_info.value).lower() + + +def test_encode_tag_negative_bignum() -> None: + bignum = -18446744073709551617 + + with pytest.raises(ValueError) as exc_info: + libipld.encode_dag_cbor(bignum) + + assert 'number out of range' in str(exc_info.value).lower() diff --git a/src/lib.rs b/src/lib.rs index 1d90a91..04f83b3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -254,8 +254,16 @@ fn encode_dag_cbor_from_pyobject<'py, W: Write>( let i: i128 = obj.extract()?; if i.is_negative() { + if -(i + 1) > u64::MAX as i128 { + return Err(anyhow!("Number out of range")); + } + encode::write_u64(w, MajorKind::NegativeInt, -(i + 1) as u64)? } else { + if i > u64::MAX as i128 { + return Err(anyhow!("Number out of range")); + } + encode::write_u64(w, MajorKind::UnsignedInt, i as u64)? }