Compare commits

...

8 Commits

Author SHA1 Message Date
David Tolnay 8c34e0940f Release 1.0.23 2017-11-29 22:26:32 -08:00
David Tolnay eb6bf16a51 Revert "Catch wrong field names length in serde_test"
There are at least two reasonable things to expect the len field to
check: the length of the fields array passed to deserialize_struct, or
the number of field tokens. Even beyond these, in some cases it can be
useful to test deserialization with a bogus len to test how the
Deserialize impl reacts to an incorrect size_hint.

This reverts commit 436cafb0a3 which was
released in serde_test 1.0.20.
2017-11-29 22:21:05 -08:00
David Tolnay 797d049db5 Release 1.0.22 2017-11-29 20:01:43 -08:00
David Tolnay d61a373f12 Merge pull request #1104 from serde-rs/abs
Fix missing absolute paths in deserialize_seq
2017-11-29 19:58:21 -08:00
David Tolnay e0eea551b4 Fix missing absolute paths in deserialize_seq 2017-11-29 19:45:22 -08:00
David Tolnay c650a92bf7 Update to compiletest-rs 0.3 to fix "every suggestion should have at least one span" 2017-11-24 17:12:58 -08:00
David Tolnay f218f4d7bf Release 1.0.21 2017-11-15 22:24:18 -08:00
Alex Shapiro 8c0a2015be Fix error when deserializing untagged enum
Serde's `ContentDeserializer` and `ContentRefDeserializer`
cannot deserialize struct enum variant associated data when
that data is encoded as a sequence. This failure leads to
errors when decoding an enum nested in another untagged
enum. For example:

    #[derive(Serialize, Deserialize)]
    #[serde(untagged)]
    enum Foo {
        A(Bar),
    }

    #[derive(Serialize, Deserialize)]
    enum Bar {
        B{f1: String},
    }

    let data1 = Foo::A(Bar::B{f1: "Hello".into()});
    let bytes = rmp_serde::to_vec(&data1).unwrap();
    let data2 = rmp_serde::from_slice::<Foo>(&bytes).unwrap();

Deserializing fails with the error `Syntax("data did not
match any variant of untagged enum Foo")`, but the
underlying failure occurs when decoding the associated data
of `Bar::B`.

This pull request fixes the issue by allowing
`ContentDeserializer` and `ContentRefDeserializer` to
deserialize sequence-encoded struct enum variant data.
2017-11-15 21:56:33 -08:00
12 changed files with 29 additions and 24 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde" name = "serde"
version = "1.0.20" # remember to update html_root_url version = "1.0.23" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework" description = "A generic serialization/deserialization framework"
+1 -1
View File
@@ -79,7 +79,7 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here. // Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.20")] #![doc(html_root_url = "https://docs.rs/serde/1.0.23")]
// Support using Serde without the standard library! // Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
+6
View File
@@ -1246,6 +1246,9 @@ mod content {
Some(Content::Map(v)) => { Some(Content::Map(v)) => {
de::Deserializer::deserialize_any(MapDeserializer::new(v), visitor) de::Deserializer::deserialize_any(MapDeserializer::new(v), visitor)
} }
Some(Content::Seq(v)) => {
de::Deserializer::deserialize_any(SeqDeserializer::new(v), visitor)
}
Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant"),), Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant"),),
_ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant"),), _ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant"),),
} }
@@ -1640,6 +1643,9 @@ mod content {
Some(&Content::Map(ref v)) => { Some(&Content::Map(ref v)) => {
de::Deserializer::deserialize_any(MapRefDeserializer::new(v), visitor) de::Deserializer::deserialize_any(MapRefDeserializer::new(v), visitor)
} }
Some(&Content::Seq(ref v)) => {
de::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor)
}
Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant"),), Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant"),),
_ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant"),), _ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant"),),
} }
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_derive" name = "serde_derive"
version = "1.0.20" # remember to update html_root_url version = "1.0.23" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]" description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
+2 -2
View File
@@ -418,8 +418,8 @@ fn deserialize_seq(
}; };
let assign = quote! { let assign = quote! {
let #var = match #visit { let #var = match #visit {
Some(__value) => __value, _serde::export::Some(__value) => __value,
None => { _serde::export::None => {
return _serde::export::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting)); return _serde::export::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting));
} }
}; };
+1 -1
View File
@@ -22,7 +22,7 @@
//! //!
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html //! [https://serde.rs/derive.html]: https://serde.rs/derive.html
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.20")] #![doc(html_root_url = "https://docs.rs/serde_derive/1.0.23")]
#![cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))] #![cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))]
#![cfg_attr(feature = "cargo-clippy", allow(used_underscore_binding))] #![cfg_attr(feature = "cargo-clippy", allow(used_underscore_binding))]
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_test" name = "serde_test"
version = "1.0.20" # remember to update html_root_url version = "1.0.23" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "Token De/Serializer for testing De/Serialize implementations" description = "Token De/Serializer for testing De/Serialize implementations"
+2 -2
View File
@@ -352,8 +352,8 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
V: Visitor<'de>, V: Visitor<'de>,
{ {
match self.peek_token() { match self.peek_token() {
Token::Struct { .. } => { Token::Struct { len: n, .. } => {
assert_next_token!(self, Token::Struct { name: name, len: fields.len() }); assert_next_token!(self, Token::Struct { name: name, len: n });
self.visit_map(Some(fields.len()), Token::StructEnd, visitor) self.visit_map(Some(fields.len()), Token::StructEnd, visitor)
} }
Token::Map { .. } => { Token::Map { .. } => {
+1 -1
View File
@@ -155,7 +155,7 @@
//! # } //! # }
//! ``` //! ```
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.20")] #![doc(html_root_url = "https://docs.rs/serde_test/1.0.23")]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))] #![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy lints // Whitelisted clippy lints
-8
View File
@@ -425,10 +425,6 @@ pub enum Token {
/// The header of a struct. /// The header of a struct.
/// ///
/// When testing deserialization, the `len` field must match the number of
/// fields that the struct expects to deserialize. This may be different
/// from the number of fields contained in the input tokens.
///
/// After this header are the fields of the struct, followed by `StructEnd`. /// After this header are the fields of the struct, followed by `StructEnd`.
/// ///
/// ```rust /// ```rust
@@ -465,10 +461,6 @@ pub enum Token {
/// The header of a struct variant of an enum. /// The header of a struct variant of an enum.
/// ///
/// When testing deserialization, the `len` field must match the number of
/// fields that the struct variant expects to deserialize. This may be
/// different from the number of fields contained in the input tokens.
///
/// After this header are the fields of the struct variant, followed by /// After this header are the fields of the struct variant, followed by
/// `StructVariantEnd`. /// `StructVariantEnd`.
/// ///
+1 -1
View File
@@ -15,4 +15,4 @@ serde_derive = { path = "../serde_derive" }
serde_test = { path = "../serde_test" } serde_test = { path = "../serde_test" }
[dependencies] [dependencies]
compiletest_rs = { version = "0.2", optional = true } compiletest_rs = { version = "0.3", optional = true }
+12 -5
View File
@@ -23,6 +23,7 @@ use self::serde::de::{DeserializeOwned, Deserializer};
use std::borrow::Cow; use std::borrow::Cow;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::option::Option as StdOption;
use std::result::Result as StdResult; use std::result::Result as StdResult;
// Try to trip up the generated code if it fails to use fully qualified paths. // Try to trip up the generated code if it fails to use fully qualified paths.
@@ -32,6 +33,12 @@ struct Result;
struct Ok; struct Ok;
#[allow(dead_code)] #[allow(dead_code)]
struct Err; struct Err;
#[allow(dead_code)]
struct Option;
#[allow(dead_code)]
struct Some;
#[allow(dead_code)]
struct None;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@@ -56,7 +63,7 @@ fn test_gen() {
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
struct WithRef<'a, T: 'a> { struct WithRef<'a, T: 'a> {
#[serde(skip_deserializing)] #[serde(skip_deserializing)]
t: Option<&'a T>, t: StdOption<&'a T>,
#[serde(serialize_with="ser_x", deserialize_with="de_x")] #[serde(serialize_with="ser_x", deserialize_with="de_x")]
x: X, x: X,
} }
@@ -77,9 +84,9 @@ fn test_gen() {
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
struct NoBounds<T> { struct NoBounds<T> {
t: T, t: T,
option: Option<T>, option: StdOption<T>,
boxed: Box<T>, boxed: Box<T>,
option_boxed: Option<Box<T>>, option_boxed: StdOption<Box<T>>,
} }
assert::<NoBounds<i32>>(); assert::<NoBounds<i32>>();
@@ -175,8 +182,8 @@ fn test_gen() {
#[derive(Serialize)] #[derive(Serialize)]
struct OptionStatic<'a> { struct OptionStatic<'a> {
a: Option<&'a str>, a: StdOption<&'a str>,
b: Option<&'static str>, b: StdOption<&'static str>,
} }
assert_ser::<OptionStatic>(); assert_ser::<OptionStatic>();