• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 bool g_suppress_logging = false;
18 
19 }  // namespace
20 
ValidationErrorToString(ValidationError error)21 const char* ValidationErrorToString(ValidationError error) {
22   switch (error) {
23     case VALIDATION_ERROR_NONE:
24       return "VALIDATION_ERROR_NONE";
25     case VALIDATION_ERROR_MISALIGNED_OBJECT:
26       return "VALIDATION_ERROR_MISALIGNED_OBJECT";
27     case VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE:
28       return "VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE";
29     case VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER:
30       return "VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER";
31     case VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER:
32       return "VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER";
33     case VALIDATION_ERROR_ILLEGAL_HANDLE:
34       return "VALIDATION_ERROR_ILLEGAL_HANDLE";
35     case VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE:
36       return "VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE";
37     case VALIDATION_ERROR_ILLEGAL_POINTER:
38       return "VALIDATION_ERROR_ILLEGAL_POINTER";
39     case VALIDATION_ERROR_UNEXPECTED_NULL_POINTER:
40       return "VALIDATION_ERROR_UNEXPECTED_NULL_POINTER";
41     case VALIDATION_ERROR_ILLEGAL_INTERFACE_ID:
42       return "VALIDATION_ERROR_ILLEGAL_INTERFACE_ID";
43     case VALIDATION_ERROR_UNEXPECTED_INVALID_INTERFACE_ID:
44       return "VALIDATION_ERROR_UNEXPECTED_INVALID_INTERFACE_ID";
45     case VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS:
46       return "VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS";
47     case VALIDATION_ERROR_MESSAGE_HEADER_MISSING_REQUEST_ID:
48       return "VALIDATION_ERROR_MESSAGE_HEADER_MISSING_REQUEST_ID";
49     case VALIDATION_ERROR_MESSAGE_HEADER_UNKNOWN_METHOD:
50       return "VALIDATION_ERROR_MESSAGE_HEADER_UNKNOWN_METHOD";
51     case VALIDATION_ERROR_DIFFERENT_SIZED_ARRAYS_IN_MAP:
52       return "VALIDATION_ERROR_DIFFERENT_SIZED_ARRAYS_IN_MAP";
53     case VALIDATION_ERROR_UNKNOWN_UNION_TAG:
54       return "VALIDATION_ERROR_UNKNOWN_UNION_TAG";
55     case VALIDATION_ERROR_UNKNOWN_ENUM_VALUE:
56       return "VALIDATION_ERROR_UNKNOWN_ENUM_VALUE";
57     case VALIDATION_ERROR_DESERIALIZATION_FAILED:
58       return "VALIDATION_ERROR_DESERIALIZATION_FAILED";
59     case VALIDATION_ERROR_MAX_RECURSION_DEPTH:
60       return "VALIDATION_ERROR_MAX_RECURSION_DEPTH";
61   }
62 
63   return "Unknown error";
64 }
65 
ReportValidationError(ValidationContext * context,ValidationError error,const char * description)66 void ReportValidationError(ValidationContext* context,
67                            ValidationError error,
68                            const char* description) {
69   if (g_validation_error_observer) {
70     g_validation_error_observer->set_last_error(error);
71     return;
72   }
73 
74   if (description) {
75     if (!g_suppress_logging) {
76       LOG(ERROR) << "Invalid message: " << ValidationErrorToString(error)
77                  << " (" << description << ")";
78     }
79     if (context->message()) {
80       context->message()->NotifyBadMessage(
81           base::StringPrintf("Validation failed for %s [%s (%s)]",
82                              context->description().data(),
83                              ValidationErrorToString(error), description));
84     }
85   } else {
86     if (!g_suppress_logging)
87       LOG(ERROR) << "Invalid message: " << ValidationErrorToString(error);
88     if (context->message()) {
89       context->message()->NotifyBadMessage(
90           base::StringPrintf("Validation failed for %s [%s]",
91                              context->description().data(),
92                              ValidationErrorToString(error)));
93     }
94   }
95 }
96 
ReportValidationErrorForMessage(mojo::Message * message,ValidationError error,const char * description)97 void ReportValidationErrorForMessage(
98     mojo::Message* message,
99     ValidationError error,
100     const char* description) {
101   ValidationContext validation_context(nullptr, 0, 0, 0, message, description);
102   ReportValidationError(&validation_context, error);
103 }
104 
105 ScopedSuppressValidationErrorLoggingForTests
ScopedSuppressValidationErrorLoggingForTests()106     ::ScopedSuppressValidationErrorLoggingForTests()
107     : was_suppressed_(g_suppress_logging) {
108   g_suppress_logging = true;
109 }
110 
111 ScopedSuppressValidationErrorLoggingForTests
~ScopedSuppressValidationErrorLoggingForTests()112     ::~ScopedSuppressValidationErrorLoggingForTests() {
113   g_suppress_logging = was_suppressed_;
114 }
115 
ValidationErrorObserverForTesting(const base::Closure & callback)116 ValidationErrorObserverForTesting::ValidationErrorObserverForTesting(
117     const base::Closure& callback)
118     : last_error_(VALIDATION_ERROR_NONE), callback_(callback) {
119   DCHECK(!g_validation_error_observer);
120   g_validation_error_observer = this;
121 }
122 
~ValidationErrorObserverForTesting()123 ValidationErrorObserverForTesting::~ValidationErrorObserverForTesting() {
124   DCHECK(g_validation_error_observer == this);
125   g_validation_error_observer = nullptr;
126 }
127 
ReportSerializationWarning(ValidationError error)128 bool ReportSerializationWarning(ValidationError error) {
129   if (g_serialization_warning_observer) {
130     g_serialization_warning_observer->set_last_warning(error);
131     return true;
132   }
133 
134   return false;
135 }
136 
SerializationWarningObserverForTesting()137 SerializationWarningObserverForTesting::SerializationWarningObserverForTesting()
138     : last_warning_(VALIDATION_ERROR_NONE) {
139   DCHECK(!g_serialization_warning_observer);
140   g_serialization_warning_observer = this;
141 }
142 
143 SerializationWarningObserverForTesting::
~SerializationWarningObserverForTesting()144     ~SerializationWarningObserverForTesting() {
145   DCHECK(g_serialization_warning_observer == this);
146   g_serialization_warning_observer = nullptr;
147 }
148 
149 }  // namespace internal
150 }  // namespace mojo
151