1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_VALIDATION_ERRORS_H_
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_VALIDATION_ERRORS_H_
#include "base/logging.h"
#include "base/macros.h"
#include "mojo/public/cpp/bindings/callback.h"
namespace mojo {
namespace internal {
enum ValidationError {
// There is no validation error.
VALIDATION_ERROR_NONE,
// An object (struct or array) is not 8-byte aligned.
VALIDATION_ERROR_MISALIGNED_OBJECT,
// An object is not contained inside the message data, or it overlaps other
// objects.
VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE,
// A struct header doesn't make sense, for example:
// - |num_bytes| is smaller than the size of the struct header.
// - |num_bytes| and |version| don't match.
// TODO(yzshen): Consider splitting it into two different error codes. Because
// the former indicates someone is misbehaving badly whereas the latter could
// be due to an inappropriately-modified .mojom file.
VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER,
// An array header doesn't make sense, for example:
// - |num_bytes| is smaller than the size of the header plus the size required
// to store |num_elements| elements.
// - For fixed-size arrays, |num_elements| is different than the specified
// size.
VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER,
// An encoded handle is illegal.
VALIDATION_ERROR_ILLEGAL_HANDLE,
// A non-nullable handle field is set to invalid handle.
VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
// An encoded pointer is illegal.
VALIDATION_ERROR_ILLEGAL_POINTER,
// A non-nullable pointer field is set to null.
VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
// An interface ID is illegal.
VALIDATION_ERROR_ILLEGAL_INTERFACE_ID,
// A non-nullable interface ID field is set to invalid.
VALIDATION_ERROR_UNEXPECTED_INVALID_INTERFACE_ID,
// |flags| in the message header is invalid. The flags are either
// inconsistent with one another, inconsistent with other parts of the
// message, or unexpected for the message receiver. For example the
// receiver is expecting a request message but the flags indicate that
// the message is a response message.
VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS,
// |flags| in the message header indicates that a request ID is required but
// there isn't one.
VALIDATION_ERROR_MESSAGE_HEADER_MISSING_REQUEST_ID,
// The |name| field in a message header contains an unexpected value.
VALIDATION_ERROR_MESSAGE_HEADER_UNKNOWN_METHOD,
// Two parallel arrays which are supposed to represent a map have different
// lengths.
VALIDATION_ERROR_DIFFERENT_SIZED_ARRAYS_IN_MAP,
// Attempted to deserialize a tagged union with an unknown tag.
VALIDATION_ERROR_UNKNOWN_UNION_TAG,
// A value of a non-extensible enum type is unknown.
VALIDATION_ERROR_UNKNOWN_ENUM_VALUE
};
const char* ValidationErrorToString(ValidationError error);
void ReportValidationError(ValidationError error,
const char* description = nullptr);
// Only used by validation tests and when there is only one thread doing message
// validation.
class ValidationErrorObserverForTesting {
public:
explicit ValidationErrorObserverForTesting(const Callback<void()>& callback);
~ValidationErrorObserverForTesting();
ValidationError last_error() const { return last_error_; }
void set_last_error(ValidationError error) {
last_error_ = error;
callback_.Run();
}
private:
ValidationError last_error_;
Callback<void()> callback_;
DISALLOW_COPY_AND_ASSIGN(ValidationErrorObserverForTesting);
};
// Used only by MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING. Don't use it directly.
//
// The function returns true if the error is recorded (by a
// SerializationWarningObserverForTesting object), false otherwise.
bool ReportSerializationWarning(ValidationError error);
// Only used by serialization tests and when there is only one thread doing
// message serialization.
class SerializationWarningObserverForTesting {
public:
SerializationWarningObserverForTesting();
~SerializationWarningObserverForTesting();
ValidationError last_warning() const { return last_warning_; }
void set_last_warning(ValidationError error) { last_warning_ = error; }
private:
ValidationError last_warning_;
DISALLOW_COPY_AND_ASSIGN(SerializationWarningObserverForTesting);
};
} // namespace internal
} // namespace mojo
// In debug build, logs a serialization warning if |condition| evaluates to
// true:
// - if there is a SerializationWarningObserverForTesting object alive,
// records |error| in it;
// - otherwise, logs a fatal-level message.
// |error| is the validation error that will be triggered by the receiver
// of the serialzation result.
//
// In non-debug build, does nothing (not even compiling |condition|).
#define MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(condition, error, \
description) \
DLOG_IF(FATAL, (condition) && !ReportSerializationWarning(error)) \
<< "The outgoing message will trigger " \
<< ValidationErrorToString(error) << " at the receiving side (" \
<< description << ").";
#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_VALIDATION_ERRORS_H_
|