OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "mojo/public/cpp/bindings/lib/message_header_validator.h" | |
6 | |
7 #include "mojo/public/cpp/bindings/lib/bindings_serialization.h" | |
8 #include "mojo/public/cpp/bindings/lib/bounds_checker.h" | |
9 #include "mojo/public/cpp/bindings/lib/validation_errors.h" | |
10 | |
11 namespace mojo { | |
12 namespace internal { | |
13 namespace { | |
14 | |
15 bool IsValidMessageHeader(const MessageHeader* header) { | |
16 // NOTE: Our goal is to preserve support for future extension of the message | |
17 // header. If we encounter fields we do not understand, we must ignore them. | |
18 | |
19 // Extra validation of the struct header: | |
20 if (header->num_fields == 2) { | |
21 if (header->num_bytes != sizeof(MessageHeader)) { | |
22 ReportValidationError(VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER); | |
23 return false; | |
24 } | |
25 } else if (header->num_fields == 3) { | |
26 if (header->num_bytes != sizeof(MessageHeaderWithRequestID)) { | |
27 ReportValidationError(VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER); | |
28 return false; | |
29 } | |
30 } else if (header->num_fields > 3) { | |
31 if (header->num_bytes < sizeof(MessageHeaderWithRequestID)) { | |
32 ReportValidationError(VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER); | |
33 return false; | |
34 } | |
35 } | |
36 | |
37 // Validate flags (allow unknown bits): | |
38 | |
39 // These flags require a RequestID. | |
40 if (header->num_fields < 3 && ((header->flags & kMessageExpectsResponse) || | |
41 (header->flags & kMessageIsResponse))) { | |
42 ReportValidationError(VALIDATION_ERROR_MESSAGE_HEADER_MISSING_REQUEST_ID); | |
43 return false; | |
44 } | |
45 | |
46 // These flags are mutually exclusive. | |
47 if ((header->flags & kMessageExpectsResponse) && | |
48 (header->flags & kMessageIsResponse)) { | |
49 ReportValidationError( | |
50 VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAG_COMBINATION); | |
51 return false; | |
52 } | |
53 | |
54 return true; | |
55 } | |
56 | |
57 } // namespace | |
58 | |
59 MessageHeaderValidator::MessageHeaderValidator(MessageReceiver* sink) | |
60 : MessageFilter(sink) { | |
61 } | |
62 | |
63 bool MessageHeaderValidator::Accept(Message* message) { | |
64 // Pass 0 as number of handles because we don't expect any in the header, even | |
65 // if |message| contains handles. | |
66 BoundsChecker bounds_checker(message->data(), message->data_num_bytes(), 0); | |
67 | |
68 if (!ValidateStructHeader( | |
69 message->data(), sizeof(MessageHeader), 2, &bounds_checker)) { | |
70 return false; | |
71 } | |
72 | |
73 if (!IsValidMessageHeader(message->header())) | |
74 return false; | |
75 | |
76 return sink_->Accept(message); | |
77 } | |
78 | |
79 } // namespace internal | |
80 } // namespace mojo | |
OLD | NEW |