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

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

Powered by Google App Engine
This is Rietveld 408576698