1 use serde::serde_if_integer128;
2 use serde_derive::Deserialize;
3 use serde_yaml::Value;
4 use std::collections::BTreeMap;
5 use std::fmt::Debug;
6 use unindent::unindent;
7 
test_de<T>(yaml: &str, expected: &T) where T: serde::de::DeserializeOwned + PartialEq + Debug,8 fn test_de<T>(yaml: &str, expected: &T)
9 where
10     T: serde::de::DeserializeOwned + PartialEq + Debug,
11 {
12     let deserialized: T = serde_yaml::from_str(yaml).unwrap();
13     assert_eq!(*expected, deserialized);
14 
15     serde_yaml::from_str::<serde_yaml::Value>(yaml).unwrap();
16     serde_yaml::from_str::<serde::de::IgnoredAny>(yaml).unwrap();
17 }
18 
test_de_seed<T, S>(yaml: &str, seed: S, expected: &T) where T: PartialEq + Debug, S: for<'de> serde::de::DeserializeSeed<'de, Value = T>,19 fn test_de_seed<T, S>(yaml: &str, seed: S, expected: &T)
20 where
21     T: PartialEq + Debug,
22     S: for<'de> serde::de::DeserializeSeed<'de, Value = T>,
23 {
24     let deserialized: T = serde_yaml::seed::from_str_seed(yaml, seed).unwrap();
25     assert_eq!(*expected, deserialized);
26 
27     serde_yaml::from_str::<serde_yaml::Value>(yaml).unwrap();
28     serde_yaml::from_str::<serde::de::IgnoredAny>(yaml).unwrap();
29 }
30 
31 #[test]
test_alias()32 fn test_alias() {
33     let yaml = unindent(
34         "
35         ---
36         first:
37           &alias
38           1
39         second:
40           *alias
41         third: 3",
42     );
43     let mut expected = BTreeMap::new();
44     {
45         expected.insert(String::from("first"), 1);
46         expected.insert(String::from("second"), 1);
47         expected.insert(String::from("third"), 3);
48     }
49     test_de(&yaml, &expected);
50 }
51 
52 #[test]
test_option()53 fn test_option() {
54     #[derive(Deserialize, PartialEq, Debug)]
55     struct Data {
56         a: Option<f64>,
57         b: Option<String>,
58         c: Option<bool>,
59     }
60     let yaml = unindent(
61         "
62         ---
63         b:
64         c: true",
65     );
66     let expected = Data {
67         a: None,
68         b: None,
69         c: Some(true),
70     };
71     test_de(&yaml, &expected);
72 }
73 
74 #[test]
test_option_alias()75 fn test_option_alias() {
76     #[derive(Deserialize, PartialEq, Debug)]
77     struct Data {
78         a: Option<f64>,
79         b: Option<String>,
80         c: Option<bool>,
81         d: Option<f64>,
82         e: Option<String>,
83         f: Option<bool>,
84     }
85     let yaml = unindent(
86         "
87         ---
88         none_f:
89           &none_f
90           ~
91         none_s:
92           &none_s
93           ~
94         none_b:
95           &none_b
96           ~
97 
98         some_f:
99           &some_f
100           1.0
101         some_s:
102           &some_s
103           x
104         some_b:
105           &some_b
106           true
107 
108         a: *none_f
109         b: *none_s
110         c: *none_b
111         d: *some_f
112         e: *some_s
113         f: *some_b",
114     );
115     let expected = Data {
116         a: None,
117         b: None,
118         c: None,
119         d: Some(1.0),
120         e: Some("x".to_owned()),
121         f: Some(true),
122     };
123     test_de(&yaml, &expected);
124 }
125 
126 #[test]
test_enum_alias()127 fn test_enum_alias() {
128     #[derive(Deserialize, PartialEq, Debug)]
129     enum E {
130         A,
131         B(u8, u8),
132     }
133     #[derive(Deserialize, PartialEq, Debug)]
134     struct Data {
135         a: E,
136         b: E,
137     }
138     let yaml = unindent(
139         "
140         ---
141         aref:
142           &aref
143           A
144         bref:
145           &bref
146           B:
147             - 1
148             - 2
149 
150         a: *aref
151         b: *bref",
152     );
153     let expected = Data {
154         a: E::A,
155         b: E::B(1, 2),
156     };
157     test_de(&yaml, &expected);
158 }
159 
160 #[test]
test_enum_tag()161 fn test_enum_tag() {
162     #[derive(Deserialize, PartialEq, Debug)]
163     enum E {
164         A(String),
165         B(String),
166     }
167     #[derive(Deserialize, PartialEq, Debug)]
168     struct Data {
169         a: E,
170         b: E,
171     }
172     let yaml = unindent(
173         "
174         ---
175         a: !A foo
176         b: !B bar",
177     );
178     let expected = Data {
179         a: E::A("foo".into()),
180         b: E::B("bar".into()),
181     };
182     test_de(&yaml, &expected);
183 }
184 
185 #[test]
test_number_as_string()186 fn test_number_as_string() {
187     #[derive(Deserialize, PartialEq, Debug)]
188     struct Num {
189         value: String,
190     }
191     let yaml = unindent(
192         "
193         ---
194         # Cannot be represented as u128
195         value: 340282366920938463463374607431768211457",
196     );
197     let expected = Num {
198         value: "340282366920938463463374607431768211457".to_owned(),
199     };
200     test_de(&yaml, &expected);
201 }
202 
203 serde_if_integer128! {
204     #[test]
205     fn test_i128_big() {
206         let expected: i128 = ::std::i64::MIN as i128 - 1;
207         let yaml = unindent(
208             "
209             ---
210             -9223372036854775809",
211         );
212         assert_eq!(expected, serde_yaml::from_str::<i128>(&yaml).unwrap());
213     }
214 
215     #[test]
216     fn test_u128_big() {
217         let expected: u128 = ::std::u64::MAX as u128 + 1;
218         let yaml = unindent(
219             "
220             ---
221             18446744073709551616",
222         );
223         assert_eq!(expected, serde_yaml::from_str::<u128>(&yaml).unwrap());
224     }
225 }
226 
227 #[test]
test_number_alias_as_string()228 fn test_number_alias_as_string() {
229     #[derive(Deserialize, PartialEq, Debug)]
230     struct Num {
231         version: String,
232         value: String,
233     }
234     let yaml = unindent(
235         "
236         ---
237         version: &a 1.10
238         value: *a",
239     );
240     let expected = Num {
241         version: "1.10".to_owned(),
242         value: "1.10".to_owned(),
243     };
244     test_de(&yaml, &expected);
245 }
246 
247 #[test]
test_de_mapping()248 fn test_de_mapping() {
249     #[derive(Debug, Deserialize, PartialEq)]
250     struct Data {
251         pub substructure: serde_yaml::Mapping,
252     }
253     let yaml = unindent(
254         "
255         ---
256         substructure:
257           a: 'foo'
258           b: 'bar'",
259     );
260 
261     let mut expected = Data {
262         substructure: serde_yaml::Mapping::new(),
263     };
264     expected.substructure.insert(
265         serde_yaml::Value::String("a".to_owned()),
266         serde_yaml::Value::String("foo".to_owned()),
267     );
268     expected.substructure.insert(
269         serde_yaml::Value::String("b".to_owned()),
270         serde_yaml::Value::String("bar".to_owned()),
271     );
272 
273     test_de(&yaml, &expected);
274 }
275 
276 #[test]
test_bomb()277 fn test_bomb() {
278     #[derive(Debug, Deserialize, PartialEq)]
279     struct Data {
280         expected: String,
281     }
282 
283     // This would deserialize an astronomical number of elements if we were
284     // vulnerable.
285     let yaml = unindent(
286         "
287         ---
288         a: &a ~
289         b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]
290         c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]
291         d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]
292         e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]
293         f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]
294         g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]
295         h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]
296         i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]
297         j: &j [*i,*i,*i,*i,*i,*i,*i,*i,*i]
298         k: &k [*j,*j,*j,*j,*j,*j,*j,*j,*j]
299         l: &l [*k,*k,*k,*k,*k,*k,*k,*k,*k]
300         m: &m [*l,*l,*l,*l,*l,*l,*l,*l,*l]
301         n: &n [*m,*m,*m,*m,*m,*m,*m,*m,*m]
302         o: &o [*n,*n,*n,*n,*n,*n,*n,*n,*n]
303         p: &p [*o,*o,*o,*o,*o,*o,*o,*o,*o]
304         q: &q [*p,*p,*p,*p,*p,*p,*p,*p,*p]
305         r: &r [*q,*q,*q,*q,*q,*q,*q,*q,*q]
306         s: &s [*r,*r,*r,*r,*r,*r,*r,*r,*r]
307         t: &t [*s,*s,*s,*s,*s,*s,*s,*s,*s]
308         u: &u [*t,*t,*t,*t,*t,*t,*t,*t,*t]
309         v: &v [*u,*u,*u,*u,*u,*u,*u,*u,*u]
310         w: &w [*v,*v,*v,*v,*v,*v,*v,*v,*v]
311         x: &x [*w,*w,*w,*w,*w,*w,*w,*w,*w]
312         y: &y [*x,*x,*x,*x,*x,*x,*x,*x,*x]
313         z: &z [*y,*y,*y,*y,*y,*y,*y,*y,*y]
314         expected: string",
315     );
316 
317     let expected = Data {
318         expected: "string".to_owned(),
319     };
320 
321     assert_eq!(expected, serde_yaml::from_str::<Data>(&yaml).unwrap());
322 }
323 
324 #[test]
test_numbers()325 fn test_numbers() {
326     let cases = [
327         ("0xF0", "240"),
328         ("+0xF0", "240"),
329         ("-0xF0", "-240"),
330         ("0o70", "56"),
331         ("+0o70", "56"),
332         ("-0o70", "-56"),
333         ("0b10", "2"),
334         ("+0b10", "2"),
335         ("-0b10", "-2"),
336         ("127", "127"),
337         ("+127", "127"),
338         ("-127", "-127"),
339         (".inf", ".inf"),
340         (".Inf", ".inf"),
341         (".INF", ".inf"),
342         ("-.inf", "-.inf"),
343         ("-.Inf", "-.inf"),
344         ("-.INF", "-.inf"),
345         (".nan", ".nan"),
346         (".NaN", ".nan"),
347         (".NAN", ".nan"),
348         ("0.1", "0.1"),
349     ];
350     for &(yaml, expected) in &cases {
351         let value = serde_yaml::from_str::<Value>(yaml).unwrap();
352         match value {
353             Value::Number(number) => assert_eq!(number.to_string(), expected),
354             _ => panic!("expected number"),
355         }
356     }
357 }
358 
359 #[test]
test_stateful()360 fn test_stateful() {
361     struct Seed(i64);
362 
363     impl<'de> serde::de::DeserializeSeed<'de> for Seed {
364         type Value = i64;
365         fn deserialize<D>(self, deserializer: D) -> Result<i64, D::Error>
366         where
367             D: serde::de::Deserializer<'de>,
368         {
369             struct Visitor(i64);
370             impl<'de> serde::de::Visitor<'de> for Visitor {
371                 type Value = i64;
372 
373                 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
374                     write!(formatter, "an integer")
375                 }
376 
377                 fn visit_i64<E: serde::de::Error>(self, v: i64) -> Result<i64, E> {
378                     Ok(v * self.0)
379                 }
380 
381                 fn visit_u64<E: serde::de::Error>(self, v: u64) -> Result<i64, E> {
382                     Ok(v as i64 * self.0)
383                 }
384             }
385 
386             deserializer.deserialize_any(Visitor(self.0))
387         }
388     }
389 
390     let cases = [("3", 5, 15), ("6", 7, 42), ("-5", 9, -45)];
391     for &(yaml, seed, expected) in &cases {
392         test_de_seed(yaml, Seed(seed), &expected);
393     }
394 }
395