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/validation_errors.h" 6 7 #include "base/strings/stringprintf.h" 8 #include "mojo/public/cpp/bindings/message.h" 9 10 namespace mojo { 11 namespace internal { 12 namespace { 13 14 ValidationErrorObserverForTesting* g_validation_error_observer = nullptr; 15 SerializationWarningObserverForTesting* g_serialization_warning_observer = 16 nullptr; 17 18 } // namespace 19 20 const char* ValidationErrorToString(ValidationError error) { 21 switch (error) { 22 case VALIDATION_ERROR_NONE: 23 return "VALIDATION_ERROR_NONE"; 24 case VALIDATION_ERROR_MISALIGNED_OBJECT: 25 return "VALIDATION_ERROR_MISALIGNED_OBJECT"; 26 case VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE: 27 return "VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE"; 28 case VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER: 29 return "VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER"; 30 case VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER: 31 return "VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER"; 32 case VALIDATION_ERROR_ILLEGAL_HANDLE: 33 return "VALIDATION_ERROR_ILLEGAL_HANDLE"; 34 case VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE: 35 return "VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE"; 36 case VALIDATION_ERROR_ILLEGAL_POINTER: 37 return "VALIDATION_ERROR_ILLEGAL_POINTER"; 38 case VALIDATION_ERROR_UNEXPECTED_NULL_POINTER: 39 return "VALIDATION_ERROR_UNEXPECTED_NULL_POINTER"; 40 case VALIDATION_ERROR_ILLEGAL_INTERFACE_ID: 41 return "VALIDATION_ERROR_ILLEGAL_INTERFACE_ID"; 42 case VALIDATION_ERROR_UNEXPECTED_INVALID_INTERFACE_ID: 43 return "VALIDATION_ERROR_UNEXPECTED_INVALID_INTERFACE_ID"; 44 case VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS: 45 return "VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS"; 46 case VALIDATION_ERROR_MESSAGE_HEADER_MISSING_REQUEST_ID: 47 return "VALIDATION_ERROR_MESSAGE_HEADER_MISSING_REQUEST_ID"; 48 case VALIDATION_ERROR_MESSAGE_HEADER_UNKNOWN_METHOD: 49 return "VALIDATION_ERROR_MESSAGE_HEADER_UNKNOWN_METHOD"; 50 case VALIDATION_ERROR_DIFFERENT_SIZED_ARRAYS_IN_MAP: 51 return "VALIDATION_ERROR_DIFFERENT_SIZED_ARRAYS_IN_MAP"; 52 case VALIDATION_ERROR_UNKNOWN_UNION_TAG: 53 return "VALIDATION_ERROR_UNKNOWN_UNION_TAG"; 54 case VALIDATION_ERROR_UNKNOWN_ENUM_VALUE: 55 return "VALIDATION_ERROR_UNKNOWN_ENUM_VALUE"; 56 case VALIDATION_ERROR_DESERIALIZATION_FAILED: 57 return "VALIDATION_ERROR_DESERIALIZATION_FAILED"; 58 } 59 60 return "Unknown error"; 61 } 62 63 void ReportValidationError(ValidationContext* context, 64 ValidationError error, 65 const char* description) { 66 if (g_validation_error_observer) { 67 g_validation_error_observer->set_last_error(error); 68 return; 69 } 70 71 if (description) { 72 LOG(ERROR) << "Invalid message: " << ValidationErrorToString(error) << " (" 73 << description << ")"; 74 if (context->message()) { 75 context->message()->NotifyBadMessage( 76 base::StringPrintf("Validation failed for %s [%s (%s)]", 77 context->description().data(), 78 ValidationErrorToString(error), description)); 79 } 80 } else { 81 LOG(ERROR) << "Invalid message: " << ValidationErrorToString(error); 82 if (context->message()) { 83 context->message()->NotifyBadMessage( 84 base::StringPrintf("Validation failed for %s [%s]", 85 context->description().data(), 86 ValidationErrorToString(error))); 87 } 88 } 89 } 90 91 ValidationErrorObserverForTesting::ValidationErrorObserverForTesting( 92 const base::Closure& callback) 93 : last_error_(VALIDATION_ERROR_NONE), callback_(callback) { 94 DCHECK(!g_validation_error_observer); 95 g_validation_error_observer = this; 96 } 97 98 ValidationErrorObserverForTesting::~ValidationErrorObserverForTesting() { 99 DCHECK(g_validation_error_observer == this); 100 g_validation_error_observer = nullptr; 101 } 102 103 bool ReportSerializationWarning(ValidationError error) { 104 if (g_serialization_warning_observer) { 105 g_serialization_warning_observer->set_last_warning(error); 106 return true; 107 } 108 109 return false; 110 } 111 112 SerializationWarningObserverForTesting::SerializationWarningObserverForTesting() 113 : last_warning_(VALIDATION_ERROR_NONE) { 114 DCHECK(!g_serialization_warning_observer); 115 g_serialization_warning_observer = this; 116 } 117 118 SerializationWarningObserverForTesting:: 119 ~SerializationWarningObserverForTesting() { 120 DCHECK(g_serialization_warning_observer == this); 121 g_serialization_warning_observer = nullptr; 122 } 123 124 } // namespace internal 125 } // namespace mojo 126