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

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

Powered by Google App Engine
This is Rietveld 408576698