Skip to main content

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_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
25/// This represents an action that will yield a Value when given further bytes to process and
26/// handles to potentially consume. This is how we implement out-of-line data. The initial parse
27/// takes the inline data, and when we're ready, the Defer can be fed the remaining bytes to take
28/// the out of line data.
29enum Defer<'d> {
30    /// This Defer doesn't need any further processing. We can just offer up the value right now.
31    Complete(Value),
32
33    /// This Defer implements the actual deferred processing pattern described.
34    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    /// Completes a deferred parse and returns the result.
48    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
305/// Given a list of defers, complete them all and turn them into a list of complete values.
306fn 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
595/// Contents of an envelope header.
596enum 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
827/// Decode a FIDL request or response, depending on the direction header.
828fn 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
865/// Decode a FIDL request from a byte buffer and a list of handles.
866pub 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
874/// Decode a FIDL response from a byte buffer and a list of handles.
875pub 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
883/// Decode a FIDL value.
884pub 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}