From 76d160344b43a968f17311488051b43989946cfc Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Fri, 21 Jul 2017 11:17:40 +0200 Subject: [PATCH 1/3] Update serde to 1.0 --- Cargo.toml | 4 ++-- src/key.rs | 65 ++++++++++++++++++++++++++++++++------------------- src/macros.rs | 29 ++++++++++++++--------- 3 files changed, 61 insertions(+), 37 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9c83022..020d256 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,6 @@ clippy = {version = "0.0", optional = true} rand = "0.3" libc = "0.2" rustc-serialize = "0.3" -serde = "0.6" -serde_json = "0.6" +serde = "1.0" +serde_json = "1.0" diff --git a/src/key.rs b/src/key.rs index c404dca..144f21f 100644 --- a/src/key.rs +++ b/src/key.rs @@ -274,20 +274,20 @@ impl Encodable for PublicKey { } } -impl Deserialize for PublicKey { - fn deserialize(d: &mut D) -> Result - where D: Deserializer +impl<'de> Deserialize<'de> for PublicKey { + fn deserialize(d: D) -> Result + where D: Deserializer<'de> { use serde::de; struct Visitor { marker: marker::PhantomData, } - impl de::Visitor for Visitor { + impl<'de> de::Visitor<'de> for Visitor { type Value = PublicKey; #[inline] - fn visit_seq(&mut self, mut v: V) -> Result - where V: de::SeqVisitor + fn visit_seq(self, mut a: A) -> Result + where A: de::SeqAccess<'de> { debug_assert!(constants::UNCOMPRESSED_PUBLIC_KEY_SIZE >= constants::COMPRESSED_PUBLIC_KEY_SIZE); @@ -298,27 +298,44 @@ impl Deserialize for PublicKey { let mut read_len = 0; while read_len < constants::UNCOMPRESSED_PUBLIC_KEY_SIZE { - let read_ch = match try!(v.visit()) { + let read_ch = match try!(a.next_element()) { Some(c) => c, None => break }; ret[read_len] = read_ch; read_len += 1; } - try!(v.end()); + let one_after_last : Option = try!(a.next_element()); + if one_after_last.is_some() { + return Err(de::Error::invalid_length(read_len + 1, &self)); + } - PublicKey::from_slice(&s, &ret[..read_len]).map_err(|e| de::Error::syntax(&e.to_string())) + match read_len { + constants::UNCOMPRESSED_PUBLIC_KEY_SIZE | constants::COMPRESSED_PUBLIC_KEY_SIZE + => PublicKey::from_slice(&s, &ret[..read_len]).map_err( + |e| match e { + InvalidPublicKey => de::Error::invalid_value(de::Unexpected::Seq, &self), + _ => de::Error::custom(&e.to_string()), + } + ), + _ => Err(de::Error::invalid_length(read_len, &self)), + } } } + + fn expecting(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + write!(f, "a sequence of {} or {} bytes representing a valid compressed or uncompressed public key", + constants::COMPRESSED_PUBLIC_KEY_SIZE, constants::UNCOMPRESSED_PUBLIC_KEY_SIZE) + } } // Begin actual function - d.visit(Visitor { marker: ::std::marker::PhantomData }) + d.deserialize_seq(Visitor { marker: ::std::marker::PhantomData }) } } impl Serialize for PublicKey { - fn serialize(&self, s: &mut S) -> Result<(), S::Error> + fn serialize(&self, s: S) -> Result where S: Serializer { let secp = Secp256k1::with_caps(::ContextFlag::None); @@ -491,30 +508,30 @@ mod test { use json; // Invalid length - let zero31 = "[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]".as_bytes(); - let mut json = json::de::Deserializer::new(zero31.iter().map(|c| Ok(*c))); + let zero31 = "[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]"; + let mut json = json::de::Deserializer::from_str(zero31); assert!(::deserialize(&mut json).is_err()); - let mut json = json::de::Deserializer::new(zero31.iter().map(|c| Ok(*c))); + let mut json = json::de::Deserializer::from_str(zero31); assert!(::deserialize(&mut json).is_err()); - let zero32 = "[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]".as_bytes(); - let mut json = json::de::Deserializer::new(zero32.iter().map(|c| Ok(*c))); + let zero32 = "[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]"; + let mut json = json::de::Deserializer::from_str(zero32); assert!(::deserialize(&mut json).is_err()); - let mut json = json::de::Deserializer::new(zero32.iter().map(|c| Ok(*c))); + let mut json = json::de::Deserializer::from_str(zero32); assert!(::deserialize(&mut json).is_ok()); // All zeroes pk is invalid - let zero65 = "[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]".as_bytes(); - let mut json = json::de::Deserializer::new(zero65.iter().map(|c| Ok(*c))); + let zero65 = "[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]"; + let mut json = json::de::Deserializer::from_str(zero65); assert!(::deserialize(&mut json).is_err()); - let mut json = json::de::Deserializer::new(zero65.iter().map(|c| Ok(*c))); + let mut json = json::de::Deserializer::from_str(zero65); assert!(::deserialize(&mut json).is_err()); // Syntax error - let string = "\"my key\"".as_bytes(); - let mut json = json::de::Deserializer::new(string.iter().map(|c| Ok(*c))); + let string = "\"my key\""; + let mut json = json::de::Deserializer::from_str(string); assert!(::deserialize(&mut json).is_err()); - let mut json = json::de::Deserializer::new(string.iter().map(|c| Ok(*c))); + let mut json = json::de::Deserializer::from_str(string); assert!(::deserialize(&mut json).is_err()); } @@ -532,7 +549,7 @@ mod test { let mut serializer = json::ser::Serializer::new(&mut encoded); start.serialize(&mut serializer).unwrap(); } - let mut deserializer = json::de::Deserializer::new(encoded.iter().map(|c| Ok(*c))); + let mut deserializer = json::de::Deserializer::from_slice(&encoded); let decoded = Deserialize::deserialize(&mut deserializer); assert_eq!(Some(start), decoded.ok()); }) diff --git a/src/macros.rs b/src/macros.rs index 235b01a..ea40823 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -144,9 +144,9 @@ macro_rules! impl_array_newtype { } } - impl ::serde::Deserialize for $thing { - fn deserialize(d: &mut D) -> Result<$thing, D::Error> - where D: ::serde::Deserializer + impl<'de> ::serde::Deserialize<'de> for $thing { + fn deserialize(d: D) -> Result<$thing, D::Error> + where D: ::serde::Deserializer<'de> { // We have to define the Visitor struct inside the function // to make it local ... all we really need is that it's @@ -154,35 +154,42 @@ macro_rules! impl_array_newtype { struct Visitor { marker: ::std::marker::PhantomData<$thing>, } - impl ::serde::de::Visitor for Visitor { + impl<'de> ::serde::de::Visitor<'de> for Visitor { type Value = $thing; #[inline] - fn visit_seq(&mut self, mut v: V) -> Result<$thing, V::Error> - where V: ::serde::de::SeqVisitor + fn visit_seq(self, mut a: A) -> Result<$thing, A::Error> + where A: ::serde::de::SeqAccess<'de> { unsafe { use std::mem; let mut ret: [$ty; $len] = mem::uninitialized(); for i in 0..$len { - ret[i] = match try!(v.visit()) { + ret[i] = match try!(a.next_element()) { Some(c) => c, - None => return Err(::serde::de::Error::end_of_stream()) + None => return Err(::serde::de::Error::invalid_length(i, &self)) }; } - try!(v.end()); + let one_after_last : Option = try!(a.next_element()); + if one_after_last.is_some() { + return Err(::serde::de::Error::invalid_length($len + 1, &self)); + } Ok($thing(ret)) } } + + fn expecting(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + write!(f, "a sequence of {} elements", $len) + } } // Begin actual function - d.visit(Visitor { marker: ::std::marker::PhantomData }) + d.deserialize_seq(Visitor { marker: ::std::marker::PhantomData }) } } impl ::serde::Serialize for $thing { - fn serialize(&self, s: &mut S) -> Result<(), S::Error> + fn serialize(&self, s: S) -> Result where S: ::serde::Serializer { (&self.0[..]).serialize(s) From b1d8b09f250c67c2e56af2753b37dd9908327838 Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Fri, 21 Jul 2017 22:21:37 +0200 Subject: [PATCH 2/3] Add tests for trailing bytes during deserilization --- src/key.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/key.rs b/src/key.rs index 144f21f..0f8f182 100644 --- a/src/key.rs +++ b/src/key.rs @@ -520,6 +520,27 @@ mod test { let mut json = json::de::Deserializer::from_str(zero32); assert!(::deserialize(&mut json).is_ok()); + let zero33 = "[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]"; + let mut json = json::de::Deserializer::from_str(zero33); + assert!(::deserialize(&mut json).is_err()); + let mut json = json::de::Deserializer::from_str(zero33); + assert!(::deserialize(&mut json).is_err()); + + let trailing66 = "[4,149,16,196,140,38,92,239,179,65,59,224,230,183,91,238,240,46,186,252, + 175,102,52,249,98,178,123,72,50,171,196,254,236,1,189,143,242,227,16,87, + 247,183,162,68,237,140,92,205,151,129,166,58,111,96,123,64,180,147,51,12, + 209,89,236,213,206,17]"; + let mut json = json::de::Deserializer::from_str(trailing66); + assert!(::deserialize(&mut json).is_err()); + + // The first 65 bytes of trailing66 are valid + let valid65 = "[4,149,16,196,140,38,92,239,179,65,59,224,230,183,91,238,240,46,186,252, + 175,102,52,249,98,178,123,72,50,171,196,254,236,1,189,143,242,227,16,87, + 247,183,162,68,237,140,92,205,151,129,166,58,111,96,123,64,180,147,51,12, + 209,89,236,213,206]"; + let mut json = json::de::Deserializer::from_str(valid65); + assert!(::deserialize(&mut json).is_ok()); + // All zeroes pk is invalid let zero65 = "[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]"; let mut json = json::de::Deserializer::from_str(zero65); From a400e1678ef988be0cb2ae5dd3a4364e82784dc7 Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Fri, 21 Jul 2017 22:22:55 +0200 Subject: [PATCH 3/3] Bump version to 0.7.0 for serde update --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 020d256..749ce0f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "secp256k1" -version = "0.6.3" +version = "0.7.0" authors = [ "Dawid Ciężarkiewicz ", "Andrew Poelstra " ] license = "CC0-1.0"