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 #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 
     61   ValidationError last_error() const { return last_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 
     83   ValidationError last_warning() const { return last_warning_; }
     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