Skip to content

Commit

Permalink
Merge pull request #472 from feliwir/prevent-json-crash
Browse files Browse the repository at this point in the history
[json] Skip bulk data URI when deserializing JSON
  • Loading branch information
Enet4 authored Apr 13, 2024
2 parents 0af744f + fb0bba6 commit f2674fc
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 5 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions json/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ dicom-object = { version = "0.6.3", path = "../object" }
num-traits = "0.2.15"
serde = { version = "1.0.164", features = ["derive"] }
serde_json = { version = "1.0.96", features = ["preserve_order"] }
tracing = "0.1.34"

[dev-dependencies]
dicom-test-files = "0.2.1"
Expand Down
67 changes: 62 additions & 5 deletions json/src/de/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use dicom_core::{
use dicom_object::InMemDicomObject;
use serde::de::{Deserialize, DeserializeOwned, Error as _, Visitor};

use self::value::{DicomJsonPerson, NumberOrText};
use self::value::{BulkDataUri, DicomJsonPerson, NumberOrText};

mod value;

Expand Down Expand Up @@ -72,8 +72,19 @@ where
{
let mut obj = InMemDicomObject::<D>::new_empty_with_dict(D::default());
while let Some(e) = map.next_entry::<DicomJson<Tag>, JsonDataElement<D>>()? {
let (DicomJson(tag), JsonDataElement { vr, value }) = e;
obj.put(DataElement::new(tag, vr, value));
let (
DicomJson(tag),
JsonDataElement {
vr,
value,
bulk_data_uri,
},
) = e;
if bulk_data_uri.is_some() {
tracing::warn!("bulk data URI is not supported for InMemDicomObject; skipping {}", tag);
} else {
obj.put(DataElement::new(tag, vr, value));
}
}
Ok(obj)
}
Expand All @@ -98,6 +109,10 @@ where
struct JsonDataElement<D> {
vr: VR,
value: Value<InMemDicomObject<D>, InMemFragment>,
// TODO(#470): we just ignore this when deserializing with
// DicomJson<InMemDicomObject>
// Handle this properly with a custom deserializer
bulk_data_uri: Option<BulkDataUri>,
}

#[derive(Debug)]
Expand Down Expand Up @@ -127,6 +142,7 @@ where
let mut vr = None;
let mut value: Option<serde_json::Value> = None;
let mut inline_binary = None;
let mut bulk_data_uri = None;

while let Some(key) = map.next_key::<String>()? {
match &*key {
Expand All @@ -145,6 +161,10 @@ where
));
}

if bulk_data_uri.is_some() {
return Err(A::Error::custom("\"Value\" conflicts with \"BulkDataURI\""));
}

value = Some(map.next_value()?);
}
"InlineBinary" => {
Expand All @@ -153,10 +173,31 @@ where
"\"InlineBinary\" conflicts with \"Value\"",
));
}

if bulk_data_uri.is_some() {
return Err(A::Error::custom(
"\"InlineBinary\" conflicts with \"BulkDataURI\"",
));
}
// read value as string
let val: String = map.next_value()?;
inline_binary = Some(val);
}
"BulkDataURI" => {
if values.is_some() {
return Err(A::Error::custom("\"BulkDataURI\" conflicts with \"Value\""));
}

if inline_binary.is_some() {
return Err(A::Error::custom(
"\"BulkDataURI\" conflicts with \"InlineBinary\"",
));
}

// read value as string
let val: BulkDataUri = map.next_value()?;
bulk_data_uri = Some(val);
}
_ => {
return Err(A::Error::custom("Unrecognized data element field"));
}
Expand Down Expand Up @@ -319,10 +360,14 @@ where
PrimitiveValue::from(data).into()
}
(Some(values), None) => values,
(Some(_), Some(_)) => unreachable!(),
_ => unreachable!(),
};

Ok(JsonDataElement { vr, value })
Ok(JsonDataElement {
vr,
value,
bulk_data_uri,
})
}
}

Expand Down Expand Up @@ -475,4 +520,16 @@ mod tests {
)),
)
}

#[test]
fn can_resolve_bulk_data() {
let serialized = serde_json::json!({
"7FE00010": {
"vr": "OW",
"BulkDataURI": "http://localhost:8042/dicom-web/studies/1.2.276.0.89.300.10035584652.20181014.93645/series/1.2.392.200036.9125.3.1696751121028.64888163108.42362060/instances/1.2.392.200036.9125.9.0.454007928.539582480.1883970570/bulk/7fe00010"
}
});

assert!(super::from_value::<InMemDicomObject>(serialized).is_ok());
}
}

0 comments on commit f2674fc

Please sign in to comment.