Skip to content

Commit

Permalink
Fix duplicated map keys check in decode_dag_cbor (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
MarshalX committed Mar 1, 2024
1 parent d404502 commit 4975730
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 3 deletions.
8 changes: 8 additions & 0 deletions pytests/test_dag_cbor.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ def _dag_cbor_roundtrip(benchmark, data) -> None:
assert obj == decoded, f'{obj} != {decoded}'


def test_dag_cbor_decode_duplicate_keys() -> None:
with pytest.raises(ValueError) as exc_info:
# {"abc": 1, "abc": 2}
libipld.decode_dag_cbor(bytes.fromhex('a263616263016361626302'))

assert 'Duplicate keys are not allowed' in str(exc_info.value)


@pytest.mark.parametrize('data', load_data_fixtures(_ROUNDTRIP_DATA_DIR), ids=lambda data: data[0])
def test_dag_cbor_encode(benchmark, data) -> None:
_dag_cbor_encode(benchmark, data)
Expand Down
10 changes: 7 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,21 @@ fn decode_dag_cbor_to_pyobject<R: Read + Seek>(py: Python, r: &mut R, deep: usiz
let len = decode_len(decode::read_uint(r, major)?)?;
let dict = PyDict::new(py);
for _ in 0..len {
// FIXME (MarshalX): we should raise on duplicate keys?
let key = decode_dag_cbor_to_pyobject(py, r, deep + 1)?;
let value = decode_dag_cbor_to_pyobject(py, r, deep + 1)?;

if dict.get_item(&key)?.is_some() {
return Err(anyhow::anyhow!("Duplicate keys are not allowed"));
}

dict.set_item(key, value).unwrap();
}
dict.into()
}
MajorKind::Tag => {
let value = decode::read_uint(r, major)?;
if value != 42 {
return Err(anyhow::anyhow!("non-42 tags are not supported"));
return Err(anyhow::anyhow!("Non-42 tags are not supported"));
}

decode::read_link(r)?.to_string().to_object(py)
Expand All @@ -100,7 +104,7 @@ fn decode_dag_cbor_to_pyobject<R: Read + Seek>(py: Python, r: &mut R, deep: usiz
cbor::NULL => py.None(),
cbor::F32 => (decode::read_f32(r)? as f64).to_object(py),
cbor::F64 => decode::read_f64(r)?.to_object(py),
_ => return Err(anyhow::anyhow!(format!("unsupported major type"))),
_ => return Err(anyhow::anyhow!(format!("Unsupported major type"))),
},
};
Ok(py_object)
Expand Down

0 comments on commit 4975730

Please sign in to comment.