Skip to content
This repository was archived by the owner on Nov 30, 2022. It is now read-only.

Commit a2ff38e

Browse files
authored
Merge pull request #36 from rust-bitcoin/2019-03-serdefix
fix non-human-readable serde deserialization
2 parents 1bac99e + b14fe9e commit a2ff38e

File tree

2 files changed

+53
-11
lines changed

2 files changed

+53
-11
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "bitcoin_hashes"
3-
version = "0.3.0"
3+
version = "0.3.1"
44
authors = ["Andrew Poelstra <apoelstra@wpsoftware.net>"]
55
license = "CC0-1.0"
66
description = "Hash functions used by rust-bitcoin which support rustc 1.14.0"

src/serde_macros.rs

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,63 @@ macro_rules! serde_impl(
1717

1818
impl<'de> ::serde::Deserialize<'de> for $t {
1919
fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<$t, D::Error> {
20-
use ::serde::de::Error;
2120
use hex::FromHex;
2221

2322
if d.is_human_readable() {
24-
let sl: String = ::serde::Deserialize::deserialize(d)?;
25-
$t::from_hex(&sl).map_err(D::Error::custom)
23+
struct HexVisitor;
24+
25+
impl<'de> ::serde::de::Visitor<'de> for HexVisitor {
26+
type Value = $t;
27+
28+
fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
29+
formatter.write_str("an ASCII hex string")
30+
}
31+
32+
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
33+
where
34+
E: ::serde::de::Error,
35+
{
36+
if let Ok(hex) = ::std::str::from_utf8(v) {
37+
$t::from_hex(hex).map_err(E::custom)
38+
} else {
39+
return Err(E::invalid_value(::serde::de::Unexpected::Bytes(v), &self));
40+
}
41+
}
42+
43+
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
44+
where
45+
E: ::serde::de::Error,
46+
{
47+
$t::from_hex(v).map_err(E::custom)
48+
}
49+
}
50+
51+
d.deserialize_str(HexVisitor)
2652
} else {
27-
let sl: &[u8] = ::serde::Deserialize::deserialize(d)?;
28-
if sl.len() != $t::LEN {
29-
Err(D::Error::invalid_length(sl.len(), &stringify!($len)))
30-
} else {
31-
let mut ret = [0; $len];
32-
ret.copy_from_slice(sl);
33-
Ok($t(ret))
53+
struct BytesVisitor;
54+
55+
impl<'de> ::serde::de::Visitor<'de> for BytesVisitor {
56+
type Value = $t;
57+
58+
fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
59+
formatter.write_str("a bytestring")
60+
}
61+
62+
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
63+
where
64+
E: ::serde::de::Error,
65+
{
66+
if v.len() != $t::LEN {
67+
Err(E::invalid_length(v.len(), &stringify!($len)))
68+
} else {
69+
let mut ret = [0; $len];
70+
ret.copy_from_slice(v);
71+
Ok($t(ret))
72+
}
73+
}
3474
}
75+
76+
d.deserialize_bytes(BytesVisitor)
3577
}
3678
}
3779
}

0 commit comments

Comments
 (0)