1 /*
2  * Copyright (c) Facebook, Inc. and its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 use anyhow::Result;
18 use fbthrift::simplejson_protocol::{deserialize, serialize};
19 use fbthrift::{simplejson_protocol::SimpleJsonProtocolDeserializer, Deserialize};
20 use fbthrift_test_if::{
21     Basic, Containers, En, MainStruct, MainStructNoBinary, Small, SubStruct, Un, UnOne,
22 };
23 use std::collections::BTreeMap;
24 use std::io::Cursor;
25 
26 #[test]
test_large_roundtrip() -> Result<()>27 fn test_large_roundtrip() -> Result<()> {
28     // Build the big struct
29     let mut m = BTreeMap::new();
30     m.insert("m1".to_string(), 1);
31     m.insert("m2".to_string(), 2);
32 
33     let sub = SubStruct {
34         ..Default::default()
35     };
36 
37     let u = Un::un1(UnOne {
38         one: 1,
39         ..Default::default()
40     });
41     let e = En::TWO;
42 
43     let mut int_keys = BTreeMap::new();
44     int_keys.insert(42, 43);
45     int_keys.insert(44, 45);
46 
47     let r = MainStruct {
48         foo: "foo".to_string(),
49         m,
50         bar: "test".to_string(),
51         s: sub,
52         l: vec![
53             Small {
54                 num: 1,
55                 two: 2,
56                 ..Default::default()
57             },
58             Small {
59                 num: 2,
60                 two: 3,
61                 ..Default::default()
62             },
63         ],
64         u,
65         e,
66         int_keys,
67         opt: None,
68         ..Default::default()
69     };
70 
71     // serialize it and assert that it serializes correctly
72     let s = String::from_utf8(serialize(&r).to_vec()).unwrap();
73 
74     // Note that default optionals are there
75     // but non-default optionals are not there
76     // That is an artifact on how the serialize trait works
77     let expected_string = r#"{
78         "foo":"foo",
79         "m":{"m1":1,"m2":2},
80         "bar":"test",
81         "s":{"optDef":"IAMOPT","req_def":"IAMREQ","bin":""},
82         "l":[{"num":1,"two":2},{"num":2,"two":3}],
83         "u":{"un1":{"one":1}},
84         "e":2,
85         "int_keys":{"42":43,"44":45}
86     }"#
87     .replace(" ", "")
88     .replace("\n", "");
89     assert_eq!(expected_string, s);
90 
91     // It at least needs to be valid json, the serialize then
92     // deserialize and compare will come in the next diff
93     let v: serde_json::Result<serde_json::Value> = serde_json::from_str(&s);
94     assert!(v.is_ok());
95 
96     // Assert that deserialize builts the exact same struct
97     assert_eq!(r, deserialize(s).unwrap());
98 
99     Ok(())
100 }
101 
102 #[test]
test_struct_key() -> Result<()>103 fn test_struct_key() -> Result<()> {
104     // See the `structKey` test in cpp_compat_test
105 
106     let mut h = std::collections::BTreeMap::new();
107     h.insert(
108         Small {
109             ..Default::default()
110         },
111         1,
112     );
113     let sub = SubStruct {
114         key_map: Some(h),
115         // In rust we need to specify optionals with defaults as None
116         // instead of relying on ..Default::default()
117         optDef: None,
118         ..Default::default()
119     };
120 
121     let s = String::from_utf8(serialize(&sub).to_vec()).unwrap();
122     let expected_string = r#"{
123         "req_def":"IAMREQ",
124         "key_map":{{"num":0,"two":0}:1},
125         "bin":""
126     }"#
127     .replace(" ", "")
128     .replace("\n", "");
129     assert_eq!(expected_string, s);
130 
131     // It's definitely not JSON...
132     let v: serde_json::Result<serde_json::Value> = serde_json::from_str(&s);
133     assert!(v.is_err());
134 
135     // ...but it needs to deserialize
136     assert_eq!(sub, deserialize(&s).unwrap());
137 
138     // ...though not to serde_json::Value.
139     if let Ok(wat) = deserialize(&s) {
140         let _: serde_json::Value = wat;
141         panic!("map with struct keys is not supposed to deserialize to Value");
142     }
143 
144     Ok(())
145 }
146 
147 #[test]
test_weird_text() -> Result<()>148 fn test_weird_text() -> Result<()> {
149     // See the `weirdText` test in cpp_compat_test
150 
151     let mut sub = SubStruct {
152         optDef: Some("stuff\twith\nescape\\characters'...\"lots{of}fun</xml>".to_string()),
153         bin: "1234".as_bytes().to_vec(),
154         ..Default::default()
155     };
156 
157     let s = String::from_utf8(serialize(&sub).to_vec()).unwrap();
158     let expected_string = r#"{
159         "optDef":"stuff\twith\nescape\\characters'...\"lots{of}fun</xml>",
160         "req_def":"IAMREQ",
161         "bin":"MTIzNA"
162     }"#
163     .replace(" ", "")
164     .replace("\n", "");
165     assert_eq!(expected_string, s);
166     // Make sure its equal
167     assert_eq!(sub, deserialize(s).unwrap());
168 
169     // Unicode escaping
170     sub.optDef = Some("UNICODE\u{1F60A}UH OH".to_string());
171 
172     let s = String::from_utf8(serialize(&sub).to_vec()).unwrap();
173     let expected_string = r#"{
174         "optDef":"UNICODE��UH OH",
175         "req_def":"IAMREQ",
176         "bin":"MTIzNA"
177     }"#
178     // Double-space to deal with "tabs"
179     .replace("  ", "")
180     .replace("\n", "");
181     assert_eq!(expected_string, s);
182     // Make sure its equal
183     assert_eq!(sub, deserialize(s).unwrap());
184 
185     Ok(())
186 }
187 
188 #[test]
test_skip_complex() -> Result<()>189 fn test_skip_complex() -> Result<()> {
190     // See the `skipComplex` test in cpp_compat_test
191 
192     let sub = SubStruct {
193         optDef: Some("thing".to_string()),
194         bin: "1234".as_bytes().to_vec(),
195         ..Default::default()
196     };
197 
198     let input = r#"{
199         "optDef":"thing",
200         "req_def":"IAMREQ",
201         "bin":"MTIzNA",
202         "extra":[1,{"thing":"thing2"}],
203         "extra_map":{"thing":null,"thing2":2},
204         "extra_bool":true
205     }"#
206     .replace(" ", "")
207     .replace("\n", "");
208     // Make sure everything is skipped properly
209     assert_eq!(sub, deserialize(input).unwrap());
210 
211     Ok(())
212 }
213 
214 #[test]
test_need_commas() -> Result<()>215 fn test_need_commas() -> Result<()> {
216     // See the `needCommas` test in cpp_compat_test
217 
218     // Note the missing commas
219 
220     let input = r#"{
221         "num":1
222         "two":2
223     }"#
224     .replace(" ", "")
225     .replace("\n", "");
226     assert!(deserialize::<Small, _, _>(input).is_err());
227 
228     // even when skipping
229     let input2 = r#"{
230         "num":1,
231         "two":2,
232         "extra_map":{"thing":null,"thing2":2}
233         "extra_bool":true
234     }"#
235     .replace(" ", "")
236     .replace("\n", "");
237     assert!(deserialize::<Small, _, _>(input2).is_err());
238 
239     Ok(())
240 }
241 
242 #[test]
test_need_commas_containers() -> Result<()>243 fn test_need_commas_containers() -> Result<()> {
244     // See the `needCommasContainers` test in cpp_compat_test
245 
246     let goodinput = r#"{
247         "m":{"m1":"m1","m2":"m2"}
248     }"#;
249     // Note the missing comma
250     let badinput = r#"{
251         "m":{"m1":"m1""m2":"m2"}
252     }"#;
253     assert!(deserialize::<Containers, _, _>(goodinput).is_ok());
254     assert!(deserialize::<Containers, _, _>(badinput).is_err());
255 
256     let goodinput2 = r#"{
257         "l":["l1","l2"]
258     }"#;
259     // Note the missing comma
260     let badinput2 = r#"{
261         "l":["l1""l2"]
262     }"#;
263     assert!(deserialize::<Containers, _, _>(goodinput2).is_ok());
264     assert!(deserialize::<Containers, _, _>(badinput2).is_err());
265 
266     Ok(())
267 }
268 
269 #[test]
test_null_stuff() -> Result<()>270 fn test_null_stuff() -> Result<()> {
271     // See the `nullStuff` test in cpp_compat_test
272 
273     let sub = SubStruct {
274         optDef: None,
275         bin: "1234".as_bytes().to_vec(),
276         ..Default::default()
277     };
278 
279     let input = r#"{
280         "optDef":null,
281         "req_def":"IAMREQ",
282         "bin":"MTIzNA"
283     }"#
284     .replace(" ", "")
285     .replace("\n", "");
286     // Make sure everything is skipped properly
287     assert_eq!(sub, deserialize(input).unwrap());
288 
289     Ok(())
290 }
291 
292 #[test]
infinite_spaces() -> Result<()>293 fn infinite_spaces() -> Result<()> {
294     let mut m = BTreeMap::new();
295     m.insert("m1".to_string(), 1);
296     m.insert("m2".to_string(), 2);
297 
298     let sub = SubStruct {
299         ..Default::default()
300     };
301 
302     let u = Un::un1(UnOne {
303         one: 1,
304         ..Default::default()
305     });
306     let e = En::TWO;
307 
308     let mut int_keys = BTreeMap::new();
309     int_keys.insert(42, 43);
310     int_keys.insert(44, 45);
311 
312     let r = MainStruct {
313         foo: "foo".to_string(),
314         m,
315         bar: "test".to_string(),
316         s: sub,
317         l: vec![
318             Small {
319                 num: 1,
320                 two: 2,
321                 ..Default::default()
322             },
323             Small {
324                 num: 2,
325                 two: 3,
326                 ..Default::default()
327             },
328         ],
329         u,
330         e,
331         int_keys,
332         opt: None,
333         ..Default::default()
334     };
335 
336     let input = r#"{
337          "foo"  :  "foo" ,
338           "m" : { "m1" :  1   , "m2" : 2 }  ,
339         "bar":"test",
340         "s":{"optDef":  "IAMOPT"  ,"req_def":  "IAMREQ","bin": ""  },
341         "l":[{"num":1,"two":2},{"num"  :2 ," two" : 3 } ],
342         "u":{"un1":{"one":  1  } },
343         "e":  2  ,
344         "int_keys"  :{"42"   :  43,  "44":45}
345     }"#;
346 
347     // Assert that deserialize builts the exact same struct
348     assert_eq!(r, deserialize(input).unwrap());
349 
350     Ok(())
351 }
352 
353 #[test]
test_bool() -> Result<()>354 fn test_bool() -> Result<()> {
355     let b = Basic {
356         b: true,
357         b2: false,
358         ..Default::default()
359     };
360     // serialize it and assert that it serializes correctly
361     let s = String::from_utf8(serialize(&b).to_vec()).unwrap();
362 
363     // Assert that deserialize builts the exact same struct
364     assert_eq!(b, deserialize(s).unwrap());
365 
366     Ok(())
367 }
368 
369 #[test]
test_serde_compat() -> Result<()>370 fn test_serde_compat() -> Result<()> {
371     // Build the big struct
372     let mut m = BTreeMap::new();
373     m.insert("m1".to_string(), 1);
374     m.insert("m2".to_string(), 2);
375 
376     let u = Un::un1(UnOne {
377         one: 1,
378         ..Default::default()
379     });
380     let e = En::TWO;
381 
382     let mut int_keys = BTreeMap::new();
383     int_keys.insert(42, 43);
384     int_keys.insert(44, 45);
385 
386     let r = MainStructNoBinary {
387         foo: "foo".to_string(),
388         m,
389         bar: "test".to_string(),
390         l: vec![
391             Small {
392                 num: 1,
393                 two: 2,
394                 ..Default::default()
395             },
396             Small {
397                 num: 2,
398                 two: 3,
399                 ..Default::default()
400             },
401         ],
402         u,
403         e,
404         int_keys,
405         opt: None,
406         ..Default::default()
407     };
408 
409     let fbthrift_s = String::from_utf8(serialize(&r).to_vec()).unwrap();
410     // We aren't going to get full compat, but at least make it so fbthrift
411     // can deserialize
412     // what serde has written out
413     let serde_s = serde_json::to_string(&r).unwrap();
414 
415     // but passing between them should work
416     assert_eq!(r, serde_json::from_str(&fbthrift_s).unwrap());
417     assert_eq!(r, deserialize(&serde_s).unwrap());
418     Ok(())
419 }
420 
421 #[test]
test_multiple_deser() -> Result<()>422 fn test_multiple_deser() -> Result<()> {
423     // Tests that we don't too eagerly advance the buffer
424     let b1 = Basic {
425         b: true,
426         b2: false,
427         ..Default::default()
428     };
429     let b2 = Basic {
430         b: true,
431         b2: true,
432         ..Default::default()
433     };
434     // serialize it and assert that it serializes correctly
435     let s1 = String::from_utf8(serialize(&b1).to_vec()).unwrap();
436     let s2 = String::from_utf8(serialize(&b2).to_vec()).unwrap();
437     let to_check = format!("{} {}", s1, s2);
438 
439     let mut deserializer = SimpleJsonProtocolDeserializer::new(Cursor::new(to_check.as_bytes()));
440     // Assert that deserialize builts the exact same struct
441     assert_eq!(b1, Basic::read(&mut deserializer)?);
442     assert_eq!(b2, Basic::read(&mut deserializer)?);
443 
444     Ok(())
445 }
446 
447 #[test]
test_not_enough() -> Result<()>448 fn test_not_enough() -> Result<()> {
449     // Tests that we can deserialize until
450     // we run out, and don't panic
451     let b1 = Basic {
452         b: true,
453         b2: false,
454         ..Default::default()
455     };
456     let b2 = Basic {
457         b: true,
458         b2: true,
459         ..Default::default()
460     };
461     // serialize it and assert that it serializes correctly
462     let s1 = String::from_utf8(serialize(&b1).to_vec()).unwrap();
463     let s2 = String::from_utf8(serialize(&b2).to_vec()).unwrap();
464     let to_check = format!("{} {}", s1, s2);
465 
466     let mut deserializer = SimpleJsonProtocolDeserializer::new(Cursor::new(
467         // 6 should cover the } and a `true` value
468         &to_check.as_bytes()[..to_check.as_bytes().len() - 6],
469     ));
470     // Assert that deserialize builts the exact same struct
471     assert_eq!(b1, Basic::read(&mut deserializer)?);
472     assert!(Basic::read(&mut deserializer).is_err());
473 
474     Ok(())
475 }
476 
477 #[test]
test_unknown_union() -> Result<()>478 fn test_unknown_union() -> Result<()> {
479     // See unknownUnion
480 
481     // Build the empty union
482     let u = Un::default();
483 
484     let s = String::from_utf8(serialize(&u).to_vec()).unwrap();
485     let expected_string = "{}";
486     assert_eq!(expected_string, s);
487 
488     // Assert that deserialize builts the exact same struct
489     assert_eq!(u, deserialize(s).unwrap());
490 
491     // ...
492     // extra weirdness
493     // Build an explicit unknown
494     let explicit_unknown = Un::UnknownField(100);
495     let s2 = String::from_utf8(serialize(&explicit_unknown).to_vec()).unwrap();
496     let expected_string = "{}";
497     assert_eq!(expected_string, s2);
498 
499     // Deserializes to the default -1 case, this matches the other
500     // protocols behavior
501     assert_eq!(u, deserialize(s2).unwrap());
502 
503     // backwards compat test
504     let old_output = r#"{
505         "UnknownField":-1
506     }"#
507     .replace(" ", "")
508     .replace("\n", "");
509 
510     assert_eq!(u, deserialize(old_output).unwrap());
511 
512     Ok(())
513 }
514