Skip to content

Commit

Permalink
Allow deserializing JSON null as an empty ByteString.
Browse files Browse the repository at this point in the history
The API server allows binary data values in ConfigMaps and Secrets to be
null if validation is disabled. This commit allows such a value to be
deserialized as an empty ByteString. This was done rather than change
Secret::binary_data and ConfigMap::binary_data to be maps of Option<ByteString>
since that would be worse for ergonomics and because these values can only be
created with validation disabled.

Mapping to an empty ByteString has precedence with the API server's handling
of nulls in ConfigMap::data, which again requires validation to be disabled,
and in which case the API server itself maps the nulls to empty strings.

Fixes #114
  • Loading branch information
Arnavion committed Dec 16, 2022
1 parent 1e5ab30 commit b619ade
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 1 deletion.
11 changes: 11 additions & 0 deletions k8s-openapi-tests/src/deserialize_leniency.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
use k8s_openapi::serde_json;

#[test]
fn bytestring_null() {
for (input, expected) in [
(r#""azhzLW9wZW5hcGk=""#, &b"k8s-openapi"[..]),
("null", &b""[..]),
] {
let actual: k8s_openapi::ByteString = serde_json::from_str(input).expect("couldn't deserialize ByteString");
assert_eq!(actual.0, expected);
}
}

#[test]
fn daemon_set() {
for input in [
Expand Down
10 changes: 9 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,12 +429,20 @@ impl<'de> serde::Deserialize<'de> for ByteString {
formatter.write_str("a base64-encoded string")
}

fn visit_none<E>(self) -> Result<Self::Value, E> where E: serde::de::Error {
Ok(ByteString(vec![]))
}

fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error> where D: serde::Deserializer<'de> {
deserializer.deserialize_str(self)
}

fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> where E: serde::de::Error {
Ok(ByteString(base64::decode(v).map_err(serde::de::Error::custom)?))
}
}

deserializer.deserialize_str(Visitor)
deserializer.deserialize_option(Visitor)
}
}

Expand Down

0 comments on commit b619ade

Please sign in to comment.