1use fidl_constants::{ALLOC_PRESENT_U32, ALLOC_PRESENT_U64};
6use nom::bytes::complete::take;
7use nom::combinator::{map, value, verify};
8use nom::multi::count;
9use nom::sequence::{pair, preceded, terminated};
10use nom::{IResult, Parser};
11
12use fidl_data_zx::{DEFAULT_CHANNEL_RIGHTS, ObjType as ObjectType, Rights};
13
14use crate::error::{Error, Result};
15use crate::handle::*;
16use crate::library;
17use crate::transaction::{TransactionHeader, decode_transaction_header};
18use crate::util::*;
19use crate::value::Value;
20
21use std::str;
22
23type DResult<'a, R> = IResult<&'a [u8], R, Error>;
24
25enum Defer<'d> {
30 Complete(Value),
32
33 Action(
35 Box<
36 dyn for<'a> FnOnce(
37 &'a [u8],
38 &mut Vec<HandleInfo>,
39 RecursionCounter,
40 ) -> DResult<'a, Value>
41 + 'd,
42 >,
43 ),
44}
45
46impl<'d> Defer<'d> {
47 fn complete<'a>(
49 self,
50 data: &'a [u8],
51 handles: &mut Vec<HandleInfo>,
52 counter: RecursionCounter,
53 ) -> DResult<'a, Value> {
54 match self {
55 Defer::Complete(v) => Ok((data, v)),
56 Defer::Action(act) => act(data, handles, counter),
57 }
58 }
59}
60
61impl<'d> From<Value> for Defer<'d> {
62 fn from(v: Value) -> Defer<'d> {
63 Defer::Complete(v)
64 }
65}
66
67fn take_u8(data: &[u8]) -> DResult<'_, u8> {
68 map(take(1usize), |x: &[u8]| x[0]).parse(data)
69}
70
71fn value_u8(data: &[u8]) -> DResult<'_, Value> {
72 map(take_u8, Value::U8).parse(data)
73}
74
75fn value_bool(data: &[u8]) -> DResult<'_, Value> {
76 map(verify(take_u8, |&x| x == 0 || x == 1), |x| Value::Bool(x != 0)).parse(data)
77}
78
79fn take_u16(data: &[u8]) -> DResult<'_, u16> {
80 map(take(2usize), |x: &[u8]| u16::from_le_bytes(x.try_into().unwrap())).parse(data)
81}
82
83fn value_u16(data: &[u8]) -> DResult<'_, Value> {
84 map(take_u16, Value::U16).parse(data)
85}
86
87fn take_u32(data: &[u8]) -> DResult<'_, u32> {
88 map(take(4usize), |x: &[u8]| u32::from_le_bytes(x.try_into().unwrap())).parse(data)
89}
90
91fn value_u32(data: &[u8]) -> DResult<'_, Value> {
92 map(take_u32, Value::U32).parse(data)
93}
94
95fn take_u64(data: &[u8]) -> DResult<'_, u64> {
96 map(take(8usize), |x: &[u8]| u64::from_le_bytes(x.try_into().unwrap())).parse(data)
97}
98
99fn value_u64(data: &[u8]) -> DResult<'_, Value> {
100 map(take_u64, Value::U64).parse(data)
101}
102
103fn take_i8(data: &[u8]) -> DResult<'_, i8> {
104 map(take(1usize), |x: &[u8]| i8::from_le_bytes([x[0]])).parse(data)
105}
106
107fn value_i8(data: &[u8]) -> DResult<'_, Value> {
108 map(take_i8, Value::I8).parse(data)
109}
110
111fn take_i16(data: &[u8]) -> DResult<'_, i16> {
112 map(take(2usize), |x: &[u8]| i16::from_le_bytes(x.try_into().unwrap())).parse(data)
113}
114
115fn value_i16(data: &[u8]) -> DResult<'_, Value> {
116 map(take_i16, Value::I16).parse(data)
117}
118
119fn take_i32(data: &[u8]) -> DResult<'_, i32> {
120 map(take(4usize), |x: &[u8]| i32::from_le_bytes(x.try_into().unwrap())).parse(data)
121}
122
123fn value_i32(data: &[u8]) -> DResult<'_, Value> {
124 map(take_i32, Value::I32).parse(data)
125}
126
127fn take_i64(data: &[u8]) -> DResult<'_, i64> {
128 map(take(8usize), |x: &[u8]| i64::from_le_bytes(x.try_into().unwrap())).parse(data)
129}
130
131fn value_i64(data: &[u8]) -> DResult<'_, Value> {
132 map(take_i64, Value::I64).parse(data)
133}
134
135fn take_f32(data: &[u8]) -> DResult<'_, f32> {
136 map(take(4usize), |x: &[u8]| f32::from_le_bytes(x.try_into().unwrap())).parse(data)
137}
138
139fn value_f32(data: &[u8]) -> DResult<'_, Value> {
140 map(take_f32, Value::F32).parse(data)
141}
142
143fn take_f64(data: &[u8]) -> DResult<'_, f64> {
144 map(take(8usize), |x: &[u8]| f64::from_le_bytes(x.try_into().unwrap())).parse(data)
145}
146
147fn value_f64(data: &[u8]) -> DResult<'_, Value> {
148 map(take_f64, Value::F64).parse(data)
149}
150
151fn transaction_header(data: &[u8]) -> DResult<'_, TransactionHeader> {
152 decode_transaction_header(data)
153 .map(|(a, b)| (b, a))
154 .map_err(|e| Error::DecodeError(format!("Invalid FIDL transaction header ({e:?})")).into())
155}
156
157fn take_padding(amount: usize) -> impl Fn(&[u8]) -> DResult<'_, ()> {
158 move |bytes| value((), verify(take(amount), |x: &[u8]| x.iter().all(|&x| x == 0))).parse(bytes)
159}
160
161fn decode_struct<'s>(
162 ns: &'s library::Namespace,
163 st: &'s library::Struct,
164 nullable: bool,
165) -> impl Fn(&[u8]) -> DResult<'_, Defer<'s>> {
166 move |bytes: &[u8]| {
167 if !nullable {
168 return decode_struct_nonnull(ns, st).parse(bytes);
169 }
170
171 let (bytes, presence) = take_u64(bytes)?;
172
173 if presence == 0 {
174 Ok((bytes, Defer::Complete(Value::Null)))
175 } else if presence != ALLOC_PRESENT_U64 {
176 Err(Error::DecodeError("Bad presence indicator".to_owned()).into())
177 } else {
178 Ok((
179 bytes,
180 Defer::Action(Box::new(
181 move |bytes: &[u8],
182 handles: &mut Vec<HandleInfo>,
183 counter: RecursionCounter| {
184 let counter = counter.next()?;
185 let align = alignment_padding_for_size(st.size);
186 let (bytes, defer) =
187 terminated(decode_struct_nonnull(ns, st), take_padding(align))
188 .parse(bytes)?;
189 defer.complete(bytes, handles, counter)
190 },
191 )),
192 ))
193 }
194 }
195}
196
197fn decode_struct_nonnull<'s>(
198 ns: &'s library::Namespace,
199 st: &'s library::Struct,
200) -> impl Fn(&[u8]) -> DResult<'_, Defer<'s>> {
201 move |mut bytes: &[u8]| {
202 let mut offset = 0;
203 let mut fields = Vec::new();
204
205 for member in &st.members {
206 let (remaining, result) =
207 preceded(take_padding(member.offset - offset), decode_type(ns, &member.ty))
208 .parse(bytes)?;
209 fields.push((member.name.clone(), result));
210 bytes = remaining;
211 offset = member.offset + member.ty.inline_size(ns)?;
212 }
213
214 if offset < st.size {
215 let (remaining, _) = take_padding(st.size - offset).parse(bytes)?;
216 bytes = remaining;
217 }
218
219 Ok((
220 bytes,
221 Defer::Action(Box::new(
222 move |mut bytes: &[u8],
223 handles: &mut Vec<HandleInfo>,
224 counter: RecursionCounter| {
225 let mut complete_fields = Vec::new();
226
227 for (name, defer) in fields {
228 let (remaining, value) = defer.complete(bytes, handles, counter)?;
229 bytes = remaining;
230 complete_fields.push((name, value))
231 }
232
233 Ok((bytes, Value::Object(complete_fields)))
234 },
235 )),
236 ))
237 }
238}
239
240fn decode_type<'t>(
241 ns: &'t library::Namespace,
242 ty: &'t library::Type,
243) -> impl Fn(&[u8]) -> DResult<'_, Defer<'t>> {
244 use library::Type;
245 move |b: &[u8]| {
246 match ty {
247 Type::Bool => value_bool(b),
248 Type::U8 => value_u8(b),
249 Type::U16 => value_u16(b),
250 Type::U32 => value_u32(b),
251 Type::U64 => value_u64(b),
252 Type::I8 => value_i8(b),
253 Type::I16 => value_i16(b),
254 Type::I32 => value_i32(b),
255 Type::I64 => value_i64(b),
256 Type::F32 => value_f32(b),
257 Type::F64 => value_f64(b),
258 Type::Array(ty, size) => return decode_array(ns, ty, *size).parse(b),
259 Type::Vector { ty, nullable, element_count } => {
260 return decode_vector(ns, ty, *nullable, *element_count).parse(b);
261 }
262 Type::String { nullable, byte_count } => {
263 return decode_string(*nullable, *byte_count).parse(b);
264 }
265 Type::Identifier { name, nullable } => {
266 return decode_identifier(ns, name, *nullable).parse(b);
267 }
268 Type::Handle { object_type, nullable, rights } => {
269 return decode_handle(*object_type, *nullable, *rights).parse(b);
270 }
271 Type::Endpoint { protocol, rights, nullable, role } => match role {
272 library::EndpointRole::Client => {
273 return decode_client_end(
274 protocol.clone(),
275 *nullable,
276 rights.or(Some(DEFAULT_CHANNEL_RIGHTS)),
277 )
278 .parse(b);
279 }
280 library::EndpointRole::Server => {
281 return decode_server_end(
282 protocol.clone(),
283 *nullable,
284 rights.or(Some(DEFAULT_CHANNEL_RIGHTS)),
285 )
286 .parse(b);
287 }
288 },
289 Type::UnknownString(s) => {
290 Err(Error::LibraryError(format!("Unresolved Type: {}", s)).into())
291 }
292 Type::Unknown(library::TypeInfo { identifier: s, .. }) => {
293 return Err(Error::LibraryError(format!(
294 "Unresolved Type: {}",
295 s.as_ref().map_or("<unidentified>", String::as_str)
296 ))
297 .into());
298 }
299 Type::FrameworkError => map(take_u32, |_| Value::Null).parse(b),
300 }
301 .map(|(x, y)| (x, Defer::Complete(y)))
302 }
303}
304
305fn complete_deferred_list<'a>(
307 bytes: &'a [u8],
308 handles: &mut Vec<HandleInfo>,
309 defers: Vec<Defer<'_>>,
310 counter: RecursionCounter,
311) -> DResult<'a, Value> {
312 let mut bytes = bytes;
313 let mut values = Vec::new();
314
315 for defer in defers {
316 let (next_bytes, value) = defer.complete(bytes, handles, counter)?;
317 bytes = next_bytes;
318 values.push(value)
319 }
320
321 Ok((bytes, Value::List(values)))
322}
323
324fn decode_array<'t>(
325 ns: &'t library::Namespace,
326 ty: &'t library::Type,
327 size: usize,
328) -> impl Fn(&[u8]) -> DResult<'_, Defer<'t>> {
329 move |bytes: &[u8]| {
330 let (bytes, defers) = count(decode_type(ns, ty), size).parse(bytes)?;
331
332 Ok((
333 bytes,
334 Defer::Action(Box::new(
335 move |bytes: &[u8], handles: &mut Vec<HandleInfo>, counter: RecursionCounter| {
336 complete_deferred_list(bytes, handles, defers, counter)
337 },
338 )),
339 ))
340 }
341}
342
343fn decode_vector<'t>(
344 ns: &'t library::Namespace,
345 ty: &'t library::Type,
346 nullable: bool,
347 element_count: Option<usize>,
348) -> impl Fn(&[u8]) -> DResult<'_, Defer<'t>> {
349 move |bytes: &[u8]| {
350 let (bytes, (size, presence)) = pair(take_u64, take_u64).parse(bytes)?;
351 let size = size as usize;
352 let Some(byte_count) = size.checked_mul(ty.inline_size(ns)?) else {
353 return Err(Error::DecodeError("Vector too long".to_owned()).into());
354 };
355 let align = alignment_padding_for_size(byte_count);
356
357 if presence == 0 {
358 if nullable {
359 if size == 0 {
360 Ok((bytes, Defer::Complete(Value::Null)))
361 } else {
362 Err(Error::DecodeError("Absent vector had a size".to_owned()).into())
363 }
364 } else {
365 Err(Error::DecodeError("Missing non-nullable vector".to_owned()).into())
366 }
367 } else if presence != ALLOC_PRESENT_U64 {
368 Err(Error::DecodeError("Bad presence indicator".to_owned()).into())
369 } else if element_count.map(|x| x < size).unwrap_or(false) {
370 Err(Error::DecodeError("Vector too long".to_owned()).into())
371 } else {
372 Ok((
373 bytes,
374 Defer::Action(Box::new(
375 move |bytes: &[u8],
376 handles: &mut Vec<HandleInfo>,
377 counter: RecursionCounter| {
378 let counter = counter.next()?;
379 let (bytes, defers) =
380 terminated(count(decode_type(ns, ty), size), take_padding(align))
381 .parse(bytes)?;
382
383 complete_deferred_list(bytes, handles, defers, counter)
384 },
385 )),
386 ))
387 }
388 }
389}
390
391fn decode_string(
392 nullable: bool,
393 byte_count: Option<usize>,
394) -> impl Fn(&[u8]) -> DResult<'_, Defer<'static>> {
395 move |bytes: &[u8]| {
396 let (bytes, (size, presence)) = pair(take_u64, take_u64).parse(bytes)?;
397 let size = size as usize;
398 let align = alignment_padding_for_size(size);
399
400 if presence == 0 {
401 if nullable {
402 if size == 0 {
403 Ok((bytes, Defer::Complete(Value::Null)))
404 } else {
405 Err(Error::DecodeError("Absent string had a size".to_owned()).into())
406 }
407 } else {
408 Err(Error::DecodeError("Missing non-nullable string".to_owned()).into())
409 }
410 } else if presence != ALLOC_PRESENT_U64 {
411 Err(Error::DecodeError("Bad presence indicator".to_owned()).into())
412 } else if byte_count.map(|x| x < size).unwrap_or(false) {
413 Err(Error::DecodeError("String too long".to_owned()).into())
414 } else {
415 Ok((
416 bytes,
417 Defer::Action(Box::new(
418 move |bytes: &[u8], _: &mut Vec<HandleInfo>, counter: RecursionCounter| {
419 let _counter = counter.next()?;
420 let (bytes, data) =
421 terminated(take(size), take_padding(align)).parse(bytes)?;
422
423 match str::from_utf8(data) {
424 Ok(x) => Ok((bytes, Value::String(x.to_owned()))),
425 Err(x) => Err(Error::Utf8Error(x).into()),
426 }
427 },
428 )),
429 ))
430 }
431 }
432}
433
434fn decode_server_end(
435 interface: String,
436 nullable: bool,
437 rights: Option<Rights>,
438) -> impl Fn(&[u8]) -> DResult<'_, Defer<'static>> {
439 decode_handle_with(
440 interface,
441 nullable,
442 &|x, y, z| Value::ServerEnd(x.into(), y, z),
443 Some(ObjectType::Channel),
444 rights,
445 )
446}
447
448fn decode_client_end(
449 interface: String,
450 nullable: bool,
451 rights: Option<Rights>,
452) -> impl Fn(&[u8]) -> DResult<'_, Defer<'static>> {
453 decode_handle_with(
454 interface,
455 nullable,
456 &|x, y, z| Value::ClientEnd(x.into(), y, z),
457 Some(ObjectType::Channel),
458 rights,
459 )
460}
461
462fn decode_handle(
463 handle_type: ObjectType,
464 nullable: bool,
465 rights: Option<Rights>,
466) -> impl Fn(&[u8]) -> DResult<'_, Defer<'static>> {
467 decode_handle_with(handle_type, nullable, &Value::Handle, None, rights)
468}
469
470fn decode_handle_with<T: Clone + 'static>(
471 handle_type: T,
472 nullable: bool,
473 value_builder: &'static (impl Fn(NullableHandle, T, Option<Rights>) -> Value + 'static),
474 constrain_type: Option<ObjectType>,
475 constrain_rights: Option<Rights>,
476) -> impl Fn(&[u8]) -> DResult<'_, Defer<'static>> {
477 move |bytes: &[u8]| {
478 let handle_type = handle_type.clone();
479 let (bytes, presence) = take_u32(bytes)?;
480
481 if presence == 0 {
482 if nullable {
483 Ok((bytes, Defer::Complete(Value::Null)))
484 } else {
485 Err(Error::DecodeError("Missing non-nullable handle".to_owned()).into())
486 }
487 } else if presence != ALLOC_PRESENT_U32 {
488 Err(Error::DecodeError("Bad presence indicator".to_owned()).into())
489 } else {
490 Ok((
491 bytes,
492 Defer::Action(Box::new(
493 move |bytes: &[u8], handles: &mut Vec<HandleInfo>, _: RecursionCounter| {
494 if !handles.is_empty() {
495 if constrain_type.map(|x| x == handles[0].object_type()).unwrap_or(true)
496 {
497 let handle_info = handles.remove(0);
498
499 let decoded_rights = match (handle_info.rights(), constrain_rights)
500 {
501 (Rights::SAME_RIGHTS, Some(_)) => Rights::SAME_RIGHTS,
502 (handle_rights, Some(Rights::SAME_RIGHTS)) => handle_rights,
503 (handle_rights, None) => handle_rights,
504 (handle_rights, Some(constrain_rights)) => {
505 if handle_rights.contains(constrain_rights) {
506 constrain_rights
507 } else {
508 let mut missing = constrain_rights;
509 missing.remove(handle_rights);
510 return Err(Error::DecodeError(format!(
511 "Insufficient handle rights, need {missing:?}"
512 ))
513 .into());
514 }
515 }
516 };
517
518 Ok((
519 bytes,
520 value_builder(
521 handle_info.into_handle(),
522 handle_type,
523 Some(decoded_rights),
524 ),
525 ))
526 } else {
527 Err(Error::DecodeError("Wrong handle type".to_owned()).into())
528 }
529 } else {
530 Err(Error::DecodeError("Too few handles".to_owned()).into())
531 }
532 },
533 )),
534 ))
535 }
536 }
537}
538
539fn decode_enum<'e>(
540 ns: &'e library::Namespace,
541 en: &'e library::Enum,
542) -> impl Fn(&[u8]) -> DResult<'_, Defer<'e>> {
543 move |bytes: &[u8]| {
544 let (bytes, defer) = decode_type(ns, &en.ty).parse(bytes)?;
545 Ok((
546 bytes,
547 Defer::Action(Box::new(
548 move |bytes: &[u8], handles: &mut Vec<HandleInfo>, counter: RecursionCounter| {
549 let (bytes, value) = defer.complete(bytes, handles, counter)?;
550
551 for member in &en.members {
552 if value == member.value || !en.strict {
553 return Ok((bytes, Value::Enum(en.name.to_owned(), Box::new(value))));
554 }
555 }
556
557 if en.strict {
558 Err(Error::DecodeError("Unknown Enum Variant.".to_owned()).into())
559 } else {
560 Ok((bytes, Value::Enum(en.name.to_owned(), Box::new(value))))
561 }
562 },
563 )),
564 ))
565 }
566}
567
568fn decode_bits<'b>(
569 ns: &'b library::Namespace,
570 bits: &'b library::Bits,
571) -> impl Fn(&[u8]) -> DResult<'_, Defer<'b>> {
572 move |bytes: &[u8]| {
573 let (bytes, defer) = decode_type(ns, &bits.ty).parse(bytes)?;
574 Ok((
575 bytes,
576 Defer::Action(Box::new(
577 move |bytes: &[u8], handles: &mut Vec<HandleInfo>, counter: RecursionCounter| {
578 let (bytes, value) = defer.complete(bytes, handles, counter)?;
579
580 let data = value.bits().ok_or_else(|| {
581 Error::LibraryError("Bits with non-integer type.".to_owned())
582 })?;
583
584 if bits.strict && data != data & bits.mask {
585 Err(Error::DecodeError("Invalid value for bits field.".to_owned()).into())
586 } else {
587 Ok((bytes, Value::Bits(bits.name.to_owned(), Box::new(value))))
588 }
589 },
590 )),
591 ))
592 }
593}
594
595enum Envelope {
597 Present { bytes: u32, handles: u16 },
598 Inline { bytes: [u8; 4], handles: u16 },
599 Empty,
600}
601
602impl Envelope {
603 fn skip(&self) -> Defer<'static> {
604 let (envelope_bytes, envelope_handles) = match self {
605 Envelope::Present { bytes, handles } => (*bytes, *handles),
606 Envelope::Inline { handles, .. } => (0, *handles),
607 Envelope::Empty => return Defer::Complete(Value::Null),
608 };
609
610 Defer::Action(Box::new(
611 move |bytes: &[u8], handles: &mut Vec<HandleInfo>, counter: RecursionCounter| {
612 let _counter = counter.next()?;
613 if (envelope_bytes & 7u32) != 0 {
614 return Err(Error::DecodeError("Invalid envelope size".to_owned()).into());
615 }
616 let envelope_bytes = envelope_bytes as usize;
617 let envelope_handles = envelope_handles as usize;
618
619 if envelope_handles > handles.len() {
620 Err(Error::DecodeError("Insufficient handles for envelope".to_owned()).into())
621 } else if envelope_bytes > bytes.len() {
622 Err(Error::DecodeError("Insufficient bytes for envelope".to_owned()).into())
623 } else {
624 *handles = handles.split_off(envelope_handles);
625 Ok((&bytes[envelope_bytes as usize..], Value::Null))
626 }
627 },
628 ))
629 }
630
631 fn decode_type<'s>(
632 &self,
633 ns: &'s library::Namespace,
634 ty: &'s library::Type,
635 ) -> Result<Defer<'s>> {
636 if let &Envelope::Empty = self {
637 Ok(self.skip())
638 } else if !ty.is_resolved(ns) {
639 Ok(self.skip())
640 } else if let Envelope::Inline { bytes, handles } = self {
641 let (padding, ret) = decode_type(ns, ty).parse(bytes)?;
642 take_padding(padding.len()).parse(padding)?;
643 let expect_handles = *handles as usize;
644 Ok(Defer::Action(Box::new(
645 move |bytes: &[u8], handles: &mut Vec<HandleInfo>, counter: RecursionCounter| {
646 let handle_count = handles.len();
647 let v = ret.complete(bytes, handles, counter)?;
648
649 let handles_used = handle_count - handles.len();
650 if handles_used != expect_handles {
651 Err(Error::DecodeError("Wrong number of handles in envelope".to_owned())
652 .into())
653 } else {
654 Ok(v)
655 }
656 },
657 )))
658 } else if ty.inline_size(ns)? <= 4 {
659 Err(Error::DecodeError("Envelope should be inline".to_owned()))
660 } else {
661 let Envelope::Present { bytes, handles } = self else { unreachable!() };
662 let expect_bytes = *bytes as usize;
663 let expect_handles = *handles as usize;
664 Ok(Defer::Action(Box::new(
665 move |bytes: &[u8], handles: &mut Vec<HandleInfo>, counter: RecursionCounter| {
666 let counter = counter.next()?;
667 let bytes_start = bytes.len();
668 let align = alignment_padding_for_size(ty.inline_size(ns)?);
669 let (bytes, defer) =
670 terminated(decode_type(ns, ty), take_padding(align)).parse(bytes)?;
671
672 let handle_count = handles.len();
673 let (bytes, value) = defer.complete(bytes, handles, counter)?;
674 let handles_used = handle_count - handles.len();
675 let bytes_used = bytes_start - bytes.len();
676 if handles_used != expect_handles {
677 Err(Error::DecodeError("Wrong number of handles in envelope".to_owned())
678 .into())
679 } else if bytes_used != expect_bytes {
680 Err(Error::DecodeError("Wrong number of bytes in envelope".to_owned())
681 .into())
682 } else {
683 Ok((bytes, value))
684 }
685 },
686 )))
687 }
688 }
689
690 fn take<'a>(empty_ok: bool) -> impl Fn(&'a [u8]) -> DResult<'a, Envelope> {
691 move |bytes: &[u8]| {
692 let (bytes, (envelope_bytes, envelope_handles, envelope_flags)) =
693 (take_u32, take_u16, take_u16).parse(bytes)?;
694
695 if envelope_bytes == 0 && envelope_handles == 0 && envelope_flags == 0 {
696 if !empty_ok {
697 Err(Error::DecodeError("Unexpected empty envelope.".to_owned()).into())
698 } else {
699 Ok((bytes, Envelope::Empty))
700 }
701 } else if envelope_flags == 0 {
702 Ok((bytes, Envelope::Present { bytes: envelope_bytes, handles: envelope_handles }))
703 } else if envelope_flags == 1 {
704 Ok((
705 bytes,
706 Envelope::Inline {
707 bytes: envelope_bytes.to_le_bytes(),
708 handles: envelope_handles,
709 },
710 ))
711 } else {
712 Err(Error::DecodeError("Unknown evelope flags.".to_owned()).into())
713 }
714 }
715 }
716}
717
718fn decode_union<'u>(
719 ns: &'u library::Namespace,
720 union: &'u library::TableOrUnion,
721 nullable: bool,
722) -> impl Fn(&[u8]) -> DResult<'_, Defer<'u>> {
723 move |bytes: &[u8]| {
724 let (bytes, (ordinal, envelope)) = (take_u64, Envelope::take(nullable)).parse(bytes)?;
725
726 match (ordinal, &envelope) {
727 (0, Envelope::Empty) => return Ok((bytes, envelope.skip())),
728 (0, _) => return Err(Error::DecodeError("Invalid Union block.".to_owned()).into()),
729 _ => (),
730 };
731
732 match union.members.get(&ordinal) {
733 None if union.strict => {
734 Err(Error::DecodeError("Invalid Union ordinal.".to_owned()).into())
735 }
736 None => Ok((bytes, envelope.skip())),
737 Some(member) => Ok((
738 bytes,
739 Defer::Action(Box::new(
740 move |bytes: &[u8],
741 handles: &mut Vec<HandleInfo>,
742 counter: RecursionCounter| {
743 let (bytes, inner) = envelope
744 .decode_type(ns, &member.ty)?
745 .complete(bytes, handles, counter)?;
746 Ok((
747 bytes,
748 Value::Union(
749 union.name.to_owned(),
750 member.name.to_owned(),
751 Box::new(inner),
752 ),
753 ))
754 },
755 )),
756 )),
757 }
758 }
759}
760
761fn decode_table<'t>(
762 ns: &'t library::Namespace,
763 table: &'t library::TableOrUnion,
764) -> impl Fn(&[u8]) -> DResult<'_, Defer<'t>> {
765 move |bytes: &[u8]| {
766 let (bytes, (size, data_ptr)) = pair(take_u64, take_u64).parse(bytes)?;
767
768 if data_ptr != ALLOC_PRESENT_U64 {
769 return Err(Error::DecodeError("Bad presence indicator.".to_owned()).into());
770 }
771
772 Ok((
773 bytes,
774 Defer::Action(Box::new(
775 move |bytes: &[u8], handles: &mut Vec<HandleInfo>, counter: RecursionCounter| {
776 let counter = counter.next()?;
777 let (mut bytes, envelopes) =
778 count(Envelope::take(true), size as usize).parse(bytes)?;
779
780 let mut result = Vec::new();
781 let mut expect_ord = 1u64;
782 for envelope in envelopes {
783 let member = table.members.get(&expect_ord);
784 expect_ord += 1;
785
786 let next_bytes = if let Some(member) = member {
787 let (next_bytes, val) = envelope
788 .decode_type(ns, &member.ty)?
789 .complete(bytes, handles, counter)?;
790 if !matches!(val, Value::Null) {
791 result.push((member.name.clone(), val));
792 }
793 next_bytes
794 } else {
795 envelope.skip().complete(bytes, handles, counter)?.0
796 };
797
798 bytes = next_bytes;
799 }
800
801 Ok((bytes, Value::Object(result)))
802 },
803 )),
804 ))
805 }
806}
807
808fn decode_identifier<'s>(
809 ns: &'s library::Namespace,
810 name: &'s str,
811 nullable: bool,
812) -> impl Fn(&[u8]) -> DResult<'_, Defer<'s>> {
813 move |bytes: &[u8]| match ns.lookup(name)? {
814 library::LookupResult::Bits(b) => decode_bits(ns, b).parse(bytes),
815 library::LookupResult::Enum(e) => decode_enum(ns, e).parse(bytes),
816 library::LookupResult::Struct(s) => decode_struct(ns, s, nullable).parse(bytes),
817 library::LookupResult::Union(u) => decode_union(ns, u, nullable).parse(bytes),
818 library::LookupResult::Table(t) => decode_table(ns, t).parse(bytes),
819 library::LookupResult::Protocol(_) => Err(Error::DecodeError(format!(
820 "Protocol names cannot be used as identifiers: {}",
821 name
822 ))
823 .into()),
824 }
825}
826
827fn decode_message<'a>(
829 ns: &library::Namespace,
830 direction: Direction,
831 bytes: &'a [u8],
832 mut handles: Vec<HandleInfo>,
833) -> Result<(TransactionHeader, Value)> {
834 let (bytes, header) = transaction_header(bytes)?;
835
836 let (_, method) = ns.lookup_method_ordinal(header.ordinal)?;
837
838 let (message, has) = match direction {
839 Direction::Request => (method.request.as_ref(), method.has_request),
840 Direction::Response => (method.response.as_ref(), method.has_response),
841 };
842
843 if let Some(message) = message {
844 let (bytes, defer) = decode_type(ns, message).parse(bytes)?;
845 let (bytes, value) = defer.complete(bytes, &mut handles, RecursionCounter::new())?;
846
847 if !bytes.is_empty() && (bytes.len() >= 8 || bytes.iter().any(|x| *x != 0)) {
848 Err(Error::DecodeError(format!("{} bytes left over.", bytes.len())))
849 } else if !handles.is_empty() {
850 Err(Error::DecodeError(format!("{} handles left over.", handles.len())))
851 } else {
852 Ok((header, value))
853 }
854 } else if !has {
855 Err(Error::DecodeError(format!(
856 "Header indicates method {}, which has no {}.",
857 method.name,
858 direction.to_string()
859 )))
860 } else {
861 Ok((header, Value::Null))
862 }
863}
864
865pub fn decode_request(
867 ns: &library::Namespace,
868 bytes: &[u8],
869 handles: Vec<HandleInfo>,
870) -> Result<(TransactionHeader, Value)> {
871 decode_message(ns, Direction::Request, bytes, handles)
872}
873
874pub fn decode_response(
876 ns: &library::Namespace,
877 bytes: &[u8],
878 handles: Vec<HandleInfo>,
879) -> Result<(TransactionHeader, Value)> {
880 decode_message(ns, Direction::Response, bytes, handles)
881}
882
883pub fn decode<'a>(
885 ns: &library::Namespace,
886 ty: &str,
887 bytes: &'a [u8],
888 mut handles: Vec<HandleInfo>,
889) -> Result<Value> {
890 if bytes.len() % 8 != 0 {
891 return Err(Error::DecodeError("Unaligned encoded object".to_owned()));
892 }
893 let (bytes, defer) = decode_identifier(ns, ty, false).parse(bytes)?;
894 let (bytes, value) = defer.complete(bytes, &mut handles, RecursionCounter::new())?;
895 take_padding(bytes.len()).parse(bytes)?;
896
897 if !bytes.is_empty() && (bytes.len() >= 8 || bytes.iter().any(|x| *x != 0)) {
898 Err(Error::DecodeError(format!("{} bytes left over.", bytes.len())))
899 } else if !handles.is_empty() {
900 Err(Error::DecodeError(format!("{} handles left over.", handles.len())))
901 } else {
902 Ok(value)
903 }
904}