1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 use crate::metadata::{checksum_metadata, codes};
6 use crate::*;
7 use anyhow::{bail, ensure, Context, Result};
8 
read_metadata(data: &[u8]) -> Result<Metadata>9 pub fn read_metadata(data: &[u8]) -> Result<Metadata> {
10     MetadataReader::new(data).read_metadata()
11 }
12 
13 // Read a metadata type, this is pub so that we can test it in the metadata fixture
read_metadata_type(data: &[u8]) -> Result<Type>14 pub fn read_metadata_type(data: &[u8]) -> Result<Type> {
15     MetadataReader::new(data).read_type()
16 }
17 
18 /// Helper struct for read_metadata()
19 struct MetadataReader<'a> {
20     // This points to the initial data we were passed in
21     initial_data: &'a [u8],
22     // This points to the remaining data to be read
23     buf: &'a [u8],
24 }
25 
26 impl<'a> MetadataReader<'a> {
new(data: &'a [u8]) -> Self27     fn new(data: &'a [u8]) -> Self {
28         Self {
29             initial_data: data,
30             buf: data,
31         }
32     }
33 
34     // Read a top-level metadata item
35     //
36     // This consumes self because MetadataReader is only intended to read a single item.
read_metadata(mut self) -> Result<Metadata>37     fn read_metadata(mut self) -> Result<Metadata> {
38         let value = self.read_u8()?;
39         Ok(match value {
40             codes::NAMESPACE => NamespaceMetadata {
41                 crate_name: self.read_string()?,
42                 name: self.read_string()?,
43             }
44             .into(),
45             codes::UDL_FILE => UdlFile {
46                 module_path: self.read_string()?,
47                 namespace: self.read_string()?,
48                 file_stub: self.read_string()?,
49             }
50             .into(),
51             codes::FUNC => self.read_func()?.into(),
52             codes::CONSTRUCTOR => self.read_constructor()?.into(),
53             codes::METHOD => self.read_method()?.into(),
54             codes::RECORD => self.read_record()?.into(),
55             codes::ENUM => self.read_enum()?.into(),
56             codes::INTERFACE => self.read_object(ObjectImpl::Struct)?.into(),
57             codes::TRAIT_INTERFACE => self.read_object(ObjectImpl::Trait)?.into(),
58             codes::CALLBACK_TRAIT_INTERFACE => self.read_object(ObjectImpl::CallbackTrait)?.into(),
59             codes::CALLBACK_INTERFACE => self.read_callback_interface()?.into(),
60             codes::TRAIT_METHOD => self.read_trait_method()?.into(),
61             codes::UNIFFI_TRAIT => self.read_uniffi_trait()?.into(),
62             _ => bail!("Unexpected metadata code: {value:?}"),
63         })
64     }
65 
read_u8(&mut self) -> Result<u8>66     fn read_u8(&mut self) -> Result<u8> {
67         if !self.buf.is_empty() {
68             let value = self.buf[0];
69             self.buf = &self.buf[1..];
70             Ok(value)
71         } else {
72             bail!("Buffer is empty")
73         }
74     }
75 
peek_u8(&mut self) -> Result<u8>76     fn peek_u8(&mut self) -> Result<u8> {
77         if !self.buf.is_empty() {
78             Ok(self.buf[0])
79         } else {
80             bail!("Buffer is empty")
81         }
82     }
83 
read_u16(&mut self) -> Result<u16>84     fn read_u16(&mut self) -> Result<u16> {
85         if self.buf.len() >= 2 {
86             // read the value as little-endian
87             let value = u16::from_le_bytes([self.buf[0], self.buf[1]]);
88             self.buf = &self.buf[2..];
89             Ok(value)
90         } else {
91             bail!("Not enough data left in buffer to read a u16 value");
92         }
93     }
94 
read_u32(&mut self) -> Result<u32>95     fn read_u32(&mut self) -> Result<u32> {
96         if self.buf.len() >= 4 {
97             // read the value as little-endian
98             let value = self.buf[0] as u32
99                 + ((self.buf[1] as u32) << 8)
100                 + ((self.buf[2] as u32) << 16)
101                 + ((self.buf[3] as u32) << 24);
102             self.buf = &self.buf[4..];
103             Ok(value)
104         } else {
105             bail!("Not enough data left in buffer to read a u32 value");
106         }
107     }
108 
read_bool(&mut self) -> Result<bool>109     fn read_bool(&mut self) -> Result<bool> {
110         Ok(self.read_u8()? == 1)
111     }
112 
read_string(&mut self) -> Result<String>113     fn read_string(&mut self) -> Result<String> {
114         let size = self.read_u8()? as usize;
115         let slice;
116         (slice, self.buf) = self.buf.split_at(size);
117         String::from_utf8(slice.into()).context("Invalid string data")
118     }
119 
read_long_string(&mut self) -> Result<String>120     fn read_long_string(&mut self) -> Result<String> {
121         let size = self.read_u16()? as usize;
122         let slice;
123         (slice, self.buf) = self.buf.split_at(size);
124         String::from_utf8(slice.into()).context("Invalid string data")
125     }
126 
read_optional_long_string(&mut self) -> Result<Option<String>>127     fn read_optional_long_string(&mut self) -> Result<Option<String>> {
128         Ok(Some(self.read_long_string()?).filter(|str| !str.is_empty()))
129     }
130 
read_type(&mut self) -> Result<Type>131     fn read_type(&mut self) -> Result<Type> {
132         let value = self.read_u8()?;
133         Ok(match value {
134             codes::TYPE_U8 => Type::UInt8,
135             codes::TYPE_I8 => Type::Int8,
136             codes::TYPE_U16 => Type::UInt16,
137             codes::TYPE_I16 => Type::Int16,
138             codes::TYPE_U32 => Type::UInt32,
139             codes::TYPE_I32 => Type::Int32,
140             codes::TYPE_U64 => Type::UInt64,
141             codes::TYPE_I64 => Type::Int64,
142             codes::TYPE_F32 => Type::Float32,
143             codes::TYPE_F64 => Type::Float64,
144             codes::TYPE_BOOL => Type::Boolean,
145             codes::TYPE_STRING => Type::String,
146             codes::TYPE_DURATION => Type::Duration,
147             codes::TYPE_SYSTEM_TIME => Type::Timestamp,
148             codes::TYPE_RECORD => Type::Record {
149                 module_path: self.read_string()?,
150                 name: self.read_string()?,
151             },
152             codes::TYPE_ENUM => Type::Enum {
153                 module_path: self.read_string()?,
154                 name: self.read_string()?,
155             },
156             codes::TYPE_INTERFACE => Type::Object {
157                 module_path: self.read_string()?,
158                 name: self.read_string()?,
159                 imp: ObjectImpl::Struct,
160             },
161             codes::TYPE_TRAIT_INTERFACE => Type::Object {
162                 module_path: self.read_string()?,
163                 name: self.read_string()?,
164                 imp: ObjectImpl::Trait,
165             },
166             codes::TYPE_CALLBACK_TRAIT_INTERFACE => Type::Object {
167                 module_path: self.read_string()?,
168                 name: self.read_string()?,
169                 imp: ObjectImpl::CallbackTrait,
170             },
171             codes::TYPE_CALLBACK_INTERFACE => Type::CallbackInterface {
172                 module_path: self.read_string()?,
173                 name: self.read_string()?,
174             },
175             codes::TYPE_CUSTOM => Type::Custom {
176                 module_path: self.read_string()?,
177                 name: self.read_string()?,
178                 builtin: Box::new(self.read_type()?),
179             },
180             codes::TYPE_OPTION => Type::Optional {
181                 inner_type: Box::new(self.read_type()?),
182             },
183             codes::TYPE_VEC => {
184                 let inner_type = self.read_type()?;
185                 if inner_type == Type::UInt8 {
186                     Type::Bytes
187                 } else {
188                     Type::Sequence {
189                         inner_type: Box::new(inner_type),
190                     }
191                 }
192             }
193             codes::TYPE_HASH_MAP => Type::Map {
194                 key_type: Box::new(self.read_type()?),
195                 value_type: Box::new(self.read_type()?),
196             },
197             codes::TYPE_UNIT => bail!("Unexpected TYPE_UNIT"),
198             codes::TYPE_RESULT => bail!("Unexpected TYPE_RESULT"),
199             _ => bail!("Unexpected metadata type code: {value:?}"),
200         })
201     }
202 
read_optional_type(&mut self) -> Result<Option<Type>>203     fn read_optional_type(&mut self) -> Result<Option<Type>> {
204         Ok(match self.peek_u8()? {
205             codes::TYPE_UNIT => {
206                 _ = self.read_u8();
207                 None
208             }
209             _ => Some(self.read_type()?),
210         })
211     }
212 
read_return_type(&mut self) -> Result<(Option<Type>, Option<Type>)>213     fn read_return_type(&mut self) -> Result<(Option<Type>, Option<Type>)> {
214         Ok(match self.peek_u8()? {
215             codes::TYPE_UNIT => {
216                 _ = self.read_u8();
217                 (None, None)
218             }
219             codes::TYPE_RESULT => {
220                 _ = self.read_u8();
221                 (self.read_optional_type()?, self.read_optional_type()?)
222             }
223             _ => (Some(self.read_type()?), None),
224         })
225     }
226 
read_func(&mut self) -> Result<FnMetadata>227     fn read_func(&mut self) -> Result<FnMetadata> {
228         let module_path = self.read_string()?;
229         let name = self.read_string()?;
230         let is_async = self.read_bool()?;
231         let inputs = self.read_inputs()?;
232         let (return_type, throws) = self.read_return_type()?;
233         let docstring = self.read_optional_long_string()?;
234         Ok(FnMetadata {
235             module_path,
236             name,
237             is_async,
238             inputs,
239             return_type,
240             throws,
241             docstring,
242             checksum: self.calc_checksum(),
243         })
244     }
245 
read_constructor(&mut self) -> Result<ConstructorMetadata>246     fn read_constructor(&mut self) -> Result<ConstructorMetadata> {
247         let module_path = self.read_string()?;
248         let self_name = self.read_string()?;
249         let name = self.read_string()?;
250         let is_async = self.read_bool()?;
251         let inputs = self.read_inputs()?;
252         let (return_type, throws) = self.read_return_type()?;
253         let docstring = self.read_optional_long_string()?;
254 
255         return_type
256             .filter(|t| {
257                 matches!(
258                     t,
259                     Type::Object { name, imp: ObjectImpl::Struct, .. } if name == &self_name
260                 )
261             })
262             .context("Constructor return type must be Arc<Self>")?;
263 
264         Ok(ConstructorMetadata {
265             module_path,
266             self_name,
267             is_async,
268             name,
269             inputs,
270             throws,
271             checksum: self.calc_checksum(),
272             docstring,
273         })
274     }
275 
read_method(&mut self) -> Result<MethodMetadata>276     fn read_method(&mut self) -> Result<MethodMetadata> {
277         let module_path = self.read_string()?;
278         let self_name = self.read_string()?;
279         let name = self.read_string()?;
280         let is_async = self.read_bool()?;
281         let inputs = self.read_inputs()?;
282         let (return_type, throws) = self.read_return_type()?;
283         let docstring = self.read_optional_long_string()?;
284         Ok(MethodMetadata {
285             module_path,
286             self_name,
287             name,
288             is_async,
289             inputs,
290             return_type,
291             throws,
292             takes_self_by_arc: false, // not emitted by macros
293             checksum: self.calc_checksum(),
294             docstring,
295         })
296     }
297 
read_record(&mut self) -> Result<RecordMetadata>298     fn read_record(&mut self) -> Result<RecordMetadata> {
299         Ok(RecordMetadata {
300             module_path: self.read_string()?,
301             name: self.read_string()?,
302             fields: self.read_fields()?,
303             docstring: self.read_optional_long_string()?,
304         })
305     }
306 
read_enum(&mut self) -> Result<EnumMetadata>307     fn read_enum(&mut self) -> Result<EnumMetadata> {
308         let module_path = self.read_string()?;
309         let name = self.read_string()?;
310         let forced_flatness = match self.read_u8()? {
311             0 => None,
312             1 => Some(false),
313             2 => Some(true),
314             _ => unreachable!("invalid flatness"),
315         };
316         let discr_type = if self.read_bool()? {
317             Some(self.read_type()?)
318         } else {
319             None
320         };
321         let variants = if forced_flatness == Some(true) {
322             self.read_flat_variants()?
323         } else {
324             self.read_variants()?
325         };
326 
327         Ok(EnumMetadata {
328             module_path,
329             name,
330             forced_flatness,
331             discr_type,
332             variants,
333             non_exhaustive: self.read_bool()?,
334             docstring: self.read_optional_long_string()?,
335         })
336     }
337 
read_object(&mut self, imp: ObjectImpl) -> Result<ObjectMetadata>338     fn read_object(&mut self, imp: ObjectImpl) -> Result<ObjectMetadata> {
339         Ok(ObjectMetadata {
340             module_path: self.read_string()?,
341             name: self.read_string()?,
342             imp,
343             docstring: self.read_optional_long_string()?,
344         })
345     }
346 
read_uniffi_trait(&mut self) -> Result<UniffiTraitMetadata>347     fn read_uniffi_trait(&mut self) -> Result<UniffiTraitMetadata> {
348         let code = self.read_u8()?;
349         let mut read_metadata_method = || -> Result<MethodMetadata> {
350             let code = self.read_u8()?;
351             ensure!(code == codes::METHOD, "expected METHOD but read {code}");
352             self.read_method()
353         };
354 
355         Ok(match UniffiTraitDiscriminants::from(code)? {
356             UniffiTraitDiscriminants::Debug => UniffiTraitMetadata::Debug {
357                 fmt: read_metadata_method()?,
358             },
359             UniffiTraitDiscriminants::Display => UniffiTraitMetadata::Display {
360                 fmt: read_metadata_method()?,
361             },
362             UniffiTraitDiscriminants::Eq => UniffiTraitMetadata::Eq {
363                 eq: read_metadata_method()?,
364                 ne: read_metadata_method()?,
365             },
366             UniffiTraitDiscriminants::Hash => UniffiTraitMetadata::Hash {
367                 hash: read_metadata_method()?,
368             },
369         })
370     }
371 
read_callback_interface(&mut self) -> Result<CallbackInterfaceMetadata>372     fn read_callback_interface(&mut self) -> Result<CallbackInterfaceMetadata> {
373         Ok(CallbackInterfaceMetadata {
374             module_path: self.read_string()?,
375             name: self.read_string()?,
376             docstring: self.read_optional_long_string()?,
377         })
378     }
379 
read_trait_method(&mut self) -> Result<TraitMethodMetadata>380     fn read_trait_method(&mut self) -> Result<TraitMethodMetadata> {
381         let module_path = self.read_string()?;
382         let trait_name = self.read_string()?;
383         let index = self.read_u32()?;
384         let name = self.read_string()?;
385         let is_async = self.read_bool()?;
386         let inputs = self.read_inputs()?;
387         let (return_type, throws) = self.read_return_type()?;
388         let docstring = self.read_optional_long_string()?;
389         Ok(TraitMethodMetadata {
390             module_path,
391             trait_name,
392             index,
393             name,
394             is_async,
395             inputs,
396             return_type,
397             throws,
398             takes_self_by_arc: false, // not emitted by macros
399             checksum: self.calc_checksum(),
400             docstring,
401         })
402     }
403 
read_fields(&mut self) -> Result<Vec<FieldMetadata>>404     fn read_fields(&mut self) -> Result<Vec<FieldMetadata>> {
405         let len = self.read_u8()?;
406         (0..len)
407             .map(|_| {
408                 let name = self.read_string()?;
409                 let ty = self.read_type()?;
410                 let default = self.read_optional_default(&name, &ty)?;
411                 Ok(FieldMetadata {
412                     name,
413                     ty,
414                     default,
415                     docstring: self.read_optional_long_string()?,
416                 })
417             })
418             .collect()
419     }
420 
read_variants(&mut self) -> Result<Vec<VariantMetadata>>421     fn read_variants(&mut self) -> Result<Vec<VariantMetadata>> {
422         let len = self.read_u8()?;
423         (0..len)
424             .map(|_| {
425                 Ok(VariantMetadata {
426                     name: self.read_string()?,
427                     discr: self.read_optional_default("<variant-value>", &Type::UInt64)?,
428                     fields: self.read_fields()?,
429                     docstring: self.read_optional_long_string()?,
430                 })
431             })
432             .collect()
433     }
434 
read_flat_variants(&mut self) -> Result<Vec<VariantMetadata>>435     fn read_flat_variants(&mut self) -> Result<Vec<VariantMetadata>> {
436         let len = self.read_u8()?;
437         (0..len)
438             .map(|_| {
439                 Ok(VariantMetadata {
440                     name: self.read_string()?,
441                     discr: None,
442                     fields: vec![],
443                     docstring: self.read_optional_long_string()?,
444                 })
445             })
446             .collect()
447     }
448 
read_inputs(&mut self) -> Result<Vec<FnParamMetadata>>449     fn read_inputs(&mut self) -> Result<Vec<FnParamMetadata>> {
450         let len = self.read_u8()?;
451         (0..len)
452             .map(|_| {
453                 let name = self.read_string()?;
454                 let ty = self.read_type()?;
455                 let default = self.read_optional_default(&name, &ty)?;
456                 Ok(FnParamMetadata {
457                     name,
458                     ty,
459                     default,
460                     // not emitted by macros
461                     by_ref: false,
462                     optional: false,
463                 })
464             })
465             .collect()
466     }
467 
calc_checksum(&self) -> Option<u16>468     fn calc_checksum(&self) -> Option<u16> {
469         let bytes_read = self.initial_data.len() - self.buf.len();
470         let metadata_buf = &self.initial_data[..bytes_read];
471         Some(checksum_metadata(metadata_buf))
472     }
473 
read_optional_default(&mut self, name: &str, ty: &Type) -> Result<Option<LiteralMetadata>>474     fn read_optional_default(&mut self, name: &str, ty: &Type) -> Result<Option<LiteralMetadata>> {
475         if self.read_bool()? {
476             Ok(Some(self.read_default(name, ty)?))
477         } else {
478             Ok(None)
479         }
480     }
481 
read_default(&mut self, name: &str, ty: &Type) -> Result<LiteralMetadata>482     fn read_default(&mut self, name: &str, ty: &Type) -> Result<LiteralMetadata> {
483         let literal_kind = self.read_u8()?;
484 
485         Ok(match literal_kind {
486             codes::LIT_STR => {
487                 ensure!(
488                     matches!(ty, Type::String),
489                     "field {name} of type {ty:?} can't have a default value of type string"
490                 );
491                 LiteralMetadata::String(self.read_string()?)
492             }
493             codes::LIT_INT => {
494                 let base10_digits = self.read_string()?;
495                 // procmacros emit the type for discriminant values based purely on whether the constant
496                 // is positive or negative.
497                 let ty = if !base10_digits.is_empty()
498                     && base10_digits.as_bytes()[0] == b'-'
499                     && ty == &Type::UInt64
500                 {
501                     &Type::Int64
502                 } else {
503                     ty
504                 };
505                 macro_rules! parse_int {
506                     ($ty:ident, $variant:ident) => {
507                         LiteralMetadata::$variant(
508                             base10_digits
509                                 .parse::<$ty>()
510                                 .with_context(|| {
511                                     format!("parsing default for field {name}: {base10_digits}")
512                                 })?
513                                 .into(),
514                             Radix::Decimal,
515                             ty.to_owned(),
516                         )
517                     };
518                 }
519 
520                 match ty {
521                     Type::UInt8 => parse_int!(u8, UInt),
522                     Type::Int8 => parse_int!(i8, Int),
523                     Type::UInt16 => parse_int!(u16, UInt),
524                     Type::Int16 => parse_int!(i16, Int),
525                     Type::UInt32 => parse_int!(u32, UInt),
526                     Type::Int32 => parse_int!(i32, Int),
527                     Type::UInt64 => parse_int!(u64, UInt),
528                     Type::Int64 => parse_int!(i64, Int),
529                     _ => {
530                         bail!("field {name} of type {ty:?} can't have a default value of type integer");
531                     }
532                 }
533             }
534             codes::LIT_FLOAT => match ty {
535                 Type::Float32 | Type::Float64 => {
536                     LiteralMetadata::Float(self.read_string()?, ty.to_owned())
537                 }
538                 _ => {
539                     bail!("field {name} of type {ty:?} can't have a default value of type float");
540                 }
541             },
542             codes::LIT_BOOL => LiteralMetadata::Boolean(self.read_bool()?),
543             codes::LIT_NONE => match ty {
544                 Type::Optional { .. } => LiteralMetadata::None,
545                 _ => bail!("field {name} of type {ty:?} can't have a default value of None"),
546             },
547             codes::LIT_SOME => match ty {
548                 Type::Optional { inner_type, .. } => LiteralMetadata::Some {
549                     inner: Box::new(self.read_default(name, inner_type)?),
550                 },
551                 _ => bail!("field {name} of type {ty:?} can't have a default value of None"),
552             },
553             codes::LIT_EMPTY_SEQ => LiteralMetadata::EmptySequence,
554             _ => bail!("Unexpected literal kind code: {literal_kind:?}"),
555         })
556     }
557 }
558