Home | History | Annotate | Download | only in lib
      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 
     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 
     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 
     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
    106     ::ScopedSuppressValidationErrorLoggingForTests()
    107     : was_suppressed_(g_suppress_logging) {
    108   g_suppress_logging = true;
    109 }
    110 
    111 ScopedSuppressValidationErrorLoggingForTests
    112     ::~ScopedSuppressValidationErrorLoggingForTests() {
    113   g_suppress_logging = was_suppressed_;
    114 }
    115 
    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 
    123 ValidationErrorObserverForTesting::~ValidationErrorObserverForTesting() {
    124   DCHECK(g_validation_error_observer == this);
    125   g_validation_error_observer = nullptr;
    126 }
    127 
    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 
    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::
    144     ~SerializationWarningObserverForTesting() {
    145   DCHECK(g_serialization_warning_observer == this);
    146   g_serialization_warning_observer = nullptr;
    147 }
    148 
    149 }  // namespace internal
    150 }  // namespace mojo
    151