Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(155)

Side by Side Diff: mojo/public/rust/src/bindings/mojom.rs

Issue 2220183003: Rust: Add validation to decode (Closed) Base URL: git@github.com:domokit/mojo.git@coder-testing
Patch Set: Pass all tests Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 use bindings::decoding::{Decoder, ValidationError};
5 use bindings::encoding; 6 use bindings::encoding;
6 use bindings::encoding::{Bits, Encoder, Context, DATA_HEADER_SIZE, DataHeader, D ataHeaderValue}; 7 use bindings::encoding::{Bits, Encoder, Context, DATA_HEADER_SIZE, DataHeader, D ataHeaderValue};
7 use bindings::decoding::Decoder;
8
9 use bindings::message::MessageHeader; 8 use bindings::message::MessageHeader;
10 9
11 use std::cmp::Eq; 10 use std::cmp::Eq;
12 use std::collections::HashMap; 11 use std::collections::HashMap;
13 use std::hash::Hash; 12 use std::hash::Hash;
14 use std::mem; 13 use std::mem;
15 use std::ptr; 14 use std::ptr;
16 use std::vec::Vec; 15 use std::vec::Vec;
17 16
18 use system::{CastHandle, Handle, UntypedHandle}; 17 use system::{CastHandle, Handle, UntypedHandle};
19 use system::data_pipe; 18 use system::data_pipe;
20 use system::message_pipe; 19 use system::message_pipe;
21 use system::shared_buffer; 20 use system::shared_buffer;
22 use system::wait_set; 21 use system::wait_set;
23 22
24 /// The size of a Mojom map plus header in bytes. 23 /// The size of a Mojom map plus header in bytes.
25 const MAP_SIZE: usize = 24; 24 const MAP_SIZE: usize = 24;
26 25
26 /// The sorted set of versions for a map.
27 const MAP_VERSIONS: [(u32, u32); 1] = [(0, MAP_SIZE as u32)];
28
27 /// The size of a Mojom union in bytes (header included). 29 /// The size of a Mojom union in bytes (header included).
28 pub const UNION_SIZE: usize = 16; 30 pub const UNION_SIZE: usize = 16;
29 31
30 /// The size of a Mojom pointer in bits. 32 /// The size of a Mojom pointer in bits.
31 pub const POINTER_BIT_SIZE: Bits = Bits(64); 33 pub const POINTER_BIT_SIZE: Bits = Bits(64);
32 34
33 /// The value of a Mojom null pointer. 35 /// The value of a Mojom null pointer.
34 pub const MOJOM_NULL_POINTER: u64 = 0; 36 pub const MOJOM_NULL_POINTER: u64 = 0;
35 37
36 /// An enumeration of all the possible low-level Mojom types. 38 /// An enumeration of all the possible low-level Mojom types.
(...skipping 18 matching lines...) Expand all
55 fn embed_size(context: &Context) -> Bits; 57 fn embed_size(context: &Context) -> Bits;
56 58
57 /// Recursively computes the size of the complete Mojom archive 59 /// Recursively computes the size of the complete Mojom archive
58 /// starting from this type. 60 /// starting from this type.
59 fn compute_size(&self, context: Context) -> usize; 61 fn compute_size(&self, context: Context) -> usize;
60 62
61 /// Encodes this type into the encoder given a context. 63 /// Encodes this type into the encoder given a context.
62 fn encode(self, encoder: &mut Encoder, context: Context); 64 fn encode(self, encoder: &mut Encoder, context: Context);
63 65
64 /// Using a decoder, decodes itself out of a byte buffer. 66 /// Using a decoder, decodes itself out of a byte buffer.
65 fn decode(decoder: &mut Decoder, context: Context) -> Self; 67 fn decode(decoder: &mut Decoder, context: Context) -> Result<Self, Validatio nError>;
66 } 68 }
67 69
68 /// Whatever implements this trait is a Mojom pointer type which means 70 /// Whatever implements this trait is a Mojom pointer type which means
69 /// that on encode, a pointer is inlined and the implementer is 71 /// that on encode, a pointer is inlined and the implementer is
70 /// serialized elsewhere in the output buffer. 72 /// serialized elsewhere in the output buffer.
71 pub trait MojomPointer: MojomEncodable { 73 pub trait MojomPointer: MojomEncodable {
72 /// Get the DataHeader meta-data for this pointer type. 74 /// Get the DataHeader meta-data for this pointer type.
73 fn header_data(&self) -> DataHeaderValue; 75 fn header_data(&self) -> DataHeaderValue;
74 76
75 /// Get the size of only this type when serialized. 77 /// Get the size of only this type when serialized.
76 fn serialized_size(&self, context: &Context) -> usize; 78 fn serialized_size(&self, context: &Context) -> usize;
77 79
78 /// Encodes the actual values of the type into the encoder. 80 /// Encodes the actual values of the type into the encoder.
79 fn encode_value(self, encoder: &mut Encoder, context: Context); 81 fn encode_value(self, encoder: &mut Encoder, context: Context);
80 82
81 /// Decodes the actual values of the type into the decoder. 83 /// Decodes the actual values of the type into the decoder.
82 fn decode_value(decoder: &mut Decoder, context: Context) -> Self; 84 fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, Val idationError>;
83 85
84 /// Writes a pointer inlined into the current context before calling 86 /// Writes a pointer inlined into the current context before calling
85 /// encode_value. 87 /// encode_value.
86 fn encode_new(self, encoder: &mut Encoder, context: Context) { 88 fn encode_new(self, encoder: &mut Encoder, context: Context) {
87 let data_size = self.serialized_size(&context); 89 let data_size = self.serialized_size(&context);
88 let data_header = DataHeader::new(data_size, self.header_data()); 90 let data_header = DataHeader::new(data_size, self.header_data());
89 let new_context = encoder.add(&data_header).unwrap(); 91 let new_context = encoder.add(&data_header).unwrap();
90 self.encode_value(encoder, new_context); 92 self.encode_value(encoder, new_context);
91 } 93 }
92 94
93 /// Reads a pointer inlined into the current context before calling 95 /// Reads a pointer inlined into the current context before calling
94 /// decode_value. 96 /// decode_value.
95 fn decode_new(decoder: &mut Decoder, _context: Context, pointer: u64) -> Sel f { 97 fn decode_new(decoder: &mut Decoder, _context: Context, pointer: u64) -> Res ult<Self, ValidationError> {
96 let new_context = decoder.claim(pointer as usize).unwrap(); 98 match decoder.claim(pointer as usize) {
97 Self::decode_value(decoder, new_context) 99 Ok(new_context) => Self::decode_value(decoder, new_context),
100 Err(err) => Err(err),
101 }
98 } 102 }
99 } 103 }
100 104
101 /// Whatever implements this trait is a Mojom union type which means that 105 /// Whatever implements this trait is a Mojom union type which means that
102 /// on encode it is inlined, but if the union is nested inside of another 106 /// on encode it is inlined, but if the union is nested inside of another
103 /// union type, it is treated as a pointer type. 107 /// union type, it is treated as a pointer type.
104 pub trait MojomUnion: MojomEncodable { 108 pub trait MojomUnion: MojomEncodable {
105 /// Get the union's current tag. 109 /// Get the union's current tag.
106 fn get_tag(&self) -> u32; 110 fn get_tag(&self) -> u32;
107 111
108 /// Encode the actual value of the union. 112 /// Encode the actual value of the union.
109 fn encode_value(self, encoder: &mut Encoder, context: Context); 113 fn encode_value(self, encoder: &mut Encoder, context: Context);
110 114
111 /// Decode the actual value of the union. 115 /// Decode the actual value of the union.
112 fn decode_value(decoder: &mut Decoder, context: Context) -> Self; 116 fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, Val idationError>;
113 117
114 /// The embed_size for when the union acts as a pointer type. 118 /// The embed_size for when the union acts as a pointer type.
115 fn nested_embed_size() -> Bits { 119 fn nested_embed_size() -> Bits {
116 POINTER_BIT_SIZE 120 POINTER_BIT_SIZE
117 } 121 }
118 122
119 /// The encoding routine for when the union acts as a pointer type. 123 /// The encoding routine for when the union acts as a pointer type.
120 fn nested_encode(self, encoder: &mut Encoder, context: Context) { 124 fn nested_encode(self, encoder: &mut Encoder, context: Context) {
121 let loc = encoder.size() as u64; 125 let loc = encoder.size() as u64;
122 { 126 {
123 let state = encoder.get_mut(&context); 127 let state = encoder.get_mut(&context);
124 state.encode_pointer(loc); 128 state.encode_pointer(loc);
125 } 129 }
126 let tag = DataHeaderValue::UnionTag(self.get_tag()); 130 let tag = DataHeaderValue::UnionTag(self.get_tag());
127 let data_header = DataHeader::new(UNION_SIZE, tag); 131 let data_header = DataHeader::new(UNION_SIZE, tag);
128 let new_context = encoder.add(&data_header).unwrap(); 132 let new_context = encoder.add(&data_header).unwrap();
129 self.encode_value(encoder, new_context.set_is_union(true)); 133 self.encode_value(encoder, new_context.set_is_union(true));
130 } 134 }
131 135
132 /// The decoding routine for when the union acts as a pointer type. 136 /// The decoding routine for when the union acts as a pointer type.
133 fn nested_decode(decoder: &mut Decoder, context: Context) -> Self { 137 fn nested_decode(decoder: &mut Decoder, context: Context) -> Result<Self, Va lidationError> {
134 let global_offset = { 138 let global_offset = {
135 let state = decoder.get_mut(&context); 139 let state = decoder.get_mut(&context);
136 state.decode_pointer() as usize 140 match state.decode_pointer() {
141 Some(ptr) => ptr as usize,
142 None => return Err(ValidationError::IllegalPointer),
143 }
137 }; 144 };
138 let new_context = decoder.claim(global_offset).unwrap(); 145 if global_offset == (MOJOM_NULL_POINTER as usize) {
139 Self::decode_value(decoder, new_context) 146 return Err(ValidationError::UnexpectedNullPointer);
147 }
148 match decoder.claim(global_offset as usize) {
149 Ok(new_context) => Self::decode_value(decoder, new_context),
150 Err(err) => Err(err),
151 }
140 } 152 }
141 153
142 /// The embed_size for when the union is inlined into the current context. 154 /// The embed_size for when the union is inlined into the current context.
143 fn inline_embed_size() -> Bits { 155 fn inline_embed_size() -> Bits {
144 Bits(8 * (UNION_SIZE as usize)) 156 Bits(8 * (UNION_SIZE as usize))
145 } 157 }
146 158
147 /// The encoding routine for when the union is inlined into the current cont ext. 159 /// The encoding routine for when the union is inlined into the current cont ext.
148 fn inline_encode(self, encoder: &mut Encoder, context: Context) { 160 fn inline_encode(self, encoder: &mut Encoder, context: Context) {
149 { 161 {
150 let mut state = encoder.get_mut(&context); 162 let mut state = encoder.get_mut(&context);
151 state.align_to_bytes(8); 163 state.align_to_bytes(8);
152 state.encode(UNION_SIZE as u32); 164 state.encode(UNION_SIZE as u32);
153 state.encode(self.get_tag()); 165 state.encode(self.get_tag());
154 } 166 }
155 self.encode_value(encoder, context.clone()); 167 self.encode_value(encoder, context.clone());
156 { 168 {
157 let mut state = encoder.get_mut(&context); 169 let mut state = encoder.get_mut(&context);
158 state.align_to_bytes(8); 170 state.align_to_bytes(8);
159 state.align_to_byte(); 171 state.align_to_byte();
160 } 172 }
161 } 173 }
162 174
163 /// The decoding routine for when the union is inlined into the current cont ext. 175 /// The decoding routine for when the union is inlined into the current cont ext.
164 fn inline_decode(decoder: &mut Decoder, context: Context) -> Self { 176 fn inline_decode(decoder: &mut Decoder, context: Context) -> Result<Self, Va lidationError> {
165 { 177 {
166 let mut state = decoder.get_mut(&context); 178 let mut state = decoder.get_mut(&context);
167 state.align_to_byte(); 179 state.align_to_byte();
168 state.align_to_bytes(8); 180 state.align_to_bytes(8);
169 } 181 }
170 let value = Self::decode_value(decoder, context.clone()); 182 let value = Self::decode_value(decoder, context.clone());
171 { 183 {
172 let mut state = decoder.get_mut(&context); 184 let mut state = decoder.get_mut(&context);
173 state.align_to_byte(); 185 state.align_to_byte();
174 state.align_to_bytes(8); 186 state.align_to_bytes(8);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 /// interface that may recieve messages for some interface. 248 /// interface that may recieve messages for some interface.
237 /// 249 ///
238 /// When implementing this trait, specify the container "union" type 250 /// When implementing this trait, specify the container "union" type
239 /// which can contain any of the potential messages that may be recieved. 251 /// which can contain any of the potential messages that may be recieved.
240 /// This way, we can return that type and let the user multiplex over 252 /// This way, we can return that type and let the user multiplex over
241 /// what message was received. 253 /// what message was received.
242 pub trait MojomInterfaceRecv: MojomInterface { 254 pub trait MojomInterfaceRecv: MojomInterface {
243 type Container: MojomMessageOption; 255 type Container: MojomMessageOption;
244 256
245 /// Tries to read a message from a pipe and decodes it. 257 /// Tries to read a message from a pipe and decodes it.
246 fn recv_response(&self) -> Self::Container { 258 fn recv_response(&self) -> Result<Self::Container, ValidationError> {
247 // TODO(mknyszek): Actually handle errors with reading 259 // TODO(mknyszek): Actually handle errors with reading
248 let (buffer, handles) = self.pipe().read(mpflags!(Read::None)).unwrap(); 260 let (buffer, handles) = self.pipe().read(mpflags!(Read::None)).unwrap();
249 Self::Container::decode_message(buffer, handles) 261 Self::Container::decode_message(buffer, handles)
250 } 262 }
251 } 263 }
252 264
253 /// Whatever implements this trait is considered to be a Mojom struct. 265 /// Whatever implements this trait is considered to be a Mojom struct.
254 /// 266 ///
255 /// Mojom structs are always the root of any Mojom message. Thus, we 267 /// Mojom structs are always the root of any Mojom message. Thus, we
256 /// provide convenience functions for serialization here. 268 /// provide convenience functions for serialization here.
257 pub trait MojomStruct: MojomPointer { 269 pub trait MojomStruct: MojomPointer {
258 /// Given a pre-allocated buffer, the struct serializes itself. 270 /// Given a pre-allocated buffer, the struct serializes itself.
259 fn serialize(self, buffer: &mut [u8]) -> Vec<UntypedHandle> { 271 fn serialize(self, buffer: &mut [u8]) -> Vec<UntypedHandle> {
260 let mut encoder = Encoder::new(buffer); 272 let mut encoder = Encoder::new(buffer);
261 self.encode_new(&mut encoder, Default::default()); 273 self.encode_new(&mut encoder, Default::default());
262 encoder.unwrap() 274 encoder.unwrap()
263 } 275 }
264 276
265 /// The struct computes its own size, allocates a buffer, and then 277 /// The struct computes its own size, allocates a buffer, and then
266 /// serializes itself into that buffer. 278 /// serializes itself into that buffer.
267 fn auto_serialize(self) -> (Vec<u8>, Vec<UntypedHandle>) { 279 fn auto_serialize(self) -> (Vec<u8>, Vec<UntypedHandle>) {
268 let size = self.compute_size(Default::default()); 280 let size = self.compute_size(Default::default());
269 let mut buf = Vec::with_capacity(size); 281 let mut buf = Vec::with_capacity(size);
270 buf.resize(size, 0); 282 buf.resize(size, 0);
271 let handles = self.serialize(&mut buf); 283 let handles = self.serialize(&mut buf);
272 (buf, handles) 284 (buf, handles)
273 } 285 }
274 286
275 /// Decode the type from a byte array and a set of handles. 287 /// Decode the type from a byte array and a set of handles.
276 fn deserialize(buffer: &mut [u8], handles: Vec<UntypedHandle>) -> Self { 288 fn deserialize(buffer: &mut [u8], handles: Vec<UntypedHandle>) -> Result<Sel f, ValidationError> {
277 let mut decoder = Decoder::new(buffer, handles); 289 let mut decoder = Decoder::new(buffer, handles);
278 Self::decode_new(&mut decoder, Default::default(), 0) 290 Self::decode_new(&mut decoder, Default::default(), 0)
279 } 291 }
280 } 292 }
281 293
282 /// Marks a MojomStruct as being capable of being sent across some 294 /// Marks a MojomStruct as being capable of being sent across some
283 /// Mojom interface. 295 /// Mojom interface.
284 pub trait MojomMessage: MojomStruct { 296 pub trait MojomMessage: MojomStruct {
285 fn create_header() -> MessageHeader; 297 fn create_header() -> MessageHeader;
286 } 298 }
287 299
288 /// The trait for a "container" type intended to be used in MojomInterfaceRecv. 300 /// The trait for a "container" type intended to be used in MojomInterfaceRecv.
289 /// 301 ///
290 /// This trait contains the decode logic which decodes based on the message head er 302 /// This trait contains the decode logic which decodes based on the message head er
291 /// and returns itself: a union type which may contain any of the possible messa ges 303 /// and returns itself: a union type which may contain any of the possible messa ges
292 /// that may be sent across this interface. 304 /// that may be sent across this interface.
293 pub trait MojomMessageOption: Sized { 305 pub trait MojomMessageOption: Sized {
294 /// Decodes the actual payload of the message. 306 /// Decodes the actual payload of the message.
295 /// 307 ///
296 /// Implemented by a code generator. 308 /// Implemented by a code generator.
297 fn decode_payload(name: u32, buffer: &mut [u8], handles: Vec<UntypedHandle>) -> Self; 309 fn decode_payload(header: MessageHeader, buffer: &mut [u8], handles: Vec<Unt ypedHandle>) -> Result<Self, ValidationError>;
298 310
299 /// Decodes the message header and then the payload, returning a new 311 /// Decodes the message header and then the payload, returning a new
300 /// copy of itself. 312 /// copy of itself.
301 fn decode_message(mut buffer: Vec<u8>, handles: Vec<UntypedHandle>) -> Self { 313 fn decode_message(mut buffer: Vec<u8>, handles: Vec<UntypedHandle>) -> Resul t<Self, ValidationError> {
302 let header = MessageHeader::deserialize(&mut buffer[..], Vec::new()); 314 let header = match MessageHeader::deserialize(&mut buffer[..], Vec::new( )) {
315 Ok(header) => header,
316 Err(err) => return Err(err),
317 };
303 let payload_buffer = &mut buffer[header.serialized_size(&Default::defaul t())..]; 318 let payload_buffer = &mut buffer[header.serialized_size(&Default::defaul t())..];
304 Self::decode_payload(header.name, payload_buffer, handles) 319 Self::decode_payload(header, payload_buffer, handles)
305 } 320 }
306 } 321 }
307 322
308 // ********************************************** // 323 // ********************************************** //
309 // ****** IMPLEMENTATIONS FOR COMMON TYPES ****** // 324 // ****** IMPLEMENTATIONS FOR COMMON TYPES ****** //
310 // ********************************************** // 325 // ********************************************** //
311 326
312 macro_rules! impl_encodable_for_prim { 327 macro_rules! impl_encodable_for_prim {
313 ($($prim_type:ty),*) => { 328 ($($prim_type:ty),*) => {
314 $( 329 $(
315 impl MojomEncodable for $prim_type { 330 impl MojomEncodable for $prim_type {
316 fn mojom_type() -> MojomType { 331 fn mojom_type() -> MojomType {
317 MojomType::Simple 332 MojomType::Simple
318 } 333 }
319 fn mojom_alignment() -> usize { 334 fn mojom_alignment() -> usize {
320 mem::size_of::<$prim_type>() 335 mem::size_of::<$prim_type>()
321 } 336 }
322 fn embed_size(_context: &Context) -> Bits { 337 fn embed_size(_context: &Context) -> Bits {
323 Bits(8 * mem::size_of::<$prim_type>()) 338 Bits(8 * mem::size_of::<$prim_type>())
324 } 339 }
325 fn compute_size(&self, _context: Context) -> usize { 340 fn compute_size(&self, _context: Context) -> usize {
326 0 // Indicates that this type is inlined and it adds nothing ext ernal to the size 341 0 // Indicates that this type is inlined and it adds nothing ext ernal to the size
327 } 342 }
328 fn encode(self, encoder: &mut Encoder, context: Context) { 343 fn encode(self, encoder: &mut Encoder, context: Context) {
329 let mut state = encoder.get_mut(&context); 344 let mut state = encoder.get_mut(&context);
330 state.encode(self); 345 state.encode(self);
331 } 346 }
332 fn decode(decoder: &mut Decoder, context: Context) -> Self { 347 fn decode(decoder: &mut Decoder, context: Context) -> Result<Self, V alidationError> {
333 let mut state = decoder.get_mut(&context); 348 let mut state = decoder.get_mut(&context);
334 state.decode::<Self>() 349 Ok(state.decode::<Self>())
335 } 350 }
336 } 351 }
337 )* 352 )*
338 } 353 }
339 } 354 }
340 355
341 impl_encodable_for_prim!(i8, i16, i32, i64, u8, u16, u32, u64, f32, f64); 356 impl_encodable_for_prim!(i8, i16, i32, i64, u8, u16, u32, u64, f32, f64);
342 357
343 impl MojomEncodable for bool { 358 impl MojomEncodable for bool {
344 fn mojom_alignment() -> usize { 359 fn mojom_alignment() -> usize {
345 panic!("Should never check mojom_alignment of bools (they're bit-aligned )!"); 360 panic!("Should never check_decode mojom_alignment of bools (they're bit- aligned)!");
346 } 361 }
347 fn mojom_type() -> MojomType { 362 fn mojom_type() -> MojomType {
348 MojomType::Simple 363 MojomType::Simple
349 } 364 }
350 fn embed_size(_context: &Context) -> Bits { 365 fn embed_size(_context: &Context) -> Bits {
351 Bits(1) 366 Bits(1)
352 } 367 }
353 fn compute_size(&self, _context: Context) -> usize { 368 fn compute_size(&self, _context: Context) -> usize {
354 0 // Indicates that this type is inlined and it adds nothing external to the size 369 0 // Indicates that this type is inlined and it adds nothing external to the size
355 } 370 }
356 fn encode(self, encoder: &mut Encoder, context: Context) { 371 fn encode(self, encoder: &mut Encoder, context: Context) {
357 let mut state = encoder.get_mut(&context); 372 let mut state = encoder.get_mut(&context);
358 state.encode_bool(self); 373 state.encode_bool(self);
359 } 374 }
360 fn decode(decoder: &mut Decoder, context: Context) -> Self { 375 fn decode(decoder: &mut Decoder, context: Context) -> Result<Self, Validatio nError> {
361 let mut state = decoder.get_mut(&context); 376 let mut state = decoder.get_mut(&context);
362 state.decode_bool() 377 Ok(state.decode_bool())
363 } 378 }
364 } 379 }
365 380
366 // Options should be considered to represent nullability the Mojom IDL. 381 // Options should be considered to represent nullability the Mojom IDL.
367 // Any type wrapped in an Option type is nullable. 382 // Any type wrapped in an Option type is nullable.
368 383
369 impl<T: MojomEncodable> MojomEncodable for Option<T> { 384 impl<T: MojomEncodable> MojomEncodable for Option<T> {
370 fn mojom_alignment() -> usize { 385 fn mojom_alignment() -> usize {
371 T::mojom_alignment() 386 T::mojom_alignment()
372 } 387 }
(...skipping 20 matching lines...) Expand all
393 MojomType::Handle => state.encode_null_handle(), 408 MojomType::Handle => state.encode_null_handle(),
394 MojomType::Interface => { 409 MojomType::Interface => {
395 state.encode_null_handle(); 410 state.encode_null_handle();
396 state.encode(0 as u32); 411 state.encode(0 as u32);
397 }, 412 },
398 MojomType::Simple => panic!("Unexpected simple type in Optio n!"), 413 MojomType::Simple => panic!("Unexpected simple type in Optio n!"),
399 } 414 }
400 }, 415 },
401 } 416 }
402 } 417 }
403 fn decode(decoder: &mut Decoder, context: Context) -> Self { 418 fn decode(decoder: &mut Decoder, context: Context) -> Result<Self, Validatio nError> {
404 let skipped = { 419 let skipped = {
405 let mut state = decoder.get_mut(&context); 420 let mut state = decoder.get_mut(&context);
406 match T::mojom_type() { 421 match T::mojom_type() {
407 MojomType::Pointer => state.skip_if_null_pointer(), 422 MojomType::Pointer => state.skip_if_null_pointer(),
408 MojomType::Union => state.skip_if_null_union(), 423 MojomType::Union => state.skip_if_null_union(),
409 MojomType::Handle => state.skip_if_null_handle(), 424 MojomType::Handle => state.skip_if_null_handle(),
410 MojomType::Interface => state.skip_if_null_interface(), 425 MojomType::Interface => state.skip_if_null_interface(),
411 MojomType::Simple => panic!("Unexpected simple type in Option!") , 426 MojomType::Simple => panic!("Unexpected simple type in Option!") ,
412 } 427 }
413 }; 428 };
414 if skipped { 429 if skipped {
415 None 430 Ok(None)
416 } else { 431 } else {
417 Some(T::decode(decoder, context)) 432 match T::decode(decoder, context) {
433 Ok(value) => Ok(Some(value)),
434 Err(err) => Err(err),
435 }
418 } 436 }
419 } 437 }
420 } 438 }
421 439
422 macro_rules! impl_pointer_for_array { 440 macro_rules! impl_pointer_for_array {
423 () => { 441 () => {
424 fn header_data(&self) -> DataHeaderValue { 442 fn header_data(&self) -> DataHeaderValue {
425 DataHeaderValue::Elements(self.len() as u32) 443 DataHeaderValue::Elements(self.len() as u32)
426 } 444 }
427 fn serialized_size(&self, context: &Context) -> usize { 445 fn serialized_size(&self, context: &Context) -> usize {
(...skipping 19 matching lines...) Expand all
447 } 465 }
448 } 466 }
449 467
450 impl<T: MojomEncodable> MojomPointer for Vec<T> { 468 impl<T: MojomEncodable> MojomPointer for Vec<T> {
451 impl_pointer_for_array!(); 469 impl_pointer_for_array!();
452 fn encode_value(self, encoder: &mut Encoder, context: Context) { 470 fn encode_value(self, encoder: &mut Encoder, context: Context) {
453 for elem in self.into_iter() { 471 for elem in self.into_iter() {
454 elem.encode(encoder, context.clone()); 472 elem.encode(encoder, context.clone());
455 } 473 }
456 } 474 }
457 fn decode_value(decoder: &mut Decoder, context: Context) -> Vec<T> { 475 fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Vec<T>, V alidationError> {
458 // TODO(mknyszek): Verify elems, bytes, and T::embed_size match 476 let elems = {
459 let (_bytes, elems) = {
460 let mut state = decoder.get_mut(&context); 477 let mut state = decoder.get_mut(&context);
461 (state.decode::<u32>(), state.decode::<u32>()) 478 match state.decode_array_header::<T>() {
479 Ok(header) => header.data(),
480 Err(err) => return Err(err),
481 }
462 }; 482 };
463 let mut value = Vec::with_capacity(elems as usize); 483 let mut value = Vec::with_capacity(elems as usize);
464 // TODO(mknyszek): Don't trust elems blindly
465 for _ in 0..elems { 484 for _ in 0..elems {
466 value.push(T::decode(decoder, context.clone())); 485 match T::decode(decoder, context.clone()) {
486 Ok(elem) => value.push(elem),
487 Err(err) => return Err(err),
488 }
467 } 489 }
468 value 490 Ok(value)
469 } 491 }
470 } 492 }
471 493
472 impl<T: MojomEncodable> MojomEncodable for Vec<T> { 494 impl<T: MojomEncodable> MojomEncodable for Vec<T> {
473 impl_encodable_for_array!(); 495 impl_encodable_for_array!();
474 } 496 }
475 497
476 macro_rules! impl_encodable_for_boxed_fixed_array { 498 macro_rules! impl_encodable_for_boxed_fixed_array {
477 ($($len:expr),*) => { 499 ($($len:expr),*) => {
478 $( 500 $(
479 impl<T: MojomEncodable> MojomPointer for Box<[T; $len]> { 501 impl<T: MojomEncodable> MojomPointer for Box<[T; $len]> {
480 impl_pointer_for_array!(); 502 impl_pointer_for_array!();
481 fn encode_value(self, encoder: &mut Encoder, context: Context) { 503 fn encode_value(self, encoder: &mut Encoder, context: Context) {
482 for elem in (self as Box<[T]>).into_vec().into_iter() { 504 for elem in (self as Box<[T]>).into_vec().into_iter() {
483 elem.encode(encoder, context.clone()); 505 elem.encode(encoder, context.clone());
484 } 506 }
485 } 507 }
486 fn decode_value(decoder: &mut Decoder, context: Context) -> Box<[T; $len]> { 508 fn decode_value(decoder: &mut Decoder, context: Context) -> Result<B ox<[T; $len]>, ValidationError> {
487 // TODO(mknyszek): Verify elems, bytes, and T::embed_size match 509 let elems = {
488 let (_bytes, elems) = {
489 let mut state = decoder.get_mut(&context); 510 let mut state = decoder.get_mut(&context);
490 (state.decode::<u32>(), state.decode::<u32>()) 511 match state.decode_array_header::<T>() {
512 Ok(header) => header.data(),
513 Err(err) => return Err(err),
514 }
491 }; 515 };
492 assert_eq!(elems, $len); 516 if elems != $len {
517 return Err(ValidationError::UnexpectedArrayHeader);
518 }
493 let mut array: [T; $len]; 519 let mut array: [T; $len];
520 let mut error = None;
494 unsafe { 521 unsafe {
495 // Since we don't force Default to be implemented on Mojom t ypes 522 // Since we don't force Default to be implemented on Mojom t ypes
496 // (mainly due to handles) we need to create this array as u ninitialized 523 // (mainly due to handles) we need to create this array as u ninitialized
497 // and initialize it manually. 524 // and initialize it manually.
498 array = mem::uninitialized(); 525 array = mem::uninitialized();
526 let mut inits = 0;
499 for elem in &mut array[..] { 527 for elem in &mut array[..] {
500 ptr::write(elem, T::decode(decoder, context.clone())); 528 match T::decode(decoder, context.clone()) {
529 Ok(value) => ptr::write(elem, value),
530 Err(err) => {
531 error = Some(err);
532 break;
533 },
534 }
535 inits += 1;
536 }
537 // An error occurred, so we need to do some clean-up.
538 if inits != $len {
539 for i in 0..inits {
540 ptr::drop_in_place(&mut array[i] as *mut T);
541 }
542 mem::forget(array);
543 return Err(error.take().expect("Corrupted stack?"));
501 } 544 }
502 } 545 }
503 Box::new(array) 546 Ok(Box::new(array))
504 } 547 }
505 } 548 }
506 impl<T: MojomEncodable> MojomEncodable for Box<[T; $len]> { 549 impl<T: MojomEncodable> MojomEncodable for Box<[T; $len]> {
507 impl_encodable_for_array!(); 550 impl_encodable_for_array!();
508 } 551 }
509 )* 552 )*
510 } 553 }
511 } 554 }
512 555
513 // Unfortunately, we cannot be generic over the length of a fixed array 556 // Unfortunately, we cannot be generic over the length of a fixed array
514 // even though its part of the type (this will hopefully be added in the 557 // even though its part of the type (this will hopefully be added in the
515 // future) so for now we implement encodable for only the first 33 fixed 558 // future) so for now we implement encodable for only the first 33 fixed
516 // size array types. 559 // size array types.
517 impl_encodable_for_boxed_fixed_array!( 0, 1, 2, 3, 4, 5, 6, 7, 560 impl_encodable_for_boxed_fixed_array!( 0, 1, 2, 3, 4, 5, 6, 7,
518 8, 9, 10, 11, 12, 13, 14, 15, 561 8, 9, 10, 11, 12, 13, 14, 15,
519 16, 17, 18, 19, 20, 21, 22, 23, 562 16, 17, 18, 19, 20, 21, 22, 23,
520 24, 25, 26, 27, 28, 29, 30, 31, 563 24, 25, 26, 27, 28, 29, 30, 31,
521 32); 564 32);
522 565
523 impl<T: MojomEncodable> MojomPointer for Box<[T]> { 566 impl<T: MojomEncodable> MojomPointer for Box<[T]> {
524 impl_pointer_for_array!(); 567 impl_pointer_for_array!();
525 fn encode_value(self, encoder: &mut Encoder, context: Context) { 568 fn encode_value(self, encoder: &mut Encoder, context: Context) {
526 for elem in self.into_vec().into_iter() { 569 for elem in self.into_vec().into_iter() {
527 elem.encode(encoder, context.clone()); 570 elem.encode(encoder, context.clone());
528 } 571 }
529 } 572 }
530 fn decode_value(decoder: &mut Decoder, context: Context) -> Box<[T]> { 573 fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Box<[T]>, ValidationError> {
531 Vec::<T>::decode_value(decoder, context).into_boxed_slice() 574 match Vec::<T>::decode_value(decoder, context) {
575 Ok(vec) => Ok(vec.into_boxed_slice()),
576 Err(err) => Err(err),
577 }
532 } 578 }
533 } 579 }
534 580
535 impl<T: MojomEncodable> MojomEncodable for Box<[T]> { 581 impl<T: MojomEncodable> MojomEncodable for Box<[T]> {
536 impl_encodable_for_array!(); 582 impl_encodable_for_array!();
537 } 583 }
538 584
539 // We can represent a Mojom string as just a Rust String type 585 // We can represent a Mojom string as just a Rust String type
540 // since both are UTF-8. 586 // since both are UTF-8.
541 impl MojomPointer for String { 587 impl MojomPointer for String {
542 fn header_data(&self) -> DataHeaderValue { 588 fn header_data(&self) -> DataHeaderValue {
543 DataHeaderValue::Elements(self.len() as u32) 589 DataHeaderValue::Elements(self.len() as u32)
544 } 590 }
545 fn serialized_size(&self, _context: &Context) -> usize { 591 fn serialized_size(&self, _context: &Context) -> usize {
546 DATA_HEADER_SIZE + self.len() 592 DATA_HEADER_SIZE + self.len()
547 } 593 }
548 fn encode_value(self, encoder: &mut Encoder, context: Context) { 594 fn encode_value(self, encoder: &mut Encoder, context: Context) {
549 for byte in self.as_bytes() { 595 for byte in self.as_bytes() {
550 byte.encode(encoder, context.clone()); 596 byte.encode(encoder, context.clone());
551 } 597 }
552 } 598 }
553 fn decode_value(decoder: &mut Decoder, context: Context) -> String { 599 fn decode_value(decoder: &mut Decoder, context: Context) -> Result<String, V alidationError> {
554 let mut state = decoder.get_mut(&context); 600 let mut state = decoder.get_mut(&context);
555 // TODO(mknyszek): Verify elems, bytes, and T::embed_size match 601 let elems = match state.decode_array_header::<u8>() {
556 let _bytes = state.decode::<u32>(); 602 Ok(header) => header.data(),
557 let elems = state.decode::<u32>(); 603 Err(err) => return Err(err),
604 };
558 let mut value = Vec::with_capacity(elems as usize); 605 let mut value = Vec::with_capacity(elems as usize);
559 // TODO(mknyszek): Don't trust elems blindly
560 for _ in 0..elems { 606 for _ in 0..elems {
561 value.push(state.decode::<u8>()); 607 value.push(state.decode::<u8>());
562 } 608 }
563 match String::from_utf8(value) { 609 match String::from_utf8(value) {
564 Ok(string) => string, 610 Ok(string) => Ok(string),
565 // TODO(mknyszek): Don't panic and return an error
566 Err(err) => panic!("Error decoding String: {}", err), 611 Err(err) => panic!("Error decoding String: {}", err),
567 } 612 }
568 } 613 }
569 } 614 }
570 615
571 impl MojomEncodable for String { 616 impl MojomEncodable for String {
572 impl_encodable_for_pointer!(); 617 impl_encodable_for_pointer!();
573 fn compute_size(&self, context: Context) -> usize { 618 fn compute_size(&self, context: Context) -> usize {
574 encoding::align_default(self.serialized_size(&context)) 619 encoding::align_default(self.serialized_size(&context))
575 } 620 }
576 } 621 }
577 622
623 /// Helper function to clean up duplicate code in HashMap.
624 fn array_claim_and_decode_header<T: MojomEncodable>(decoder: &mut Decoder, offse t: usize) -> Result<(Context, usize), ValidationError> {
625 let context = match decoder.claim(offset) {
626 Ok(new_context) => new_context,
627 Err(err) => return Err(err),
628 };
629 let elems = {
630 let state = decoder.get_mut(&context);
631 match state.decode_array_header::<T>() {
632 Ok(header) => header.data(),
633 Err(err) => return Err(err),
634 }
635 };
636 Ok((context, elems as usize))
637 }
638
578 impl<K: MojomEncodable + Eq + Hash, V: MojomEncodable> MojomPointer for HashMap< K, V> { 639 impl<K: MojomEncodable + Eq + Hash, V: MojomEncodable> MojomPointer for HashMap< K, V> {
579 fn header_data(&self) -> DataHeaderValue { 640 fn header_data(&self) -> DataHeaderValue {
580 DataHeaderValue::Version(0) 641 DataHeaderValue::Version(0)
581 } 642 }
582 fn serialized_size(&self, _context: &Context) -> usize { 643 fn serialized_size(&self, _context: &Context) -> usize {
583 MAP_SIZE 644 MAP_SIZE
584 } 645 }
585 fn encode_value(self, encoder: &mut Encoder, context: Context) { 646 fn encode_value(self, encoder: &mut Encoder, context: Context) {
586 let elems = self.len(); 647 let elems = self.len();
587 let meta_value = DataHeaderValue::Elements(elems as u32); 648 let meta_value = DataHeaderValue::Elements(elems as u32);
(...skipping 13 matching lines...) Expand all
601 // Claim space for the keys array in the encoder 662 // Claim space for the keys array in the encoder
602 let keys_context = encoder.add(&keys_data_header).unwrap(); 663 let keys_context = encoder.add(&keys_data_header).unwrap();
603 // Encode keys, setup vals 664 // Encode keys, setup vals
604 for (key, value) in self.into_iter() { 665 for (key, value) in self.into_iter() {
605 key.encode(encoder, keys_context.clone()); 666 key.encode(encoder, keys_context.clone());
606 vals_vec.push(value); 667 vals_vec.push(value);
607 } 668 }
608 // Encode vals 669 // Encode vals
609 vals_vec.encode(encoder, context.clone()) 670 vals_vec.encode(encoder, context.clone())
610 } 671 }
611 fn decode_value(decoder: &mut Decoder, context: Context) -> HashMap<K, V> { 672 fn decode_value(decoder: &mut Decoder, context: Context) -> Result<HashMap<K , V>, ValidationError> {
612 // TODO(mknyszek): Verify elems, bytes, and T::embed_size match
613 let (keys_offset, vals_offset) = { 673 let (keys_offset, vals_offset) = {
614 let mut state = decoder.get_mut(&context); 674 let state = decoder.get_mut(&context);
615 let _bytes = state.decode::<u32>(); 675 match state.decode_struct_header(&MAP_VERSIONS) {
616 let _version = state.decode::<u32>(); 676 Ok(_) => (),
617 let keys_offset = state.decode_pointer() as usize; 677 Err(err) => return Err(err),
618 let vals_offset = state.decode_pointer() as usize; 678 };
619 (keys_offset, vals_offset) 679 // Decode the keys pointer and check for overflow
680 let keys_offset = match state.decode_pointer() {
681 Some(ptr) => ptr,
682 None => return Err(ValidationError::IllegalPointer),
683 };
684 // Decode the keys pointer and check for overflow
685 let vals_offset = match state.decode_pointer() {
686 Some(ptr) => ptr,
687 None => return Err(ValidationError::IllegalPointer),
688 };
689 if keys_offset == MOJOM_NULL_POINTER || vals_offset == MOJOM_NULL_PO INTER {
690 return Err(ValidationError::UnexpectedNullPointer);
691 }
692 (keys_offset as usize, vals_offset as usize)
620 }; 693 };
621 let keys_context = decoder.claim(keys_offset).unwrap(); 694 let (keys_context, keys_elems) = match array_claim_and_decode_header::<K >(decoder, keys_offset) {
622 let keys_elems = { 695 Ok((context, elems)) => (context, elems),
623 let state = decoder.get_mut(&keys_context); 696 Err(err) => return Err(err),
624 let _size_keys = state.decode::<u32>();
625 state.decode::<u32>()
626 }; 697 };
627 let mut keys_vec: Vec<K> = Vec::with_capacity(keys_elems as usize); 698 let mut keys_vec: Vec<K> = Vec::with_capacity(keys_elems as usize);
628 for _ in 0..keys_elems { 699 for _ in 0..keys_elems {
629 let key = K::decode(decoder, keys_context.clone()); 700 let key = match K::decode(decoder, keys_context.clone()) {
701 Ok(value) => value,
702 Err(err) => return Err(err),
703 };
630 keys_vec.push(key); 704 keys_vec.push(key);
631 } 705 }
632 let vals_context = decoder.claim(vals_offset).unwrap(); 706 let (vals_context, vals_elems) = match array_claim_and_decode_header::<V >(decoder, vals_offset) {
633 let vals_elems = { 707 Ok((context, elems)) => (context, elems),
634 let state = decoder.get_mut(&vals_context); 708 Err(err) => return Err(err),
635 let _size_vals = state.decode::<u32>();
636 state.decode::<u32>()
637 }; 709 };
638 // TODO(mknyszek): Do a validation error instead 710 if keys_elems != vals_elems {
639 assert_eq!(keys_elems, vals_elems); 711 return Err(ValidationError::DifferentSizedArraysInMap);
640 // TODO(mknyszek): Don't trust elems blindly 712 }
641 let mut map = HashMap::with_capacity(keys_elems as usize); 713 let mut map = HashMap::with_capacity(keys_elems as usize);
642 for key in keys_vec.into_iter() { 714 for key in keys_vec.into_iter() {
643 let val = V::decode(decoder, vals_context.clone()); 715 let val = match V::decode(decoder, vals_context.clone()) {
716 Ok(value) => value,
717 Err(err) => return Err(err),
718 };
644 map.insert(key, val); 719 map.insert(key, val);
645 } 720 }
646 map 721 Ok(map)
647 } 722 }
648 } 723 }
649 724
650 impl<K: MojomEncodable + Eq + Hash, V: MojomEncodable> MojomEncodable for HashMa p<K, V> { 725 impl<K: MojomEncodable + Eq + Hash, V: MojomEncodable> MojomEncodable for HashMa p<K, V> {
651 impl_encodable_for_pointer!(); 726 impl_encodable_for_pointer!();
652 fn compute_size(&self, context: Context) -> usize { 727 fn compute_size(&self, context: Context) -> usize {
653 let mut size = encoding::align_default(self.serialized_size(&context)); 728 let mut size = encoding::align_default(self.serialized_size(&context));
654 // The size of the one array 729 // The size of the one array
655 size += DATA_HEADER_SIZE; 730 size += DATA_HEADER_SIZE;
656 size += (K::embed_size(&context) * self.len()).as_bytes(); 731 size += (K::embed_size(&context) * self.len()).as_bytes();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
688 Bits(8 * mem::size_of::<u32>()) 763 Bits(8 * mem::size_of::<u32>())
689 } 764 }
690 fn compute_size(&self, _context: Context) -> usize { 765 fn compute_size(&self, _context: Context) -> usize {
691 0 766 0
692 } 767 }
693 fn encode(self, encoder: &mut Encoder, context: Context) { 768 fn encode(self, encoder: &mut Encoder, context: Context) {
694 let pos = encoder.add_handle(self.as_untyped()); 769 let pos = encoder.add_handle(self.as_untyped());
695 let mut state = encoder.get_mut(&context); 770 let mut state = encoder.get_mut(&context);
696 state.encode(pos as i32); 771 state.encode(pos as i32);
697 } 772 }
698 fn decode(decoder: &mut Decoder, context: Context) -> $handle_type { 773 fn decode(decoder: &mut Decoder, context: Context) -> Result<$handle_typ e, ValidationError> {
699 // TODO(mknyszek): Verify handle index
700 let handle_index = { 774 let handle_index = {
701 let mut state = decoder.get_mut(&context); 775 let mut state = decoder.get_mut(&context);
702 state.decode::<i32>() 776 state.decode::<i32>()
703 }; 777 };
704 decoder.claim_handle::<$handle_type>(handle_index) 778 decoder.claim_handle::<$handle_type>(handle_index)
705 } 779 }
706 } 780 }
707 } 781 }
708 782
709 impl MojomEncodable for UntypedHandle { 783 impl MojomEncodable for UntypedHandle {
(...skipping 12 matching lines...) Expand all
722 impl_encodable_for_handle!(data_pipe::Consumer<T>); 796 impl_encodable_for_handle!(data_pipe::Consumer<T>);
723 } 797 }
724 798
725 impl<T> MojomEncodable for data_pipe::Producer<T> { 799 impl<T> MojomEncodable for data_pipe::Producer<T> {
726 impl_encodable_for_handle!(data_pipe::Producer<T>); 800 impl_encodable_for_handle!(data_pipe::Producer<T>);
727 } 801 }
728 802
729 impl MojomEncodable for wait_set::WaitSet { 803 impl MojomEncodable for wait_set::WaitSet {
730 impl_encodable_for_handle!(wait_set::WaitSet); 804 impl_encodable_for_handle!(wait_set::WaitSet);
731 } 805 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698