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 crate::binary_type::{CopyFromBuf, Discard};
18 use crate::bufext::BufMutExt;
19 use crate::errors::ProtocolError;
20 use crate::framing::{Framing, FramingDecoded, FramingEncoded, FramingEncodedFinal};
21 use crate::thrift_protocol::{MessageType, ProtocolID};
22 use crate::ttype::TType;
23 use crate::Result;
24 
25 /// The maximum recursive depth the skip() function will traverse
26 pub const DEFAULT_RECURSION_DEPTH: i32 = 64;
27 
28 /// Helper type alias to get the pre-finalization encoded type of a protocol frame.
29 pub type ProtocolEncoded<P> = FramingEncoded<<P as Protocol>::Frame>;
30 
31 /// Helper type alias to get the final encoded type of a protocol frame
32 pub type ProtocolEncodedFinal<P> = FramingEncodedFinal<<P as Protocol>::Frame>;
33 
34 /// Helper type alias to get the buffer type for a frame to be decoded.
35 pub type ProtocolDecoded<P> = FramingDecoded<<P as Protocol>::Frame>;
36 
37 /// An instance of Protocol glues a Framing implementation to a serializer
38 /// (ProtocolWriter) and deserializer (ProtocolReader). It constructs, as
39 /// needed, a serializer to construct a frame with a given protocol, or a
40 /// deserializer from a frame into a stream of deserialized objects.
41 pub trait Protocol: 'static {
42     /// Type of the framing implementation
43     type Frame: Framing;
44 
45     /// Compute the size of a frame for a given protocol. This can be exact or too large, but
46     /// must not be too small.
47     type Sizer: ProtocolWriter<Final = usize>;
48 
49     /// Serialize into a buffer. The buffer is allocated with the size computed by Sizer, so
50     /// it must be large enough.
51     type Serializer: ProtocolWriter<Final = <<Self::Frame as Framing>::EncBuf as BufMutExt>::Final>;
52 
53     /// Set up a deserializer from a frame's buffer.
54     type Deserializer: ProtocolReader;
55 
56     const PROTOCOL_ID: ProtocolID;
57 
serializer<SZ, SER>(sz: SZ, ser: SER) -> <Self::Serializer as ProtocolWriter>::Final where SZ: FnOnce(&mut Self::Sizer), SER: FnOnce(&mut Self::Serializer)58     fn serializer<SZ, SER>(sz: SZ, ser: SER) -> <Self::Serializer as ProtocolWriter>::Final
59     where
60         SZ: FnOnce(&mut Self::Sizer),
61         SER: FnOnce(&mut Self::Serializer);
62 
deserializer(buf: <Self::Frame as Framing>::DecBuf) -> Self::Deserializer63     fn deserializer(buf: <Self::Frame as Framing>::DecBuf) -> Self::Deserializer;
64 
into_buffer(_: Self::Deserializer) -> <Self::Frame as Framing>::DecBuf65     fn into_buffer(_: Self::Deserializer) -> <Self::Frame as Framing>::DecBuf;
66 }
67 
skip_inner<P: ProtocolReader + ?Sized>( p: &mut P, field_type: TType, max_depth: i32, ) -> Result<()>68 fn skip_inner<P: ProtocolReader + ?Sized>(
69     p: &mut P,
70     field_type: TType,
71     max_depth: i32,
72 ) -> Result<()> {
73     if max_depth <= 0 {
74         bail_err!(ProtocolError::SkipDepthExceeded)
75     }
76 
77     match field_type {
78         TType::Void => {}
79         TType::Bool => {
80             p.read_bool()?;
81         }
82         TType::Byte => {
83             p.read_byte()?;
84         }
85         TType::I16 => {
86             p.read_i16()?;
87         }
88         TType::I32 => {
89             p.read_i32()?;
90         }
91         TType::I64 => {
92             p.read_i64()?;
93         }
94         TType::Double => {
95             p.read_double()?;
96         }
97         TType::Float => {
98             p.read_float()?;
99         }
100         TType::Struct => {
101             p.read_struct_begin(|_| ())?;
102             loop {
103                 let fields = &[];
104                 let (_, type_id, _) = p.read_field_begin(|_| (), fields)?;
105                 if type_id == TType::Stop {
106                     break;
107                 }
108                 skip_inner(p, type_id, max_depth - 1)?;
109                 p.read_field_end()?;
110             }
111             p.read_struct_end()?;
112         }
113         TType::Map => {
114             let (key_type, value_type, len) = p.read_map_begin()?;
115             if len != Some(0) {
116                 let mut idx = 0;
117                 loop {
118                     let more = p.read_map_key_begin()?;
119                     if !more {
120                         break;
121                     }
122                     skip_inner(p, key_type, max_depth - 1)?;
123                     p.read_map_value_begin()?;
124                     skip_inner(p, value_type, max_depth)?;
125                     p.read_map_value_end()?;
126 
127                     idx += 1;
128                     if should_break(len, more, idx) {
129                         break;
130                     }
131                 }
132             }
133             p.read_map_end()?;
134         }
135         TType::Set => {
136             let (elem_type, len) = p.read_set_begin()?;
137             if len != Some(0) {
138                 let mut idx = 0;
139                 loop {
140                     let more = p.read_set_value_begin()?;
141                     if !more {
142                         break;
143                     }
144                     skip_inner(p, elem_type, max_depth - 1)?;
145                     p.read_set_value_end()?;
146 
147                     idx += 1;
148                     if should_break(len, more, idx) {
149                         break;
150                     }
151                 }
152             }
153             p.read_set_end()?;
154         }
155         TType::List => {
156             let (elem_type, len) = p.read_list_begin()?;
157             if len != Some(0) {
158                 let mut idx = 0;
159                 loop {
160                     let more = p.read_list_value_begin()?;
161                     if !more {
162                         break;
163                     }
164                     skip_inner(p, elem_type, max_depth - 1)?;
165                     p.read_list_value_end()?;
166 
167                     idx += 1;
168                     if should_break(len, more, idx) {
169                         break;
170                     }
171                 }
172             }
173             p.read_list_end()?;
174         }
175         TType::UTF8 => {
176             p.read_string()?;
177         }
178         TType::UTF16 => {
179             p.read_string()?;
180         }
181         TType::String => {
182             p.read_binary::<Discard>()?;
183         }
184         TType::Stream => bail_err!(ProtocolError::StreamUnsupported),
185         TType::Stop => bail_err!(ProtocolError::UnexpectedStopInSkip),
186     };
187     Ok(())
188 }
189 
190 /// Trait for emitting a frame formatted in a given protocol
191 pub trait ProtocolWriter {
192     type Final;
193 
write_message_begin(&mut self, name: &str, type_id: MessageType, seqid: u32)194     fn write_message_begin(&mut self, name: &str, type_id: MessageType, seqid: u32);
write_message_end(&mut self)195     fn write_message_end(&mut self);
write_struct_begin(&mut self, name: &str)196     fn write_struct_begin(&mut self, name: &str);
write_struct_end(&mut self)197     fn write_struct_end(&mut self);
write_field_begin(&mut self, name: &str, type_id: TType, id: i16)198     fn write_field_begin(&mut self, name: &str, type_id: TType, id: i16);
write_field_end(&mut self)199     fn write_field_end(&mut self);
write_field_stop(&mut self)200     fn write_field_stop(&mut self);
write_map_begin(&mut self, key_type: TType, value_type: TType, size: usize)201     fn write_map_begin(&mut self, key_type: TType, value_type: TType, size: usize);
write_map_key_begin(&mut self)202     fn write_map_key_begin(&mut self);
write_map_value_begin(&mut self)203     fn write_map_value_begin(&mut self);
write_map_end(&mut self)204     fn write_map_end(&mut self);
write_list_begin(&mut self, elem_type: TType, size: usize)205     fn write_list_begin(&mut self, elem_type: TType, size: usize);
write_list_value_begin(&mut self)206     fn write_list_value_begin(&mut self);
write_list_end(&mut self)207     fn write_list_end(&mut self);
write_set_begin(&mut self, elem_type: TType, size: usize)208     fn write_set_begin(&mut self, elem_type: TType, size: usize);
write_set_value_begin(&mut self)209     fn write_set_value_begin(&mut self);
write_set_end(&mut self)210     fn write_set_end(&mut self);
write_bool(&mut self, value: bool)211     fn write_bool(&mut self, value: bool);
write_byte(&mut self, value: i8)212     fn write_byte(&mut self, value: i8);
write_i16(&mut self, value: i16)213     fn write_i16(&mut self, value: i16);
write_i32(&mut self, value: i32)214     fn write_i32(&mut self, value: i32);
write_i64(&mut self, value: i64)215     fn write_i64(&mut self, value: i64);
write_double(&mut self, value: f64)216     fn write_double(&mut self, value: f64);
write_float(&mut self, value: f32)217     fn write_float(&mut self, value: f32);
write_string(&mut self, value: &str)218     fn write_string(&mut self, value: &str);
write_binary(&mut self, value: &[u8])219     fn write_binary(&mut self, value: &[u8]);
220 
finish(self) -> Self::Final221     fn finish(self) -> Self::Final;
222 }
223 
224 /// Trait for decoding a frame in a given protocol
225 pub trait ProtocolReader {
read_message_begin<F, T>(&mut self, method: F) -> Result<(T, MessageType, u32)> where F: FnOnce(&[u8]) -> T226     fn read_message_begin<F, T>(&mut self, method: F) -> Result<(T, MessageType, u32)>
227     where
228         F: FnOnce(&[u8]) -> T;
read_message_end(&mut self) -> Result<()>229     fn read_message_end(&mut self) -> Result<()>;
read_struct_begin<F, T>(&mut self, strukt: F) -> Result<T> where F: FnOnce(&[u8]) -> T230     fn read_struct_begin<F, T>(&mut self, strukt: F) -> Result<T>
231     where
232         F: FnOnce(&[u8]) -> T;
read_struct_end(&mut self) -> Result<()>233     fn read_struct_end(&mut self) -> Result<()>;
read_field_begin<F, T>(&mut self, field: F, fields: &[Field]) -> Result<(T, TType, i16)> where F: FnOnce(&[u8]) -> T234     fn read_field_begin<F, T>(&mut self, field: F, fields: &[Field]) -> Result<(T, TType, i16)>
235     where
236         F: FnOnce(&[u8]) -> T;
read_field_end(&mut self) -> Result<()>237     fn read_field_end(&mut self) -> Result<()>;
read_map_begin(&mut self) -> Result<(TType, TType, Option<usize>)>238     fn read_map_begin(&mut self) -> Result<(TType, TType, Option<usize>)>;
read_map_key_begin(&mut self) -> Result<bool>239     fn read_map_key_begin(&mut self) -> Result<bool>;
read_map_value_begin(&mut self) -> Result<()>240     fn read_map_value_begin(&mut self) -> Result<()>;
read_map_value_end(&mut self) -> Result<()>241     fn read_map_value_end(&mut self) -> Result<()>;
read_map_end(&mut self) -> Result<()>242     fn read_map_end(&mut self) -> Result<()>;
read_list_begin(&mut self) -> Result<(TType, Option<usize>)>243     fn read_list_begin(&mut self) -> Result<(TType, Option<usize>)>;
read_list_value_begin(&mut self) -> Result<bool>244     fn read_list_value_begin(&mut self) -> Result<bool>;
read_list_value_end(&mut self) -> Result<()>245     fn read_list_value_end(&mut self) -> Result<()>;
read_list_end(&mut self) -> Result<()>246     fn read_list_end(&mut self) -> Result<()>;
read_set_begin(&mut self) -> Result<(TType, Option<usize>)>247     fn read_set_begin(&mut self) -> Result<(TType, Option<usize>)>;
read_set_value_begin(&mut self) -> Result<bool>248     fn read_set_value_begin(&mut self) -> Result<bool>;
read_set_value_end(&mut self) -> Result<()>249     fn read_set_value_end(&mut self) -> Result<()>;
read_set_end(&mut self) -> Result<()>250     fn read_set_end(&mut self) -> Result<()>;
read_bool(&mut self) -> Result<bool>251     fn read_bool(&mut self) -> Result<bool>;
read_byte(&mut self) -> Result<i8>252     fn read_byte(&mut self) -> Result<i8>;
read_i16(&mut self) -> Result<i16>253     fn read_i16(&mut self) -> Result<i16>;
read_i32(&mut self) -> Result<i32>254     fn read_i32(&mut self) -> Result<i32>;
read_i64(&mut self) -> Result<i64>255     fn read_i64(&mut self) -> Result<i64>;
read_double(&mut self) -> Result<f64>256     fn read_double(&mut self) -> Result<f64>;
read_float(&mut self) -> Result<f32>257     fn read_float(&mut self) -> Result<f32>;
read_string(&mut self) -> Result<String>258     fn read_string(&mut self) -> Result<String>;
read_binary<V: CopyFromBuf>(&mut self) -> Result<V>259     fn read_binary<V: CopyFromBuf>(&mut self) -> Result<V>;
260 
261     /// Skip over the next data element from the provided input Protocol object
skip(&mut self, field_type: TType) -> Result<()>262     fn skip(&mut self, field_type: TType) -> Result<()> {
263         skip_inner(self, field_type, DEFAULT_RECURSION_DEPTH)
264     }
265 }
266 
should_break(len: Option<usize>, more: bool, idx: usize) -> bool267 pub fn should_break(len: Option<usize>, more: bool, idx: usize) -> bool {
268     match (len, more) {
269         (Some(real_length), _) => idx >= real_length,
270         (None, true) => false,
271         (None, false) => true,
272     }
273 }
274 
275 /// Protocol::serializer wants the same serializer closure passed twice so
276 /// that it can specialize it for two types: once to compute the size, and a second time to
277 /// actually serialize the content. This macro helps by taking the factory type and
278 /// applying the serializer expression twice.
279 #[macro_export]
280 macro_rules! serialize {
281     ($protocol:ty, $serializer:expr) => {
282         <$protocol as $crate::Protocol>::serializer($serializer, $serializer)
283     };
284 }
285 
286 pub struct Field {
287     pub name: &'static str,
288     pub ttype: TType,
289     pub id: i16,
290 }
291 
292 impl Field {
new(name: &'static str, ttype: TType, id: i16) -> Self293     pub const fn new(name: &'static str, ttype: TType, id: i16) -> Self {
294         Field { name, ttype, id }
295     }
296 }
297