| 1 | use serde::de::{self, DeserializeSeed, VariantAccess, Visitor}; |
| 2 | use static_assertions::assert_impl_all; |
| 3 | |
| 4 | use std::{marker::PhantomData, str}; |
| 5 | |
| 6 | #[cfg (unix)] |
| 7 | use std::os::fd::{AsFd, AsRawFd}; |
| 8 | |
| 9 | #[cfg (feature = "gvariant" )] |
| 10 | use crate::gvariant::Deserializer as GVDeserializer; |
| 11 | use crate::{ |
| 12 | container_depths::ContainerDepths, dbus::Deserializer as DBusDeserializer, serialized::Context, |
| 13 | signature_parser::SignatureParser, utils::*, Basic, Error, ObjectPath, Result, Signature, |
| 14 | }; |
| 15 | |
| 16 | #[cfg (unix)] |
| 17 | use crate::Fd; |
| 18 | |
| 19 | /// Our deserialization implementation. |
| 20 | #[derive (Debug)] |
| 21 | pub(crate) struct DeserializerCommon<'de, 'sig, 'f, F> { |
| 22 | pub(crate) ctxt: Context, |
| 23 | pub(crate) bytes: &'de [u8], |
| 24 | |
| 25 | #[cfg (unix)] |
| 26 | pub(crate) fds: Option<&'f [F]>, |
| 27 | #[cfg (not(unix))] |
| 28 | pub(crate) fds: PhantomData<&'f F>, |
| 29 | |
| 30 | pub(crate) pos: usize, |
| 31 | |
| 32 | pub(crate) sig_parser: SignatureParser<'sig>, |
| 33 | |
| 34 | pub(crate) container_depths: ContainerDepths, |
| 35 | } |
| 36 | |
| 37 | /// Our deserialization implementation. |
| 38 | /// |
| 39 | /// Using this deserializer involves an redirection to the actual deserializer. It's best |
| 40 | /// to use the serialization functions, e.g [`crate::to_bytes`] or specific serializers, |
| 41 | /// [`crate::dbus::Deserializer`] or [`crate::zvariant::Deserializer`]. |
| 42 | pub(crate) enum Deserializer<'ser, 'sig, 'f, F> { |
| 43 | DBus(DBusDeserializer<'ser, 'sig, 'f, F>), |
| 44 | #[cfg (feature = "gvariant" )] |
| 45 | GVariant(GVDeserializer<'ser, 'sig, 'f, F>), |
| 46 | } |
| 47 | |
| 48 | assert_impl_all!(Deserializer<'_, '_, '_, ()>: Send, Sync, Unpin); |
| 49 | |
| 50 | #[cfg (unix)] |
| 51 | impl<'de, 'sig, 'f, F> DeserializerCommon<'de, 'sig, 'f, F> |
| 52 | where |
| 53 | F: AsFd, |
| 54 | { |
| 55 | pub fn get_fd(&self, idx: u32) -> Result<i32> { |
| 56 | self.fds |
| 57 | .and_then(|fds| fds.get(idx as usize).map(|fd| fd.as_fd().as_raw_fd())) |
| 58 | .ok_or(err:Error::UnknownFd) |
| 59 | } |
| 60 | } |
| 61 | |
| 62 | impl<'de, 'sig, 'f, F> DeserializerCommon<'de, 'sig, 'f, F> { |
| 63 | pub fn parse_padding(&mut self, alignment: usize) -> Result<usize> { |
| 64 | let padding = padding_for_n_bytes(self.abs_pos(), alignment); |
| 65 | if padding > 0 { |
| 66 | if self.pos + padding > self.bytes.len() { |
| 67 | return Err(serde::de::Error::invalid_length( |
| 68 | self.bytes.len(), |
| 69 | &format!(">= {}" , self.pos + padding).as_str(), |
| 70 | )); |
| 71 | } |
| 72 | |
| 73 | for i in 0..padding { |
| 74 | let byte = self.bytes[self.pos + i]; |
| 75 | if byte != 0 { |
| 76 | return Err(Error::PaddingNot0(byte)); |
| 77 | } |
| 78 | } |
| 79 | self.pos += padding; |
| 80 | } |
| 81 | |
| 82 | Ok(padding) |
| 83 | } |
| 84 | |
| 85 | pub fn prep_deserialize_basic<T>(&mut self) -> Result<()> |
| 86 | where |
| 87 | T: Basic, |
| 88 | { |
| 89 | self.sig_parser.skip_char()?; |
| 90 | self.parse_padding(T::alignment(self.ctxt.format()))?; |
| 91 | |
| 92 | Ok(()) |
| 93 | } |
| 94 | |
| 95 | pub fn next_slice(&mut self, len: usize) -> Result<&'de [u8]> { |
| 96 | if self.pos + len > self.bytes.len() { |
| 97 | return Err(serde::de::Error::invalid_length( |
| 98 | self.bytes.len(), |
| 99 | &format!(">= {}" , self.pos + len).as_str(), |
| 100 | )); |
| 101 | } |
| 102 | |
| 103 | let slice = &self.bytes[self.pos..self.pos + len]; |
| 104 | self.pos += len; |
| 105 | |
| 106 | Ok(slice) |
| 107 | } |
| 108 | |
| 109 | pub fn next_const_size_slice<T>(&mut self) -> Result<&[u8]> |
| 110 | where |
| 111 | T: Basic, |
| 112 | { |
| 113 | self.prep_deserialize_basic::<T>()?; |
| 114 | |
| 115 | self.next_slice(T::alignment(self.ctxt.format())) |
| 116 | } |
| 117 | |
| 118 | pub fn abs_pos(&self) -> usize { |
| 119 | self.ctxt.position() + self.pos |
| 120 | } |
| 121 | } |
| 122 | |
| 123 | macro_rules! deserialize_method { |
| 124 | ($method:ident($($arg:ident: $type:ty),*)) => { |
| 125 | #[inline] |
| 126 | fn $method<V>(self, $($arg: $type,)* visitor: V) -> Result<V::Value> |
| 127 | where |
| 128 | V: Visitor<'de>, |
| 129 | { |
| 130 | match self { |
| 131 | #[cfg(feature = "gvariant" )] |
| 132 | Deserializer::GVariant(de) => { |
| 133 | de.$method($($arg,)* visitor) |
| 134 | } |
| 135 | Deserializer::DBus(de) => { |
| 136 | de.$method($($arg,)* visitor) |
| 137 | } |
| 138 | } |
| 139 | } |
| 140 | } |
| 141 | } |
| 142 | |
| 143 | impl<'de, 'd, 'sig, 'f, #[cfg (unix)] F: AsFd, #[cfg (not(unix))] F> de::Deserializer<'de> |
| 144 | for &'d mut Deserializer<'de, 'sig, 'f, F> |
| 145 | { |
| 146 | type Error = Error; |
| 147 | |
| 148 | deserialize_method!(deserialize_any()); |
| 149 | deserialize_method!(deserialize_bool()); |
| 150 | deserialize_method!(deserialize_i8()); |
| 151 | deserialize_method!(deserialize_i16()); |
| 152 | deserialize_method!(deserialize_i32()); |
| 153 | deserialize_method!(deserialize_i64()); |
| 154 | deserialize_method!(deserialize_u8()); |
| 155 | deserialize_method!(deserialize_u16()); |
| 156 | deserialize_method!(deserialize_u32()); |
| 157 | deserialize_method!(deserialize_u64()); |
| 158 | deserialize_method!(deserialize_f32()); |
| 159 | deserialize_method!(deserialize_f64()); |
| 160 | deserialize_method!(deserialize_char()); |
| 161 | deserialize_method!(deserialize_str()); |
| 162 | deserialize_method!(deserialize_string()); |
| 163 | deserialize_method!(deserialize_bytes()); |
| 164 | deserialize_method!(deserialize_byte_buf()); |
| 165 | deserialize_method!(deserialize_option()); |
| 166 | deserialize_method!(deserialize_unit()); |
| 167 | deserialize_method!(deserialize_unit_struct(n: &'static str)); |
| 168 | deserialize_method!(deserialize_newtype_struct(n: &'static str)); |
| 169 | deserialize_method!(deserialize_seq()); |
| 170 | deserialize_method!(deserialize_map()); |
| 171 | deserialize_method!(deserialize_tuple(n: usize)); |
| 172 | deserialize_method!(deserialize_tuple_struct(n: &'static str, l: usize)); |
| 173 | deserialize_method!(deserialize_struct( |
| 174 | n: &'static str, |
| 175 | f: &'static [&'static str] |
| 176 | )); |
| 177 | deserialize_method!(deserialize_enum( |
| 178 | n: &'static str, |
| 179 | f: &'static [&'static str] |
| 180 | )); |
| 181 | deserialize_method!(deserialize_identifier()); |
| 182 | deserialize_method!(deserialize_ignored_any()); |
| 183 | |
| 184 | fn is_human_readable(&self) -> bool { |
| 185 | false |
| 186 | } |
| 187 | } |
| 188 | |
| 189 | #[derive (Debug)] |
| 190 | pub(crate) enum ValueParseStage { |
| 191 | Signature, |
| 192 | Value, |
| 193 | Done, |
| 194 | } |
| 195 | |
| 196 | pub(crate) fn deserialize_any<'de, 'sig, 'f, D, V>( |
| 197 | de: D, |
| 198 | next_char: char, |
| 199 | visitor: V, |
| 200 | ) -> Result<V::Value> |
| 201 | where |
| 202 | D: de::Deserializer<'de, Error = Error>, |
| 203 | V: Visitor<'de>, |
| 204 | { |
| 205 | match next_char { |
| 206 | u8::SIGNATURE_CHAR => de.deserialize_u8(visitor), |
| 207 | bool::SIGNATURE_CHAR => de.deserialize_bool(visitor), |
| 208 | i16::SIGNATURE_CHAR => de.deserialize_i16(visitor), |
| 209 | u16::SIGNATURE_CHAR => de.deserialize_u16(visitor), |
| 210 | i32::SIGNATURE_CHAR => de.deserialize_i32(visitor), |
| 211 | #[cfg (unix)] |
| 212 | Fd::SIGNATURE_CHAR => de.deserialize_i32(visitor), |
| 213 | u32::SIGNATURE_CHAR => de.deserialize_u32(visitor), |
| 214 | i64::SIGNATURE_CHAR => de.deserialize_i64(visitor), |
| 215 | u64::SIGNATURE_CHAR => de.deserialize_u64(visitor), |
| 216 | f64::SIGNATURE_CHAR => de.deserialize_f64(visitor), |
| 217 | <&str>::SIGNATURE_CHAR | ObjectPath::SIGNATURE_CHAR | Signature::SIGNATURE_CHAR => { |
| 218 | de.deserialize_str(visitor) |
| 219 | } |
| 220 | VARIANT_SIGNATURE_CHAR => de.deserialize_seq(visitor), |
| 221 | ARRAY_SIGNATURE_CHAR => de.deserialize_seq(visitor), |
| 222 | STRUCT_SIG_START_CHAR => de.deserialize_seq(visitor), |
| 223 | #[cfg (feature = "gvariant" )] |
| 224 | MAYBE_SIGNATURE_CHAR => de.deserialize_option(visitor), |
| 225 | c => Err(de::Error::invalid_value( |
| 226 | de::Unexpected::Char(c), |
| 227 | &"a valid signature character" , |
| 228 | )), |
| 229 | } |
| 230 | } |
| 231 | |
| 232 | // Enum handling is very generic so it can be here and specific deserializers can use this. |
| 233 | pub(crate) struct Enum<D, F> { |
| 234 | pub(crate) de: D, |
| 235 | pub(crate) name: &'static str, |
| 236 | pub(crate) _phantom: PhantomData<F>, |
| 237 | } |
| 238 | |
| 239 | impl<'de, D, F> VariantAccess<'de> for Enum<D, F> |
| 240 | where |
| 241 | D: de::Deserializer<'de, Error = Error>, |
| 242 | { |
| 243 | type Error = Error; |
| 244 | |
| 245 | fn unit_variant(self) -> std::result::Result<(), Self::Error> { |
| 246 | Ok(()) |
| 247 | } |
| 248 | |
| 249 | fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value> |
| 250 | where |
| 251 | T: DeserializeSeed<'de>, |
| 252 | { |
| 253 | seed.deserialize(self.de) |
| 254 | } |
| 255 | |
| 256 | fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value> |
| 257 | where |
| 258 | V: Visitor<'de>, |
| 259 | { |
| 260 | de::Deserializer::deserialize_struct(self.de, self.name, &[], visitor) |
| 261 | } |
| 262 | |
| 263 | fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value> |
| 264 | where |
| 265 | V: Visitor<'de>, |
| 266 | { |
| 267 | de::Deserializer::deserialize_struct(self.de, self.name, fields, visitor) |
| 268 | } |
| 269 | } |
| 270 | |