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 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_VALIDATION_ERRORS_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_VALIDATION_ERRORS_H_ 7 8 #include "mojo/public/cpp/system/macros.h" 9 10 namespace mojo { 11 namespace internal { 12 13 enum ValidationError { 14 // There is no validation error. 15 VALIDATION_ERROR_NONE, 16 // An object (struct or array) is not 8-byte aligned. 17 VALIDATION_ERROR_MISALIGNED_OBJECT, 18 // An object is not contained inside the message data, or it overlaps other 19 // objects. 20 VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE, 21 // A struct header doesn't make sense, for example: 22 // - |num_bytes| is smaller than the size of the oldest version that we 23 // support. 24 // - |num_fields| is smaller than the field number of the oldest version that 25 // we support. 26 // - |num_bytes| and |num_fields| don't match. 27 VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER, 28 // An array header doesn't make sense, for example: 29 // - |num_bytes| is smaller than the size of the header plus the size required 30 // to store |num_elements| elements. 31 // - For fixed-size arrays, |num_elements| is different than the specified 32 // size. 33 VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER, 34 // An encoded handle is illegal. 35 VALIDATION_ERROR_ILLEGAL_HANDLE, 36 // A non-nullable handle field is set to invalid handle. 37 VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE, 38 // An encoded pointer is illegal. 39 VALIDATION_ERROR_ILLEGAL_POINTER, 40 // A non-nullable pointer field is set to null. 41 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, 42 // |flags| in the message header is an invalid flag combination. 43 VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAG_COMBINATION, 44 // |flags| in the message header indicates that a request ID is required but 45 // there isn't one. 46 VALIDATION_ERROR_MESSAGE_HEADER_MISSING_REQUEST_ID, 47 }; 48 49 const char* ValidationErrorToString(ValidationError error); 50 51 void ReportValidationError(ValidationError error, 52 const char* description = NULL); 53 54 // Only used by validation tests and when there is only one thread doing message 55 // validation. 56 class ValidationErrorObserverForTesting { 57 public: 58 ValidationErrorObserverForTesting(); 59 ~ValidationErrorObserverForTesting(); 60 last_error()61 ValidationError last_error() const { return last_error_; } set_last_error(ValidationError error)62 void set_last_error(ValidationError error) { last_error_ = error; } 63 64 private: 65 ValidationError last_error_; 66 67 MOJO_DISALLOW_COPY_AND_ASSIGN(ValidationErrorObserverForTesting); 68 }; 69 70 // Used only by MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING. Don't use it directly. 71 // 72 // The function returns true if the error is recorded (by a 73 // SerializationWarningObserverForTesting object), false otherwise. 74 bool ReportSerializationWarning(ValidationError error); 75 76 // Only used by serialization tests and when there is only one thread doing 77 // message serialization. 78 class SerializationWarningObserverForTesting { 79 public: 80 SerializationWarningObserverForTesting(); 81 ~SerializationWarningObserverForTesting(); 82 last_warning()83 ValidationError last_warning() const { return last_warning_; } set_last_warning(ValidationError error)84 void set_last_warning(ValidationError error) { last_warning_ = error; } 85 86 private: 87 ValidationError last_warning_; 88 89 MOJO_DISALLOW_COPY_AND_ASSIGN(SerializationWarningObserverForTesting); 90 }; 91 92 } // namespace internal 93 } // namespace mojo 94 95 // In debug build, logs a serialization warning if |condition| evaluates to 96 // true: 97 // - if there is a SerializationWarningObserverForTesting object alive, 98 // records |error| in it; 99 // - otherwise, logs a fatal-level message. 100 // |error| is the validation error that will be triggered by the receiver 101 // of the serialzation result. 102 // 103 // In non-debug build, does nothing (not even compiling |condition|). 104 #define MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( \ 105 condition, error, description) \ 106 MOJO_DLOG_IF(FATAL, (condition) && !ReportSerializationWarning(error)) \ 107 << "The outgoing message will trigger " \ 108 << ValidationErrorToString(error) << " at the receiving side (" \ 109 << description << ")."; 110 111 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_VALIDATION_ERRORS_H_ 112