Don't fail to deserialize data_base64 even if datacontenttype lies

This fixes #160

From the spec: "When a CloudEvent is deserialized from JSON, the
presence of the data_base64 member clearly indicates that the value is
a Base64 encoded binary data, which the deserializer MUST decode into
a binary runtime data type. The deserializer MAY further interpret
this binary data according to the datacontenttype."
https://github.com/cloudevents/spec/blob/master/cloudevents/formats/json-format.md#312-payload-deserialization

Signed-off-by: Jim Crossley <jim@crossleys.org>
This commit is contained in:
Jim Crossley 2021-11-09 22:47:56 -05:00
parent 1e89203cbc
commit 05807fdf28
3 changed files with 33 additions and 1 deletions

View File

@ -200,6 +200,10 @@ mod tests {
fixtures::v10::full_json_base64_data_json(),
fixtures::v10::full_json_data()
),
case::full_v10_with_non_json_base64_data(
fixtures::v10::full_non_json_base64_data(),
fixtures::v10::full_non_json_data()
),
case::full_v10_with_xml_string_data(
fixtures::v10::full_xml_string_data_json(),
fixtures::v10::full_xml_string_data()

View File

@ -42,7 +42,13 @@ impl crate::event::format::EventFormatDeserializer for EventFormatDeserializer {
Ok(match (data, data_base64, is_json) {
(Some(d), None, true) => Some(Data::Json(parse_data_json!(d, E)?)),
(Some(d), None, false) => Some(Data::String(parse_data_string!(d, E)?)),
(None, Some(d), true) => Some(Data::Json(parse_json_data_base64!(d, E)?)),
(None, Some(d), true) => {
let dc = d.to_owned();
match parse_json_data_base64!(dc, E) {
Ok(x) => Some(Data::Json(x)),
Err(_) => Some(Data::Binary(parse_data_base64!(d, E)?)),
}
}
(None, Some(d), false) => Some(Data::Binary(parse_data_base64!(d, E)?)),
(Some(_), Some(_), _) => {
return Err(E::custom("Cannot have both data and data_base64 field"))

View File

@ -170,6 +170,28 @@ pub fn full_json_base64_data_json() -> Value {
})
}
pub fn full_non_json_base64_data() -> Value {
match full_json_base64_data_json() {
Value::Object(mut m) => {
m.insert(
"data_base64".to_string(),
Value::String(base64::encode(b"hello world")),
);
Value::Object(m)
}
_ => Value::Null,
}
}
pub fn full_non_json_data() -> Event {
let mut event = full_json_data();
let value = full_non_json_base64_data();
if let Value::Object(m) = value {
event.set_data_unchecked(base64::decode(m["data_base64"].as_str().unwrap()).unwrap());
}
event
}
pub fn full_xml_string_data() -> Event {
let (string_ext_name, string_ext_value) = string_extension();
let (bool_ext_name, bool_ext_value) = bool_extension();