1use super::ByteOrder;
2use crate::rustbus_core;
3use rustbus_core::message_builder::{MarshalContext, UnmarshalContext};
4use rustbus_core::wire::marshal::traits::{Marshal, SignatureBuffer};
5use rustbus_core::wire::unmarshal::traits::Unmarshal;
6use rustbus_core::wire::validate_raw;
7use rustbus_core::wire::UnixFd;
8use std::sync::Arc;
9
10use arrayvec::ArrayVec;
11
12#[derive(Debug)]
15pub struct MarshalledMessageBody {
16 buf: Arc<Vec<u8>>,
17 sig: SignatureBuffer,
18
19 raw_fds: Vec<rustbus_core::wire::UnixFd>,
21
22 byteorder: ByteOrder,
23}
24
25impl Default for MarshalledMessageBody {
26 fn default() -> Self {
27 Self::new()
28 }
29}
30
31#[derive(Debug, PartialEq)]
32enum SigErr {
33 TooLong,
34 NonBaseDictKey,
35 ArraysTooNested,
36 StructsTooNested,
37 UnexpectedClosingParenthesis,
38 UnexpectedClosingBracket,
39 DictEntryNotInArray,
40 UnknownCharacter,
41 UnclosedStruct,
42 UnclosedDictEntry,
43 ArrayWithNoType,
44 TooManyTypesInDictEntry,
45}
46const MAX_NESTING_DEPTH: u8 = 32;
60
61fn validate_sig_str(sig: &str) -> Result<(), SigErr> {
62 if sig.len() > 255 {
63 return Err(SigErr::TooLong);
64 }
65 enum Nest {
66 Array,
67 DictEntry(u8), Struct(bool), }
70 let mut stack = ArrayVec::<_, 64>::new();
71 let mut a_cnt = 0; let mut b_cnt = 0;
73 for c in sig.chars() {
74 match c {
75 'v' | 'a' | '{' | '(' if matches!(stack.last(), Some(&Nest::DictEntry(0))) => {
76 return Err(SigErr::NonBaseDictKey);
77 }
78 'a' if a_cnt >= MAX_NESTING_DEPTH => return Err(SigErr::ArraysTooNested),
79 'a' => {
80 stack.push(Nest::Array);
81 a_cnt += 1;
82 continue;
83 }
84 '(' if b_cnt >= MAX_NESTING_DEPTH => return Err(SigErr::StructsTooNested),
85 '(' => {
86 stack.push(Nest::Struct(false));
87 b_cnt += 1;
88 continue;
89 }
90 ')' if !matches!(stack.pop(), Some(Nest::Struct(true))) => {
91 return Err(SigErr::UnexpectedClosingParenthesis)
92 }
93 ')' => b_cnt -= 1,
94 '{' if !matches!(stack.last(), Some(&Nest::Array)) => {
95 return Err(SigErr::DictEntryNotInArray)
96 }
97 '{' => {
98 stack.push(Nest::DictEntry(0));
99 continue;
100 }
101 '}' if !matches!(stack.pop(), Some(Nest::DictEntry(2))) => {
102 return Err(SigErr::UnexpectedClosingBracket)
103 }
104 'v' | '}' | 'y' | 'b' | 'n' | 'q' | 'i' | 'u' | 'x' | 't' | 'd' | 's' | 'o' | 'g'
105 | 'h' => {}
106 _ => return Err(SigErr::UnknownCharacter),
107 }
108 while matches!(stack.last(), Some(&Nest::Array)) {
109 stack.pop();
110 a_cnt -= 1;
111 }
112 match stack.last_mut() {
113 Some(Nest::DictEntry(cnt)) if *cnt >= 2 => return Err(SigErr::TooManyTypesInDictEntry),
114 Some(Nest::DictEntry(cnt)) => *cnt += 1,
115 Some(Nest::Struct(non_empty)) => *non_empty = true,
116 _ => {}
117 }
118 }
119 if stack.is_empty() {
120 debug_assert_eq!(a_cnt, 0);
121 debug_assert_eq!(b_cnt, 0);
122 Ok(())
123 } else {
124 Err(match stack.last().unwrap() {
125 Nest::Struct(_) => SigErr::UnclosedStruct,
126 Nest::DictEntry(_) => SigErr::UnclosedDictEntry,
127 Nest::Array => SigErr::ArrayWithNoType,
128 })
129 }
130}
131
132impl MarshalledMessageBody {
133 #[inline]
135 pub fn new() -> Self {
136 Self::with_byteorder(ByteOrder::LittleEndian)
137 }
138
139 #[inline]
141 pub fn with_byteorder(b: ByteOrder) -> Self {
142 MarshalledMessageBody {
143 buf: Arc::new(Vec::new()),
144 raw_fds: Vec::new(),
145 sig: SignatureBuffer::new(),
146 byteorder: b,
147 }
148 }
149 #[inline]
150 pub fn from_parts(
151 buf: Vec<u8>,
152 raw_fds: Vec<rustbus_core::wire::UnixFd>,
153 sig: SignatureBuffer,
154 byteorder: ByteOrder,
155 ) -> Self {
156 Self {
157 buf: Arc::new(buf),
158 sig,
159 raw_fds,
160 byteorder,
161 }
162 }
163 #[inline]
164 pub fn sig(&self) -> &str {
165 &self.sig
166 }
167 #[inline]
168 pub fn buf(&self) -> &[u8] {
169 &self.buf
170 }
171 #[inline]
172 pub fn buf_arc(&self) -> Arc<Vec<u8>> {
173 self.buf.clone()
174 }
175 #[inline]
176 pub fn fds(&self) -> &[UnixFd] {
177 &self.raw_fds
178 }
179 #[inline]
180 pub fn byteorder(&self) -> ByteOrder {
181 self.byteorder
182 }
183 #[inline]
187 pub fn get_fds(&self) -> Vec<UnixFd> {
188 self.raw_fds.clone()
189 }
190 pub fn reset(&mut self) {
194 self.sig.clear();
195 Arc::make_mut(&mut self.buf).clear();
196 }
197
198 pub fn reserve(&mut self, additional: usize) {
201 Arc::make_mut(&mut self.buf).reserve(additional)
202 }
203 fn create_ctx2(&mut self) -> (MarshalContext, &mut SignatureBuffer) {
204 (
205 MarshalContext {
206 buf: Arc::make_mut(&mut self.buf),
207 fds: &mut self.raw_fds,
208 byteorder: self.byteorder,
209 },
210 &mut self.sig,
211 )
212 }
213 pub fn push_param_helper<F>(&mut self, push_fn: F) -> Result<(), rustbus_core::Error>
214 where
215 F: FnOnce(&mut MarshalContext, &mut SignatureBuffer) -> Result<(), rustbus_core::Error>,
216 {
217 let fd_pre_cnt = self.raw_fds.len();
218 let buf_pre_len = self.buf.len();
219 let sig_pre_len = self.sig.len();
220 let (mut ctx, sig) = self.create_ctx2();
221 match push_fn(&mut ctx, sig) {
222 Err(e) => {
223 self.raw_fds.truncate(fd_pre_cnt);
224 Arc::make_mut(&mut self.buf).truncate(buf_pre_len);
225 self.sig.truncate(sig_pre_len).unwrap();
226 Err(e)
227 }
228 Ok(()) => Ok(()),
229 }
230 }
231 fn push_param_core<P: Marshal>(
232 ctx: &mut MarshalContext,
233 sig: &mut SignatureBuffer,
234 p: P,
235 ) -> Result<(), rustbus_core::Error> {
236 p.marshal(ctx)?;
237 let pre_len = sig.len();
238 P::sig_str(sig);
239 if sig.len() > 255 {
240 let sig_err = rustbus_core::signature::Error::TooManyTypes;
241 let val_err = rustbus_core::ValError::InvalidSignature(sig_err);
242 Err(rustbus_core::Error::Validation(val_err))
243 } else if let Err(err) = validate_sig_str(&sig[pre_len..]) {
244 if !matches!(err, SigErr::ArraysTooNested | SigErr::StructsTooNested) {
245 panic!(
246 "Invalid segment of signature added '{}'!: {:?}",
247 &sig[pre_len..],
248 err
249 );
250 }
251 let sig_err = rustbus_core::signature::Error::NestingTooDeep;
252 let val_err = rustbus_core::ValError::InvalidSignature(sig_err);
253 Err(rustbus_core::Error::Validation(val_err))
254 } else {
255 Ok(())
256 }
257 }
258 pub fn push_param<P: Marshal>(&mut self, p: P) -> Result<(), rustbus_core::Error> {
260 let push_fn = move |ctx: &mut MarshalContext, sig: &mut SignatureBuffer| {
261 Self::push_param_core(ctx, sig, p)
262 };
263 self.push_param_helper(push_fn)
264 }
265 pub fn push_param2<P1: Marshal, P2: Marshal>(
267 &mut self,
268 p1: P1,
269 p2: P2,
270 ) -> Result<(), rustbus_core::Error> {
271 let push_fn = move |ctx: &mut MarshalContext, sig: &mut SignatureBuffer| {
272 Self::push_param_core(ctx, sig, p1)?;
273 Self::push_param_core(ctx, sig, p2)
274 };
275 self.push_param_helper(push_fn)
276 }
277
278 pub fn push_param3<P1: Marshal, P2: Marshal, P3: Marshal>(
280 &mut self,
281 p1: P1,
282 p2: P2,
283 p3: P3,
284 ) -> Result<(), rustbus_core::Error> {
285 let push_fn = move |ctx: &mut MarshalContext, sig: &mut SignatureBuffer| {
286 Self::push_param_core(ctx, sig, p1)?;
287 Self::push_param_core(ctx, sig, p2)?;
288 Self::push_param_core(ctx, sig, p3)
289 };
290 self.push_param_helper(push_fn)
291 }
292
293 pub fn push_param4<P1: Marshal, P2: Marshal, P3: Marshal, P4: Marshal>(
295 &mut self,
296 p1: P1,
297 p2: P2,
298 p3: P3,
299 p4: P4,
300 ) -> Result<(), rustbus_core::Error> {
301 let push_fn = move |ctx: &mut MarshalContext, sig: &mut SignatureBuffer| {
302 Self::push_param_core(ctx, sig, p1)?;
303 Self::push_param_core(ctx, sig, p2)?;
304 Self::push_param_core(ctx, sig, p3)?;
305 Self::push_param_core(ctx, sig, p4)
306 };
307 self.push_param_helper(push_fn)
308 }
309
310 pub fn push_param5<P1: Marshal, P2: Marshal, P3: Marshal, P4: Marshal, P5: Marshal>(
312 &mut self,
313 p1: P1,
314 p2: P2,
315 p3: P3,
316 p4: P4,
317 p5: P5,
318 ) -> Result<(), rustbus_core::Error> {
319 let push_fn = move |ctx: &mut MarshalContext, sig: &mut SignatureBuffer| {
320 Self::push_param_core(ctx, sig, p1)?;
321 Self::push_param_core(ctx, sig, p2)?;
322 Self::push_param_core(ctx, sig, p3)?;
323 Self::push_param_core(ctx, sig, p4)?;
324 Self::push_param_core(ctx, sig, p5)
325 };
326 self.push_param_helper(push_fn)
327 }
328
329 pub fn push_params<P: Marshal>(&mut self, params: &[P]) -> Result<(), rustbus_core::Error> {
331 let push_fn = move |ctx: &mut MarshalContext, sig: &mut SignatureBuffer| {
332 for p in params {
333 Self::push_param_core(ctx, sig, p)?;
334 }
335 Ok(())
336 };
337 self.push_param_helper(push_fn)
338 }
339
340 pub fn push_variant<P: Marshal>(&mut self, p: P) -> Result<(), rustbus_core::Error> {
342 let push_fn = move |ctx: &mut MarshalContext, sig: &mut SignatureBuffer| {
343 p.marshal_as_variant(ctx)?;
344 sig.push_static("v");
345 if sig.len() > 255 {
346 let sig_err = rustbus_core::signature::Error::TooManyTypes;
347 let val_err = rustbus_core::ValError::InvalidSignature(sig_err);
348 Err(rustbus_core::Error::Validation(val_err))
349 } else {
350 Ok(())
351 }
352 };
353 self.push_param_helper(push_fn)
354 }
355 pub fn validate(&self) -> Result<(), rustbus_core::wire::unmarshal::Error> {
357 if self.sig.is_empty() && self.buf.is_empty() {
358 return Ok(());
359 }
360 let types = rustbus_core::signature::Type::parse_description(&self.sig)?;
361 let mut used = 0;
362 for typ in types {
363 used += validate_raw::validate_marshalled(self.byteorder, used, &self.buf, &typ)
364 .map_err(|(_, e)| e)?;
365 }
366 if used == self.buf.len() {
367 Ok(())
368 } else {
369 Err(rustbus_core::wire::unmarshal::Error::NotAllBytesUsed)
370 }
371 }
372 #[inline]
374 pub fn parser(&self) -> MessageBodyParser {
375 MessageBodyParser::new(self)
376 }
377}
378
379#[derive(Debug)]
387pub struct MessageBodyParser<'body> {
388 buf_idx: usize,
389 sig_idx: usize,
390 sigs: Vec<rustbus_core::signature::Type>,
391 body: &'body MarshalledMessageBody,
392}
393
394impl<'ret, 'fds, 'body: 'ret + 'fds> MessageBodyParser<'body> {
395 pub fn new(body: &'body MarshalledMessageBody) -> Self {
396 let sigs = match rustbus_core::signature::Type::parse_description(&body.sig) {
397 Ok(sigs) => sigs,
398 Err(e) => match e {
399 rustbus_core::signature::Error::EmptySignature => Vec::new(),
400 _ => panic!("MarshalledMessageBody has bad signature: {:?}", e),
401 },
402 };
403 Self {
404 buf_idx: 0,
405 sig_idx: 0,
406 sigs,
407 body,
408 }
409 }
410
411 pub fn get_next_sig(&self) -> Option<&rustbus_core::signature::Type> {
413 self.sigs.get(self.sig_idx)
414 }
415
416 pub fn get_left_sigs(&self) -> Option<&[rustbus_core::signature::Type]> {
418 self.sigs.get(self.sig_idx..)
419 }
420
421 pub fn get<T: Unmarshal<'body, 'fds>>(
424 &mut self,
425 ) -> Result<T, rustbus_core::wire::unmarshal::Error> {
426 if self.sig_idx >= self.sigs.len() {
427 return Err(rustbus_core::wire::unmarshal::Error::EndOfMessage);
428 }
429 if self.sigs[self.sig_idx] != T::signature() {
430 return Err(rustbus_core::wire::unmarshal::Error::WrongSignature);
431 }
432
433 let mut ctx = UnmarshalContext {
434 byteorder: self.body.byteorder,
435 buf: &self.body.buf,
436 offset: self.buf_idx,
437 fds: &self.body.raw_fds,
438 };
439 match T::unmarshal(&mut ctx) {
440 Ok((bytes, res)) => {
441 self.buf_idx += bytes;
442 self.sig_idx += 1;
443 Ok(res)
444 }
445 Err(e) => Err(e),
446 }
447 }
448 fn get_mult_helper<T, F>(
450 &mut self,
451 count: usize,
452 get_calls: F,
453 ) -> Result<T, rustbus_core::wire::unmarshal::Error>
454 where
455 F: FnOnce(&mut Self) -> Result<T, rustbus_core::wire::unmarshal::Error>,
456 {
457 if self.sig_idx + count > self.sigs.len() {
458 return Err(rustbus_core::wire::unmarshal::Error::EndOfMessage);
459 }
460 let start_sig_idx = self.sig_idx;
461 let start_buf_idx = self.buf_idx;
462 match get_calls(self) {
463 Ok(ret) => Ok(ret),
464 Err(err) => {
465 self.sig_idx = start_sig_idx;
466 self.buf_idx = start_buf_idx;
467 Err(err)
468 }
469 }
470 }
471
472 pub fn get2<T1, T2>(&mut self) -> Result<(T1, T2), rustbus_core::wire::unmarshal::Error>
475 where
476 T1: Unmarshal<'body, 'fds>,
477 T2: Unmarshal<'body, 'fds>,
478 {
479 let get_calls = |parser: &mut Self| {
480 let ret1 = parser.get()?;
481 let ret2 = parser.get()?;
482 Ok((ret1, ret2))
483 };
484 self.get_mult_helper(2, get_calls)
485 }
486
487 pub fn get3<T1, T2, T3>(&mut self) -> Result<(T1, T2, T3), rustbus_core::wire::unmarshal::Error>
490 where
491 T1: Unmarshal<'body, 'fds>,
492 T2: Unmarshal<'body, 'fds>,
493 T3: Unmarshal<'body, 'fds>,
494 {
495 let get_calls = |parser: &mut Self| {
496 let ret1 = parser.get()?;
497 let ret2 = parser.get()?;
498 let ret3 = parser.get()?;
499 Ok((ret1, ret2, ret3))
500 };
501 self.get_mult_helper(3, get_calls)
502 }
503
504 pub fn get4<T1, T2, T3, T4>(
507 &mut self,
508 ) -> Result<(T1, T2, T3, T4), rustbus_core::wire::unmarshal::Error>
509 where
510 T1: Unmarshal<'body, 'fds>,
511 T2: Unmarshal<'body, 'fds>,
512 T3: Unmarshal<'body, 'fds>,
513 T4: Unmarshal<'body, 'fds>,
514 {
515 let get_calls = |parser: &mut Self| {
516 let ret1 = parser.get()?;
517 let ret2 = parser.get()?;
518 let ret3 = parser.get()?;
519 let ret4 = parser.get()?;
520 Ok((ret1, ret2, ret3, ret4))
521 };
522 self.get_mult_helper(4, get_calls)
523 }
524
525 pub fn get5<T1, T2, T3, T4, T5>(
528 &mut self,
529 ) -> Result<(T1, T2, T3, T4, T5), rustbus_core::wire::unmarshal::Error>
530 where
531 T1: Unmarshal<'body, 'fds>,
532 T2: Unmarshal<'body, 'fds>,
533 T3: Unmarshal<'body, 'fds>,
534 T4: Unmarshal<'body, 'fds>,
535 T5: Unmarshal<'body, 'fds>,
536 {
537 let get_calls = |parser: &mut Self| {
538 let ret1 = parser.get()?;
539 let ret2 = parser.get()?;
540 let ret3 = parser.get()?;
541 let ret4 = parser.get()?;
542 let ret5 = parser.get()?;
543 Ok((ret1, ret2, ret3, ret4, ret5))
544 };
545 self.get_mult_helper(5, get_calls)
546 }
547}
548
549#[test]
550fn test_marshal_trait() {
551 let mut body = MarshalledMessageBody::new();
552 let bytes: &[&[_]] = &[&[4u64]];
553 body.push_param(bytes).unwrap();
554
555 assert_eq!(
556 [12, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0],
557 &body.buf[..]
558 );
559 assert_eq!(body.sig.as_str(), "aat");
560
561 let mut body = MarshalledMessageBody::new();
562 let mut map = std::collections::HashMap::new();
563 map.insert("a", 4u32);
564
565 body.push_param(&map).unwrap();
566 assert_eq!(
567 [12, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, b'a', 0, 0, 0, 4, 0, 0, 0,],
568 &body.buf[..]
569 );
570 assert_eq!(body.sig.as_str(), "a{su}");
571
572 let mut body = MarshalledMessageBody::new();
573 body.push_param((11u64, "str", true)).unwrap();
574 assert_eq!(body.sig.as_str(), "(tsb)");
575 assert_eq!(
576 [11, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, b's', b't', b'r', 0, 1, 0, 0, 0,],
577 &body.buf[..]
578 );
579
580 struct MyStruct {
581 x: u64,
582 y: String,
583 }
584
585 use rustbus_core::wire::marshal::traits::Signature;
586 use rustbus_core::wire::marshal::MarshalContext;
587 impl Signature for &MyStruct {
588 fn signature() -> rustbus_core::signature::Type {
589 rustbus_core::signature::Type::Container(rustbus_core::signature::Container::Struct(
590 rustbus_core::signature::StructTypes::new(vec![
591 u64::signature(),
592 String::signature(),
593 ])
594 .unwrap(),
595 ))
596 }
597
598 fn alignment() -> usize {
599 8
600 }
601 }
602 impl Marshal for &MyStruct {
603 fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), rustbus_core::Error> {
604 ctx.align_to(8);
606 self.x.marshal(ctx)?;
607 self.y.marshal(ctx)?;
608 Ok(())
609 }
610 }
611
612 let mut body = MarshalledMessageBody::new();
613 body.push_param(&MyStruct {
614 x: 100,
615 y: "A".to_owned(),
616 })
617 .unwrap();
618 assert_eq!(body.sig.as_str(), "(ts)");
619 assert_eq!(
620 [100, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, b'A', 0,],
621 &body.buf[..]
622 );
623
624 let mut body = MarshalledMessageBody::new();
625 let emptymap: std::collections::HashMap<&str, u32> = std::collections::HashMap::new();
626 let mut map = std::collections::HashMap::new();
627 let mut map2 = std::collections::HashMap::new();
628 map.insert("a", 4u32);
629 map2.insert("a", &map);
630
631 body.push_param(&map2).unwrap();
632 body.push_param(&emptymap).unwrap();
633 assert_eq!(body.sig.as_str(), "a{sa{su}}a{su}");
634 assert_eq!(
635 [
636 28, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, b'a', 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
637 0, b'a', 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0
638 ],
639 &body.buf[..]
640 );
641
642 let mut body_iter = MessageBodyParser::new(&body);
644
645 type WrongNestedDict =
647 std::collections::HashMap<String, std::collections::HashMap<String, u64>>;
648 assert_eq!(
649 body_iter.get::<WrongNestedDict>().err().unwrap(),
650 rustbus_core::wire::unmarshal::Error::WrongSignature
651 );
652 type WrongStruct = (u64, i32, String);
653 assert_eq!(
654 body_iter.get::<WrongStruct>().err().unwrap(),
655 rustbus_core::wire::unmarshal::Error::WrongSignature
656 );
657
658 type NestedDict = std::collections::HashMap<String, std::collections::HashMap<String, u32>>;
660 let newmap2: NestedDict = body_iter.get().unwrap();
661 assert_eq!(newmap2.len(), 1);
662 assert_eq!(newmap2.get("a").unwrap().len(), 1);
663 assert_eq!(*newmap2.get("a").unwrap().get("a").unwrap(), 4);
664
665 assert_eq!(
667 body_iter.get::<WrongNestedDict>().err().unwrap(),
668 rustbus_core::wire::unmarshal::Error::WrongSignature
669 );
670 assert_eq!(
671 body_iter.get::<WrongStruct>().err().unwrap(),
672 rustbus_core::wire::unmarshal::Error::WrongSignature
673 );
674
675 let newemptymap: std::collections::HashMap<&str, u32> = body_iter.get().unwrap();
677 assert_eq!(newemptymap.len(), 0);
678
679 let mut body_iter = body.parser();
681 assert_eq!(
682 body_iter.get2::<NestedDict, u16>().unwrap_err(),
683 rustbus_core::wire::unmarshal::Error::WrongSignature
684 );
685 assert_eq!(
686 body_iter
687 .get3::<NestedDict, std::collections::HashMap<&str, u32>, u32>()
688 .unwrap_err(),
689 rustbus_core::wire::unmarshal::Error::EndOfMessage
690 );
691
692 let (newmap2, newemptymap): (NestedDict, std::collections::HashMap<&str, u32>) =
695 body_iter.get2().unwrap();
696 assert_eq!(newmap2.len(), 1);
698 assert_eq!(newmap2.get("a").unwrap().len(), 1);
699 assert_eq!(*newmap2.get("a").unwrap().get("a").unwrap(), 4);
700 assert_eq!(newemptymap.len(), 0);
701 assert_eq!(
702 body_iter.get::<u16>().unwrap_err(),
703 rustbus_core::wire::unmarshal::Error::EndOfMessage
704 );
705
706 let mut body_iter = body.parser();
708
709 let newmap2: NestedDict = body_iter.get().unwrap();
712 assert_eq!(newmap2.len(), 1);
714 assert_eq!(newmap2.get("a").unwrap().len(), 1);
715 assert_eq!(*newmap2.get("a").unwrap().get("a").unwrap(), 4);
716}
717
718#[cfg(test)]
719mod tests {
720 use super::{validate_sig_str, SigErr};
721 use rustbus::params::validate_signature;
722
723 #[test]
724 fn test_validate_sig_str() {
725 for _ in 0..1000000 {
726 validate_sig_str("aaai").unwrap();
727 validate_sig_str("a{ii}").unwrap();
728 validate_sig_str("(ii)").unwrap();
729 validate_sig_str("(i)").unwrap();
730 validate_sig_str("a{i(i)}").unwrap();
731 assert_eq!(validate_sig_str("{ii}"), Err(SigErr::DictEntryNotInArray));
738 assert_eq!(
739 validate_sig_str("a{i(i})"),
740 Err(SigErr::UnexpectedClosingBracket)
741 );
742 assert_eq!(
743 validate_sig_str("()"),
744 Err(SigErr::UnexpectedClosingParenthesis)
745 );
746 assert_eq!(
747 validate_sig_str("a{}"),
748 Err(SigErr::UnexpectedClosingBracket)
749 );
750 assert_eq!(
751 validate_sig_str("a{iii}"),
752 Err(SigErr::TooManyTypesInDictEntry)
753 );
754 assert_eq!(validate_sig_str("((i)"), Err(SigErr::UnclosedStruct));
755 assert_eq!(
756 validate_sig_str("(i))"),
757 Err(SigErr::UnexpectedClosingParenthesis)
758 );
759 assert_eq!(validate_sig_str("a{{i}i}"), Err(SigErr::NonBaseDictKey));
760 assert_eq!(
761 validate_sig_str("a{ii}}"),
762 Err(SigErr::UnexpectedClosingBracket)
763 );
764 assert_eq!(validate_sig_str("!!!"), Err(SigErr::UnknownCharacter));
765 assert_eq!(
766 validate_sig_str(std::str::from_utf8(&[b'b'; 256]).unwrap()),
767 Err(SigErr::TooLong)
768 );
769 assert_eq!(validate_sig_str("(i)a"), Err(SigErr::ArrayWithNoType));
770 }
771 }
772 #[test]
773 fn test_rb_validate_signature() {
774 for _ in 0..1000000 {
775 validate_signature("aaai").unwrap();
776 validate_signature("a{ii}").unwrap();
777 validate_signature("(ii)").unwrap();
778 validate_signature("(i)").unwrap();
779 validate_signature("a{i(i)}").unwrap();
780 validate_signature("").unwrap();
781 validate_signature("{ii}").unwrap_err();
786 validate_signature("a{i(i})").unwrap_err();
787 validate_signature("()").unwrap();
788 validate_signature("a{}").unwrap_err();
789 validate_signature("a{iii}").unwrap_err();
790 validate_signature("((i)").unwrap_err();
791 validate_signature("(i))").unwrap_err();
792 validate_signature("a{{i}i}").unwrap_err();
793 validate_signature("a{ii}}").unwrap_err();
794 validate_signature("!!!").unwrap_err();
795 validate_signature(std::str::from_utf8(&[b'b'; 256]).unwrap()).unwrap_err();
796 validate_signature("(i)a").unwrap_err();
797 }
798 }
799}