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

Side by Side Diff: mojo/system/message_in_transit.cc

Issue 265753006: Mojo: Factor MessageInTransit secondary buffer stuff out into a separate class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: oops Created 6 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « mojo/system/message_in_transit.h ('k') | mojo/system/message_pipe.cc » ('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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 #include "mojo/system/message_in_transit.h" 5 #include "mojo/system/message_in_transit.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include <new>
10
11 #include "base/compiler_specific.h" 9 #include "base/compiler_specific.h"
12 #include "base/logging.h" 10 #include "base/logging.h"
13 #include "mojo/system/constants.h" 11 #include "mojo/system/constants.h"
12 #include "mojo/system/transport_data.h"
14 13
15 namespace mojo { 14 namespace mojo {
16 namespace system { 15 namespace system {
17 16
18 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type 17 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type
19 MessageInTransit::kTypeMessagePipeEndpoint; 18 MessageInTransit::kTypeMessagePipeEndpoint;
20 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type 19 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type
21 MessageInTransit::kTypeMessagePipe; 20 MessageInTransit::kTypeMessagePipe;
22 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type 21 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type
23 MessageInTransit::kTypeChannel; 22 MessageInTransit::kTypeChannel;
24 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype 23 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype
25 MessageInTransit::kSubtypeMessagePipeEndpointData; 24 MessageInTransit::kSubtypeMessagePipeEndpointData;
26 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype 25 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype
27 MessageInTransit::kSubtypeChannelRunMessagePipeEndpoint; 26 MessageInTransit::kSubtypeChannelRunMessagePipeEndpoint;
28 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype 27 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype
29 MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpoint; 28 MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpoint;
30 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype 29 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype
31 MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpointAck; 30 MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpointAck;
32 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::EndpointId 31 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::EndpointId
33 MessageInTransit::kInvalidEndpointId; 32 MessageInTransit::kInvalidEndpointId;
34 STATIC_CONST_MEMBER_DEFINITION const size_t MessageInTransit::kMessageAlignment; 33 STATIC_CONST_MEMBER_DEFINITION const size_t MessageInTransit::kMessageAlignment;
35 STATIC_CONST_MEMBER_DEFINITION const size_t
36 MessageInTransit::kMaxSerializedDispatcherSize;
37 STATIC_CONST_MEMBER_DEFINITION const size_t
38 MessageInTransit::kMaxSerializedDispatcherPlatformHandles;
39 34
40 struct MessageInTransit::PrivateStructForCompileAsserts { 35 struct MessageInTransit::PrivateStructForCompileAsserts {
41 // The size of |Header| must be a multiple of the alignment. 36 // The size of |Header| must be a multiple of the alignment.
42 COMPILE_ASSERT(sizeof(Header) % kMessageAlignment == 0, 37 COMPILE_ASSERT(sizeof(Header) % kMessageAlignment == 0,
43 sizeof_MessageInTransit_Header_invalid); 38 sizeof_MessageInTransit_Header_invalid);
44 // Avoid dangerous situations, but making sure that the size of the "header" + 39 // Avoid dangerous situations, but making sure that the size of the "header" +
45 // the size of the data fits into a 31-bit number. 40 // the size of the data fits into a 31-bit number.
46 COMPILE_ASSERT(static_cast<uint64_t>(sizeof(Header)) + kMaxMessageNumBytes <= 41 COMPILE_ASSERT(static_cast<uint64_t>(sizeof(Header)) + kMaxMessageNumBytes <=
47 0x7fffffffULL, 42 0x7fffffffULL,
48 kMaxMessageNumBytes_too_big); 43 kMaxMessageNumBytes_too_big);
49 44
50 // We assume (to avoid extra rounding code) that the maximum message (data) 45 // We assume (to avoid extra rounding code) that the maximum message (data)
51 // size is a multiple of the alignment. 46 // size is a multiple of the alignment.
52 COMPILE_ASSERT(kMaxMessageNumBytes % kMessageAlignment == 0, 47 COMPILE_ASSERT(kMaxMessageNumBytes % kMessageAlignment == 0,
53 kMessageAlignment_not_a_multiple_of_alignment); 48 kMessageAlignment_not_a_multiple_of_alignment);
54
55 // The maximum serialized dispatcher size must be a multiple of the alignment.
56 COMPILE_ASSERT(kMaxSerializedDispatcherSize % kMessageAlignment == 0,
57 kMaxSerializedDispatcherSize_not_a_multiple_of_alignment);
58
59 // The size of |HandleTableEntry| must be a multiple of the alignment.
60 COMPILE_ASSERT(sizeof(HandleTableEntry) % kMessageAlignment == 0,
61 sizeof_MessageInTransit_HandleTableEntry_invalid);
62 }; 49 };
63 50
64 // For each attached (Mojo) handle, there'll be a handle table entry and
65 // serialized dispatcher data.
66 // static
67 const size_t MessageInTransit::kMaxSecondaryBufferSize = kMaxMessageNumHandles *
68 (sizeof(HandleTableEntry) + kMaxSerializedDispatcherSize);
69
70 // static
71 const size_t MessageInTransit::kMaxPlatformHandles =
72 kMaxMessageNumHandles * kMaxSerializedDispatcherPlatformHandles;
73
74 MessageInTransit::View::View(size_t message_size, const void* buffer) 51 MessageInTransit::View::View(size_t message_size, const void* buffer)
75 : buffer_(buffer) { 52 : buffer_(buffer) {
76 size_t next_message_size = 0; 53 size_t next_message_size = 0;
77 DCHECK(MessageInTransit::GetNextMessageSize(buffer_, message_size, 54 DCHECK(MessageInTransit::GetNextMessageSize(buffer_, message_size,
78 &next_message_size)); 55 &next_message_size));
79 DCHECK_EQ(message_size, next_message_size); 56 DCHECK_EQ(message_size, next_message_size);
80 // This should be equivalent. 57 // This should be equivalent.
81 DCHECK_EQ(message_size, total_size()); 58 DCHECK_EQ(message_size, total_size());
82 } 59 }
83 60
84 bool MessageInTransit::View::IsValid(const char** error_message) const { 61 bool MessageInTransit::View::IsValid(const char** error_message) const {
85 // Note: This also implies a check on the |main_buffer_size()|, which is just 62 // Note: This also implies a check on the |main_buffer_size()|, which is just
86 // |RoundUpMessageAlignment(sizeof(Header) + num_bytes())|. 63 // |RoundUpMessageAlignment(sizeof(Header) + num_bytes())|.
87 if (num_bytes() > kMaxMessageNumBytes) { 64 if (num_bytes() > kMaxMessageNumBytes) {
88 *error_message = "Message data payload too large"; 65 *error_message = "Message data payload too large";
89 return false; 66 return false;
90 } 67 }
91 68
92 if (const char* secondary_buffer_error_message = 69 if (transport_data_buffer_size() > 0) {
93 ValidateSecondaryBuffer(num_handles(), secondary_buffer(), 70 const char* e = TransportData::ValidateBuffer(transport_data_buffer(),
94 secondary_buffer_size())) { 71 transport_data_buffer_size());
95 *error_message = secondary_buffer_error_message; 72 if (e) {
96 return false; 73 *error_message = e;
74 return false;
75 }
97 } 76 }
98 77
99 return true; 78 return true;
100 } 79 }
101 80
102 MessageInTransit::MessageInTransit(Type type, 81 MessageInTransit::MessageInTransit(Type type,
103 Subtype subtype, 82 Subtype subtype,
104 uint32_t num_bytes, 83 uint32_t num_bytes,
105 uint32_t num_handles,
106 const void* bytes) 84 const void* bytes)
107 : main_buffer_size_(RoundUpMessageAlignment(sizeof(Header) + num_bytes)), 85 : main_buffer_size_(RoundUpMessageAlignment(sizeof(Header) + num_bytes)),
108 main_buffer_(static_cast<char*>(base::AlignedAlloc(main_buffer_size_, 86 main_buffer_(static_cast<char*>(base::AlignedAlloc(main_buffer_size_,
109 kMessageAlignment))), 87 kMessageAlignment))) {
110 secondary_buffer_size_(0) {
111 DCHECK_LE(num_bytes, kMaxMessageNumBytes); 88 DCHECK_LE(num_bytes, kMaxMessageNumBytes);
112 DCHECK_LE(num_handles, kMaxMessageNumHandles);
113 89
114 // |total_size| is updated below, from the other values. 90 // |total_size| is updated below, from the other values.
115 header()->type = type; 91 header()->type = type;
116 header()->subtype = subtype; 92 header()->subtype = subtype;
117 header()->source_id = kInvalidEndpointId; 93 header()->source_id = kInvalidEndpointId;
118 header()->destination_id = kInvalidEndpointId; 94 header()->destination_id = kInvalidEndpointId;
119 header()->num_bytes = num_bytes; 95 header()->num_bytes = num_bytes;
120 header()->num_handles = num_handles; 96 // Note: If dispatchers are subsequently attached, then |total_size| will have
121 // Note: If dispatchers are subsequently attached (in particular, if 97 // to be adjusted.
122 // |num_handles| is nonzero), then |total_size| will have to be adjusted.
123 UpdateTotalSize(); 98 UpdateTotalSize();
124 99
125 if (bytes) { 100 if (bytes) {
126 memcpy(MessageInTransit::bytes(), bytes, num_bytes); 101 memcpy(MessageInTransit::bytes(), bytes, num_bytes);
127 memset(static_cast<char*>(MessageInTransit::bytes()) + num_bytes, 0, 102 memset(static_cast<char*>(MessageInTransit::bytes()) + num_bytes, 0,
128 main_buffer_size_ - sizeof(Header) - num_bytes); 103 main_buffer_size_ - sizeof(Header) - num_bytes);
129 } else { 104 } else {
130 memset(MessageInTransit::bytes(), 0, main_buffer_size_ - sizeof(Header)); 105 memset(MessageInTransit::bytes(), 0, main_buffer_size_ - sizeof(Header));
131 } 106 }
132 } 107 }
133 108
134 // TODO(vtl): Do I really want/need to copy the secondary buffer here, or should
135 // I just create (deserialize) the dispatchers right away?
136 MessageInTransit::MessageInTransit(const View& message_view) 109 MessageInTransit::MessageInTransit(const View& message_view)
137 : main_buffer_size_(message_view.main_buffer_size()), 110 : main_buffer_size_(message_view.main_buffer_size()),
138 main_buffer_(static_cast<char*>(base::AlignedAlloc(main_buffer_size_, 111 main_buffer_(static_cast<char*>(base::AlignedAlloc(main_buffer_size_,
139 kMessageAlignment))), 112 kMessageAlignment))) {
140 secondary_buffer_size_(message_view.secondary_buffer_size()),
141 secondary_buffer_(secondary_buffer_size_ ?
142 static_cast<char*>(
143 base::AlignedAlloc(secondary_buffer_size_,
144 kMessageAlignment)) : NULL) {
145 DCHECK_GE(main_buffer_size_, sizeof(Header)); 113 DCHECK_GE(main_buffer_size_, sizeof(Header));
146 DCHECK_EQ(main_buffer_size_ % kMessageAlignment, 0u); 114 DCHECK_EQ(main_buffer_size_ % kMessageAlignment, 0u);
147 115
148 memcpy(main_buffer_.get(), message_view.main_buffer(), main_buffer_size_); 116 memcpy(main_buffer_.get(), message_view.main_buffer(), main_buffer_size_);
149 memcpy(secondary_buffer_.get(), message_view.secondary_buffer(),
150 secondary_buffer_size_);
151
152 DCHECK_EQ(main_buffer_size_, 117 DCHECK_EQ(main_buffer_size_,
153 RoundUpMessageAlignment(sizeof(Header) + num_bytes())); 118 RoundUpMessageAlignment(sizeof(Header) + num_bytes()));
154 } 119 }
155 120
156 MessageInTransit::~MessageInTransit() { 121 MessageInTransit::~MessageInTransit() {
157 if (dispatchers_) { 122 if (dispatchers_) {
158 for (size_t i = 0; i < dispatchers_->size(); i++) { 123 for (size_t i = 0; i < dispatchers_->size(); i++) {
159 if (!(*dispatchers_)[i]) 124 if (!(*dispatchers_)[i])
160 continue; 125 continue;
161 126
162 DCHECK((*dispatchers_)[i]->HasOneRef()); 127 DCHECK((*dispatchers_)[i]->HasOneRef());
163 (*dispatchers_)[i]->Close(); 128 (*dispatchers_)[i]->Close();
164 } 129 }
165 } 130 }
166
167 if (platform_handles_) {
168 for (size_t i = 0; i < platform_handles_->size(); i++)
169 (*platform_handles_)[i].CloseIfNecessary();
170 }
171
172 #ifndef NDEBUG
173 secondary_buffer_size_ = 0;
174 dispatchers_.reset();
175 platform_handles_.reset();
176 #endif
177 } 131 }
178 132
179 // static 133 // static
180 bool MessageInTransit::GetNextMessageSize(const void* buffer, 134 bool MessageInTransit::GetNextMessageSize(const void* buffer,
181 size_t buffer_size, 135 size_t buffer_size,
182 size_t* next_message_size) { 136 size_t* next_message_size) {
183 DCHECK(next_message_size); 137 DCHECK(next_message_size);
184 if (!buffer_size) 138 if (!buffer_size)
185 return false; 139 return false;
186 DCHECK(buffer); 140 DCHECK(buffer);
(...skipping 16 matching lines...) Expand all
203 157
204 dispatchers_ = dispatchers.Pass(); 158 dispatchers_ = dispatchers.Pass();
205 #ifndef NDEBUG 159 #ifndef NDEBUG
206 for (size_t i = 0; i < dispatchers_->size(); i++) 160 for (size_t i = 0; i < dispatchers_->size(); i++)
207 DCHECK(!(*dispatchers_)[i] || (*dispatchers_)[i]->HasOneRef()); 161 DCHECK(!(*dispatchers_)[i] || (*dispatchers_)[i]->HasOneRef());
208 #endif 162 #endif
209 } 163 }
210 164
211 void MessageInTransit::SerializeAndCloseDispatchers(Channel* channel) { 165 void MessageInTransit::SerializeAndCloseDispatchers(Channel* channel) {
212 DCHECK(channel); 166 DCHECK(channel);
213 DCHECK(!secondary_buffer_); 167 DCHECK(!transport_data_);
214 168
215 const size_t num_handles = dispatchers_ ? dispatchers_->size() : 0; 169 if (!dispatchers_ || !dispatchers_->size())
216 if (!num_handles)
217 return; 170 return;
218 171
219 // The offset to the start of the (Mojo) handle table. 172 transport_data_.reset(new TransportData(dispatchers_.Pass(), channel));
220 // TODO(vtl): Add a header to the secondary buffer.
221 const size_t handle_table_start_offset = 0;
222 // The offset to the start of the serialized dispatcher data.
223 const size_t serialized_dispatcher_start_offset =
224 handle_table_start_offset + num_handles * sizeof(HandleTableEntry);
225 // The estimated size of the secondary buffer. We compute this estimate below.
226 // It must be at least as big as the (eventual) actual size.
227 size_t estimated_size = serialized_dispatcher_start_offset;
228 size_t num_platform_handles = 0;
229 #if DCHECK_IS_ON
230 std::vector<size_t> all_max_sizes(num_handles);
231 std::vector<size_t> all_max_platform_handles(num_handles);
232 #endif
233 for (size_t i = 0; i < num_handles; i++) {
234 if (Dispatcher* dispatcher = (*dispatchers_)[i].get()) {
235 size_t max_size = 0;
236 size_t max_platform_handles = 0;
237 Dispatcher::MessageInTransitAccess::StartSerialize(
238 dispatcher, channel, &max_size, &max_platform_handles);
239
240 DCHECK_LE(max_size, kMaxSerializedDispatcherSize);
241 estimated_size += RoundUpMessageAlignment(max_size);
242 DCHECK_LE(estimated_size, kMaxSecondaryBufferSize);
243
244 DCHECK_LE(max_platform_handles,
245 kMaxSerializedDispatcherPlatformHandles);
246 num_platform_handles += max_platform_handles;
247 DCHECK_LE(num_platform_handles, kMaxPlatformHandles);
248
249 #if DCHECK_IS_ON
250 all_max_sizes[i] = max_size;
251 all_max_platform_handles[i] = max_platform_handles;
252 #endif
253 }
254 }
255
256 secondary_buffer_.reset(static_cast<char*>(
257 base::AlignedAlloc(estimated_size, kMessageAlignment)));
258 // Entirely clear out the secondary buffer, since then we won't have to worry
259 // about clearing padding or unused space (e.g., if a dispatcher fails to
260 // serialize).
261 memset(secondary_buffer_.get(), 0, estimated_size);
262
263 if (num_platform_handles > 0) {
264 DCHECK(!platform_handles_);
265 platform_handles_.reset(new std::vector<embedder::PlatformHandle>());
266 }
267
268 HandleTableEntry* handle_table = reinterpret_cast<HandleTableEntry*>(
269 secondary_buffer_.get() + handle_table_start_offset);
270 size_t current_offset = serialized_dispatcher_start_offset;
271 for (size_t i = 0; i < num_handles; i++) {
272 Dispatcher* dispatcher = (*dispatchers_)[i].get();
273 if (!dispatcher) {
274 COMPILE_ASSERT(Dispatcher::kTypeUnknown == 0,
275 value_of_Dispatcher_kTypeUnknown_must_be_zero);
276 continue;
277 }
278
279 #if DCHECK_IS_ON
280 size_t old_platform_handles_size =
281 platform_handles_ ? platform_handles_->size() : 0;
282 #endif
283
284 void* destination = secondary_buffer_.get() + current_offset;
285 size_t actual_size = 0;
286 if (Dispatcher::MessageInTransitAccess::EndSerializeAndClose(
287 dispatcher, channel, destination, &actual_size,
288 platform_handles_.get())) {
289 handle_table[i].type = static_cast<int32_t>(dispatcher->GetType());
290 handle_table[i].offset = static_cast<uint32_t>(current_offset);
291 handle_table[i].size = static_cast<uint32_t>(actual_size);
292
293 #if DCHECK_IS_ON
294 DCHECK_LE(actual_size, all_max_sizes[i]);
295 DCHECK_LE(platform_handles_ ? (platform_handles_->size() -
296 old_platform_handles_size) : 0,
297 all_max_platform_handles[i]);
298 #endif
299 } else {
300 // Nothing to do on failure, since |secondary_buffer_| was cleared, and
301 // |kTypeUnknown| is zero. The handle was simply closed.
302 LOG(ERROR) << "Failed to serialize handle to remote message pipe";
303 }
304
305 current_offset += RoundUpMessageAlignment(actual_size);
306 DCHECK_LE(current_offset, estimated_size);
307 DCHECK_LE(platform_handles_ ? platform_handles_->size() : 0,
308 num_platform_handles);
309 }
310
311 // There's no aligned realloc, so it's no good way to release unused space (if
312 // we overshot our estimated space requirements).
313 secondary_buffer_size_ = current_offset;
314
315 // The dispatchers (which we "owned") were closed. We can dispose of them now.
316 dispatchers_.reset();
317 173
318 // Update the sizes in the message header. 174 // Update the sizes in the message header.
319 UpdateTotalSize(); 175 UpdateTotalSize();
320 } 176 }
321 177
322 // Note: The message's secondary buffer should have been checked by calling 178 void MessageInTransit::UpdateTotalSize() {
323 // |View::IsValid()| (on the |View|) first. 179 DCHECK_EQ(main_buffer_size_ % kMessageAlignment, 0u);
324 void MessageInTransit::DeserializeDispatchers(Channel* channel) { 180 header()->total_size = static_cast<uint32_t>(main_buffer_size_);
325 DCHECK(!dispatchers_); 181 if (transport_data_) {
326 182 header()->total_size +=
327 // Already checked by |View::IsValid()|: 183 static_cast<uint32_t>(transport_data_->buffer_size());
328 DCHECK_LE(num_handles(), kMaxMessageNumHandles);
329
330 if (!num_handles())
331 return;
332
333 dispatchers_.reset(
334 new std::vector<scoped_refptr<Dispatcher> >(num_handles()));
335
336 size_t handle_table_size = num_handles() * sizeof(HandleTableEntry);
337 // Already checked by |View::IsValid()|:
338 DCHECK_LE(handle_table_size, secondary_buffer_size_);
339
340 const HandleTableEntry* handle_table =
341 reinterpret_cast<const HandleTableEntry*>(secondary_buffer_.get());
342 for (size_t i = 0; i < num_handles(); i++) {
343 size_t offset = handle_table[i].offset;
344 size_t size = handle_table[i].size;
345 // Already checked by |View::IsValid()|:
346 DCHECK_EQ(offset % kMessageAlignment, 0u);
347 DCHECK_LE(offset, secondary_buffer_size_);
348 DCHECK_LE(offset + size, secondary_buffer_size_);
349
350 const void* source = secondary_buffer_.get() + offset;
351 (*dispatchers_)[i] = Dispatcher::MessageInTransitAccess::Deserialize(
352 channel, handle_table[i].type, source, size);
353 } 184 }
354 } 185 }
355 186
356 // Validates the secondary buffer. Returns null on success, or a human-readable
357 // error message on error.
358 // static
359 const char* MessageInTransit::ValidateSecondaryBuffer(
360 size_t num_handles,
361 const void* secondary_buffer,
362 size_t secondary_buffer_size) {
363 // Always make sure that the secondary buffer size is sane (even if we have no
364 // handles); if it's not, someone's messing with us.
365 if (secondary_buffer_size > kMaxSecondaryBufferSize)
366 return "Message secondary buffer too large";
367
368 // Fast-path for the common case (no handles => no secondary buffer).
369 if (num_handles == 0) {
370 // We shouldn't have a secondary buffer in this case.
371 if (secondary_buffer_size > 0)
372 return "Message has no handles attached, but secondary buffer present";
373 return NULL;
374 }
375
376 // Sanity-check |num_handles| (before multiplying it against anything).
377 if (num_handles > kMaxMessageNumHandles)
378 return "Message handle payload too large";
379
380 if (secondary_buffer_size < num_handles * sizeof(HandleTableEntry))
381 return "Message secondary buffer too small";
382
383 DCHECK(secondary_buffer);
384 const HandleTableEntry* handle_table =
385 static_cast<const HandleTableEntry*>(secondary_buffer);
386
387 static const char kInvalidSerializedDispatcher[] =
388 "Message contains invalid serialized dispatcher";
389 for (size_t i = 0; i < num_handles; i++) {
390 size_t offset = handle_table[i].offset;
391 if (offset % kMessageAlignment != 0)
392 return kInvalidSerializedDispatcher;
393
394 size_t size = handle_table[i].size;
395 if (size > kMaxSerializedDispatcherSize || size > secondary_buffer_size)
396 return kInvalidSerializedDispatcher;
397
398 // Note: This is an overflow-safe check for |offset + size >
399 // secondary_buffer_size()| (we know that |size <= secondary_buffer_size()|
400 // from the previous check).
401 if (offset > secondary_buffer_size - size)
402 return kInvalidSerializedDispatcher;
403 }
404
405 return NULL;
406 }
407
408 void MessageInTransit::UpdateTotalSize() {
409 DCHECK_EQ(main_buffer_size_ % kMessageAlignment, 0u);
410 DCHECK_EQ(secondary_buffer_size_ % kMessageAlignment, 0u);
411 header()->total_size =
412 static_cast<uint32_t>(main_buffer_size_ + secondary_buffer_size_);
413 }
414
415 } // namespace system 187 } // namespace system
416 } // namespace mojo 188 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/system/message_in_transit.h ('k') | mojo/system/message_pipe.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698