diff --git a/pytests/test_dag_cbor.py b/pytests/test_dag_cbor.py index d0f7ee5..e8a73d7 100644 --- a/pytests/test_dag_cbor.py +++ b/pytests/test_dag_cbor.py @@ -227,3 +227,22 @@ def test_dag_cbor_decode_negative_infinity_f32_error() -> None: libipld.decode_dag_cbor(bytes.fromhex('faff800000')) assert 'number out of range for f32' in str(exc_info.value).lower() + + +def test_dag_cbor_decode_cbor_sequence_error() -> None: + # 0000 - two CBOR zeros (CBOR sequence), invalid in DAG-CBOR + with pytest.raises(ValueError) as exc_info: + libipld.decode_dag_cbor(bytes.fromhex('0000')) + + assert 'multiple objects' in str(exc_info.value).lower() + + +def test_decode_dag_cbor_multi() -> None: + # 0000 - two CBOR zeros (CBOR sequence), valid only for decode_dag_cbor_multi + dag_cbor = bytes.fromhex('0000') + decoded = libipld.decode_dag_cbor_multi(dag_cbor) + + assert isinstance(decoded, list) + assert len(decoded) == 2 + assert decoded[0] == 0 + assert decoded[1] == 0 diff --git a/src/lib.rs b/src/lib.rs index 32248ae..1d90a91 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -481,9 +481,19 @@ pub fn decode_car<'py>(py: Python<'py>, data: &[u8]) -> PyResult<(PyObject, Boun #[pyfunction] pub fn decode_dag_cbor(py: Python, data: &[u8]) -> PyResult { - let py_object = decode_dag_cbor_to_pyobject(py, &mut BufReader::new(Cursor::new(data)), 0); + let mut reader = BufReader::new(Cursor::new(data)); + let py_object = decode_dag_cbor_to_pyobject(py, &mut reader, 0); if let Ok(py_object) = py_object { - Ok(py_object) + // check for any remaining data in the reader + let mut buf = [0u8; 1]; + match reader.read(&mut buf) { + Ok(0) => Ok(py_object), // EOF + Err(_) => Ok(py_object), // EOF + Ok(_) => Err(get_err( + "Failed to decode DAG-CBOR", + "Invalid DAG-CBOR: contains multiple objects (CBOR sequence)".to_string() + )), + } } else { let err = get_err( "Failed to decode DAG-CBOR",