1use std::{
9 fmt::Debug,
10 io::{Cursor, Read, Result, Write},
11 sync::Arc,
12};
13
14use byteorder::{ByteOrder, LittleEndian, WriteBytesExt};
15use chrono::Duration;
16
17use crate::{
18 sync::Mutex,
19 types::{constants, status_codes::StatusCode},
20};
21
22pub type EncodingResult<T> = std::result::Result<T, StatusCode>;
23
24#[derive(Debug)]
27pub struct DepthLock {
28 depth_gauge: Arc<Mutex<DepthGauge>>,
29}
30
31impl Drop for DepthLock {
32 fn drop(&mut self) {
33 let mut dg = trace_lock!(self.depth_gauge);
34 if dg.current_depth > 0 {
35 dg.current_depth -= 1;
36 }
37 }
40}
41
42impl DepthLock {
43 pub fn obtain(
46 depth_gauge: Arc<Mutex<DepthGauge>>,
47 ) -> core::result::Result<DepthLock, StatusCode> {
48 let mut dg = trace_lock!(depth_gauge);
49 if dg.current_depth >= dg.max_depth {
50 warn!("Decoding in stream aborted due maximum recursion depth being reached");
51 Err(StatusCode::BadDecodingError)
52 } else {
53 dg.current_depth += 1;
54 drop(dg);
55 Ok(Self { depth_gauge })
56 }
57 }
58}
59
60#[derive(Debug)]
63pub struct DepthGauge {
64 pub(crate) max_depth: usize,
66 pub(crate) current_depth: usize,
68}
69
70impl Default for DepthGauge {
71 fn default() -> Self {
72 Self {
73 max_depth: constants::MAX_DECODING_DEPTH,
74 current_depth: 0,
75 }
76 }
77}
78
79impl DepthGauge {
80 pub fn minimal() -> Self {
81 Self {
82 max_depth: 1,
83 ..Default::default()
84 }
85 }
86 pub fn max_depth(&self) -> usize {
87 self.max_depth
88 }
89 pub fn current_depth(&self) -> usize {
90 self.current_depth
91 }
92}
93
94#[derive(Clone, Debug)]
95pub struct DecodingOptions {
96 pub client_offset: Duration,
99 pub max_message_size: usize,
101 pub max_chunk_count: usize,
103 pub max_string_length: usize,
105 pub max_byte_string_length: usize,
107 pub max_array_length: usize,
109 pub decoding_depth_gauge: Arc<Mutex<DepthGauge>>,
111}
112
113impl Default for DecodingOptions {
114 fn default() -> Self {
115 DecodingOptions {
116 client_offset: Duration::zero(),
117 max_message_size: constants::MAX_MESSAGE_SIZE,
118 max_chunk_count: constants::MAX_CHUNK_COUNT,
119 max_string_length: constants::MAX_STRING_LENGTH,
120 max_byte_string_length: constants::MAX_BYTE_STRING_LENGTH,
121 max_array_length: constants::MAX_ARRAY_LENGTH,
122 decoding_depth_gauge: Arc::new(Mutex::new(DepthGauge::default())),
123 }
124 }
125}
126
127impl DecodingOptions {
128 pub fn minimal() -> Self {
131 DecodingOptions {
132 max_string_length: 8192,
133 max_byte_string_length: 8192,
134 max_array_length: 8192,
135 decoding_depth_gauge: Arc::new(Mutex::new(DepthGauge::minimal())),
136 ..Default::default()
137 }
138 }
139
140 #[cfg(test)]
142 pub fn test() -> Self {
143 Self::default()
144 }
145
146 pub fn depth_lock(&self) -> core::result::Result<DepthLock, StatusCode> {
147 DepthLock::obtain(self.decoding_depth_gauge.clone())
148 }
149}
150
151pub trait BinaryEncoder<T> {
155 fn byte_len(&self) -> usize;
158 fn encode<S: Write>(&self, stream: &mut S) -> EncodingResult<usize>;
160 fn decode<S: Read>(stream: &mut S, decoding_options: &DecodingOptions) -> EncodingResult<T>;
164
165 fn encode_to_vec(&self) -> Vec<u8> {
168 let mut buffer = Cursor::new(Vec::with_capacity(self.byte_len()));
169 let _ = self.encode(&mut buffer);
170 buffer.into_inner()
171 }
172}
173
174pub fn process_encode_io_result(result: Result<usize>) -> EncodingResult<usize> {
176 result.map_err(|err| {
177 trace!("Encoding error - {:?}", err);
178 StatusCode::BadEncodingError
179 })
180}
181
182pub fn process_decode_io_result<T>(result: Result<T>) -> EncodingResult<T>
184where
185 T: Debug,
186{
187 result.map_err(|err| {
188 trace!("Decoding error - {:?}", err);
189 StatusCode::BadDecodingError
190 })
191}
192
193pub fn byte_len_array<T: BinaryEncoder<T>>(values: &Option<Vec<T>>) -> usize {
195 let mut size = 4;
196 if let Some(ref values) = values {
197 size += values.iter().map(|v| v.byte_len()).sum::<usize>();
198 }
199 size
200}
201
202pub fn write_array<S: Write, T: BinaryEncoder<T>>(
204 stream: &mut S,
205 values: &Option<Vec<T>>,
206) -> EncodingResult<usize> {
207 let mut size = 0;
208 if let Some(ref values) = values {
209 size += write_i32(stream, values.len() as i32)?;
210 for value in values.iter() {
211 size += value.encode(stream)?;
212 }
213 } else {
214 size += write_i32(stream, -1)?;
215 }
216 Ok(size)
217}
218
219pub fn read_array<S: Read, T: BinaryEncoder<T>>(
221 stream: &mut S,
222 decoding_options: &DecodingOptions,
223) -> EncodingResult<Option<Vec<T>>> {
224 let len = read_i32(stream)?;
225 if len == -1 {
226 Ok(None)
227 } else if len < -1 {
228 error!("Array length is negative value and invalid");
229 Err(StatusCode::BadDecodingError)
230 } else if len as usize > decoding_options.max_array_length {
231 error!(
232 "Array length {} exceeds decoding limit {}",
233 len, decoding_options.max_array_length
234 );
235 Err(StatusCode::BadDecodingError)
236 } else {
237 let mut values: Vec<T> = Vec::with_capacity(len as usize);
238 for _ in 0..len {
239 values.push(T::decode(stream, decoding_options)?);
240 }
241 Ok(Some(values))
242 }
243}
244
245pub fn write_bytes(stream: &mut dyn Write, value: u8, count: usize) -> EncodingResult<usize> {
247 for _ in 0..count {
248 let _ = stream
249 .write_u8(value)
250 .map_err(|_| StatusCode::BadEncodingError)?;
251 }
252 Ok(count)
253}
254
255pub fn write_u8<T>(stream: &mut dyn Write, value: T) -> EncodingResult<usize>
257where
258 T: Into<u8>,
259{
260 let buf: [u8; 1] = [value.into()];
261 process_encode_io_result(stream.write(&buf))
262}
263
264pub fn write_i16<T>(stream: &mut dyn Write, value: T) -> EncodingResult<usize>
266where
267 T: Into<i16>,
268{
269 let mut buf = [0u8; 2];
270 LittleEndian::write_i16(&mut buf, value.into());
271 process_encode_io_result(stream.write(&buf))
272}
273
274pub fn write_u16<T>(stream: &mut dyn Write, value: T) -> EncodingResult<usize>
276where
277 T: Into<u16>,
278{
279 let mut buf = [0u8; 2];
280 LittleEndian::write_u16(&mut buf, value.into());
281 process_encode_io_result(stream.write(&buf))
282}
283
284pub fn write_i32<T>(stream: &mut dyn Write, value: T) -> EncodingResult<usize>
286where
287 T: Into<i32>,
288{
289 let mut buf = [0u8; 4];
290 LittleEndian::write_i32(&mut buf, value.into());
291 process_encode_io_result(stream.write(&buf))
292}
293
294pub fn write_u32<T>(stream: &mut dyn Write, value: T) -> EncodingResult<usize>
296where
297 T: Into<u32>,
298{
299 let mut buf = [0u8; 4];
300 LittleEndian::write_u32(&mut buf, value.into());
301 process_encode_io_result(stream.write(&buf))
302}
303
304pub fn write_i64<T>(stream: &mut dyn Write, value: T) -> EncodingResult<usize>
306where
307 T: Into<i64>,
308{
309 let mut buf = [0u8; 8];
310 LittleEndian::write_i64(&mut buf, value.into());
311 process_encode_io_result(stream.write(&buf))
312}
313
314pub fn write_u64<T>(stream: &mut dyn Write, value: T) -> EncodingResult<usize>
316where
317 T: Into<u64>,
318{
319 let mut buf = [0u8; 8];
320 LittleEndian::write_u64(&mut buf, value.into());
321 process_encode_io_result(stream.write(&buf))
322}
323
324pub fn write_f32<T>(stream: &mut dyn Write, value: T) -> EncodingResult<usize>
326where
327 T: Into<f32>,
328{
329 let mut buf = [0u8; 4];
330 LittleEndian::write_f32(&mut buf, value.into());
331 process_encode_io_result(stream.write(&buf))
332}
333
334pub fn write_f64<T>(stream: &mut dyn Write, value: T) -> EncodingResult<usize>
336where
337 T: Into<f64>,
338{
339 let mut buf = [0u8; 8];
340 LittleEndian::write_f64(&mut buf, value.into());
341 process_encode_io_result(stream.write(&buf))
342}
343
344pub fn read_bytes(stream: &mut dyn Read, buf: &mut [u8]) -> EncodingResult<usize> {
346 let result = stream.read_exact(buf);
347 process_decode_io_result(result)?;
348 Ok(buf.len())
349}
350
351pub fn read_u8(stream: &mut dyn Read) -> EncodingResult<u8> {
353 let mut buf = [0u8];
354 let result = stream.read_exact(&mut buf);
355 process_decode_io_result(result)?;
356 Ok(buf[0])
357}
358
359pub fn read_i16(stream: &mut dyn Read) -> EncodingResult<i16> {
361 let mut buf = [0u8; 2];
362 let result = stream.read_exact(&mut buf);
363 process_decode_io_result(result)?;
364 Ok(LittleEndian::read_i16(&buf))
365}
366
367pub fn read_u16(stream: &mut dyn Read) -> EncodingResult<u16> {
369 let mut buf = [0u8; 2];
370 let result = stream.read_exact(&mut buf);
371 process_decode_io_result(result)?;
372 Ok(LittleEndian::read_u16(&buf))
373}
374
375pub fn read_i32(stream: &mut dyn Read) -> EncodingResult<i32> {
377 let mut buf = [0u8; 4];
378 let result = stream.read_exact(&mut buf);
379 process_decode_io_result(result)?;
380 Ok(LittleEndian::read_i32(&buf))
381}
382
383pub fn read_u32(stream: &mut dyn Read) -> EncodingResult<u32> {
385 let mut buf = [0u8; 4];
386 let result = stream.read_exact(&mut buf);
387 process_decode_io_result(result)?;
388 Ok(LittleEndian::read_u32(&buf))
389}
390
391pub fn read_i64(stream: &mut dyn Read) -> EncodingResult<i64> {
393 let mut buf = [0u8; 8];
394 let result = stream.read_exact(&mut buf);
395 process_decode_io_result(result)?;
396 Ok(LittleEndian::read_i64(&buf))
397}
398
399pub fn read_u64(stream: &mut dyn Read) -> EncodingResult<u64> {
401 let mut buf = [0u8; 8];
402 let result = stream.read_exact(&mut buf);
403 process_decode_io_result(result)?;
404 Ok(LittleEndian::read_u64(&buf))
405}
406
407pub fn read_f32(stream: &mut dyn Read) -> EncodingResult<f32> {
409 let mut buf = [0u8; 4];
410 let result = stream.read_exact(&mut buf);
411 process_decode_io_result(result)?;
412 Ok(LittleEndian::read_f32(&buf))
413}
414
415pub fn read_f64(stream: &mut dyn Read) -> EncodingResult<f64> {
417 let mut buf = [0u8; 8];
418 let result = stream.read_exact(&mut buf);
419 process_decode_io_result(result)?;
420 Ok(LittleEndian::read_f64(&buf))
421}