diff --git a/primitive-types/impls/serde/Cargo.toml b/primitive-types/impls/serde/Cargo.toml index 77a70be6c..bd2963fc4 100644 --- a/primitive-types/impls/serde/Cargo.toml +++ b/primitive-types/impls/serde/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "impl-serde" -version = "0.2.1" +version = "0.2.2" authors = ["Parity Technologies "] license = "Apache-2.0/MIT" homepage = "https://github.com/paritytech/parity-common" @@ -11,8 +11,9 @@ serde = "1.0" [dev-dependencies] criterion = "0.3.0" -uint = "0.8.1" +serde_derive = "1.0" serde_json = "1.0.40" +uint = "0.8.1" [[bench]] name = "impl_serde" diff --git a/primitive-types/impls/serde/src/serialize.rs b/primitive-types/impls/serde/src/serialize.rs index da4fe491f..95b626471 100644 --- a/primitive-types/impls/serde/src/serialize.rs +++ b/primitive-types/impls/serde/src/serialize.rs @@ -105,7 +105,7 @@ pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> where let bytes_len = v.len() - 2; let mut modulus = bytes_len % 2; - let mut bytes = vec![0u8; bytes_len / 2]; + let mut bytes = vec![0u8; (bytes_len + 1) / 2]; let mut buf = 0; let mut pos = 0; for (idx, byte) in v.bytes().enumerate().skip(2) { @@ -217,3 +217,42 @@ pub fn deserialize_check_len<'a, 'de, D>(deserializer: D, len: ExpectedLen<'a>) deserializer.deserialize_str(Visitor { len }) } + +#[cfg(test)] +mod tests { + extern crate serde_derive; + + use self::serde_derive::Deserialize; + + #[derive(Deserialize)] + struct Bytes(#[serde(with="super")] Vec); + + #[test] + fn should_not_fail_on_short_string() { + let a: Bytes = serde_json::from_str("\"0x\"").unwrap(); + let b: Bytes = serde_json::from_str("\"0x1\"").unwrap(); + let c: Bytes = serde_json::from_str("\"0x12\"").unwrap(); + let d: Bytes = serde_json::from_str("\"0x123\"").unwrap(); + let e: Bytes = serde_json::from_str("\"0x1234\"").unwrap(); + let f: Bytes = serde_json::from_str("\"0x12345\"").unwrap(); + + assert!(a.0.is_empty()); + assert_eq!(b.0, vec![1]); + assert_eq!(c.0, vec![0x12]); + assert_eq!(d.0, vec![0x1, 0x23]); + assert_eq!(e.0, vec![0x12, 0x34]); + assert_eq!(f.0, vec![0x1, 0x23, 0x45]); + } + + + #[test] + fn should_not_fail_on_other_strings() { + let a: Bytes = serde_json::from_str("\"0x7f864e18e3dd8b58386310d2fe0919eef27c6e558564b7f67f22d99d20f587\"").unwrap(); + let b: Bytes = serde_json::from_str("\"0x7f864e18e3dd8b58386310d2fe0919eef27c6e558564b7f67f22d99d20f587b\"").unwrap(); + let c: Bytes = serde_json::from_str("\"0x7f864e18e3dd8b58386310d2fe0919eef27c6e558564b7f67f22d99d20f587b4\"").unwrap(); + + assert_eq!(a.0.len(), 31); + assert_eq!(b.0.len(), 32); + assert_eq!(c.0.len(), 32); + } +}