diff --git a/pytests/test_dag_cbor.py b/pytests/test_dag_cbor.py index d589d76..d0f7ee5 100644 --- a/pytests/test_dag_cbor.py +++ b/pytests/test_dag_cbor.py @@ -179,3 +179,51 @@ def test_dab_cbor_encode_map_int_key() -> None: libipld.encode_dag_cbor(obj) assert 'Map keys must be strings' in str(exc_info.value) + + +def test_dag_cbor_decode_nan_f64_error() -> None: + # fb7ff8000000000000 - IEEE 754 double precision NaN + with pytest.raises(ValueError) as exc_info: + libipld.decode_dag_cbor(bytes.fromhex('fb7ff8000000000000')) + + assert 'number out of range for f64' in str(exc_info.value).lower() + + +def test_dag_cbor_decode_positive_infinity_f64_error() -> None: + # fb7ff0000000000000 - IEEE 754 double precision positive infinity + with pytest.raises(ValueError) as exc_info: + libipld.decode_dag_cbor(bytes.fromhex('fb7ff0000000000000')) + + assert 'number out of range for f64' in str(exc_info.value).lower() + + +def test_dag_cbor_decode_negative_infinity_f64_error() -> None: + # fbfff0000000000000 - IEEE 754 double precision negative infinity + with pytest.raises(ValueError) as exc_info: + libipld.decode_dag_cbor(bytes.fromhex('fbfff0000000000000')) + + assert 'number out of range for f64' in str(exc_info.value).lower() + + +def test_dag_cbor_decode_nan_f32_error() -> None: + # fa7fc00000 - IEEE 754 single precision NaN + with pytest.raises(ValueError) as exc_info: + libipld.decode_dag_cbor(bytes.fromhex('fa7fc00000')) + + assert 'number out of range for f32' in str(exc_info.value).lower() + + +def test_dag_cbor_decode_positive_infinity_f32_error() -> None: + # fa7f800000 - IEEE 754 single precision positive infinity + with pytest.raises(ValueError) as exc_info: + libipld.decode_dag_cbor(bytes.fromhex('fa7f800000')) + + assert 'number out of range for f32' in str(exc_info.value).lower() + + +def test_dag_cbor_decode_negative_infinity_f32_error() -> None: + # faff800000 - IEEE 754 single precision negative infinity + with pytest.raises(ValueError) as exc_info: + libipld.decode_dag_cbor(bytes.fromhex('faff800000')) + + assert 'number out of range for f32' in str(exc_info.value).lower() diff --git a/src/lib.rs b/src/lib.rs index 5b4c383..140dae6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -199,8 +199,20 @@ fn decode_dag_cbor_to_pyobject( cbor::FALSE => false.into_pyobject(py)?.into_any().unbind(), cbor::TRUE => true.into_pyobject(py)?.into_any().unbind(), cbor::NULL => py.None(), - cbor::F32 => decode::read_f32(r)?.into_pyobject(py)?.into(), - cbor::F64 => decode::read_f64(r)?.into_pyobject(py)?.into(), + cbor::F32 => { + let value = decode::read_f32(r)?; + if !value.is_finite() { + return Err(anyhow!("Number out of range for f32 (NaNs are forbidden)".to_string())); + } + value.into_pyobject(py)?.into() + }, + cbor::F64 => { + let value = decode::read_f64(r)?; + if !value.is_finite() { + return Err(anyhow!("Number out of range for f64 (NaNs are forbidden)".to_string())); + } + value.into_pyobject(py)?.into() + }, _ => return Err(anyhow!("Unsupported major type".to_string())), }, })