fidl_codec/
decode.rs

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