blob: 320bacad4850c337b19cf6c6fd682348602855e5 [file] [log] [blame]
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "mojo/public/cpp/bindings/lib/generated_code_util.h"
#include "mojo/public/cpp/bindings/lib/control_message_handler.h"
#include "mojo/public/cpp/bindings/lib/validation_context.h"
#include "mojo/public/cpp/bindings/lib/validation_util.h"
#include "mojo/public/cpp/bindings/message.h"
namespace mojo {
namespace internal {
namespace {
GenericValidationInfo FindGenericValidationInfo(
uint32_t name,
base::span<const std::pair<uint32_t, GenericValidationInfo>> info) {
for (const auto& pair : info) {
if (pair.first == name)
return pair.second;
}
return {nullptr, nullptr};
}
GenericValidationInfo FindGenericValidationInfo(
uint32_t name,
base::span<const GenericValidationInfo> info) {
if (name >= info.size())
return {nullptr, nullptr};
return info[name];
}
template <typename T>
bool ValidateRequestGenericT(Message* message,
const char* class_name,
base::span<const T> info) {
if (!message->is_serialized() ||
ControlMessageHandler::IsControlMessage(message)) {
return true;
}
ValidationContext validation_context(message, class_name,
ValidationContext::kRequestValidator);
auto entry = FindGenericValidationInfo(message->header()->name, info);
if (!entry.request_validator) {
ReportValidationError(&validation_context,
VALIDATION_ERROR_MESSAGE_HEADER_UNKNOWN_METHOD);
return false;
}
const bool message_is_request =
entry.response_validator ? ValidateMessageIsRequestExpectingResponse(
message, &validation_context)
: ValidateMessageIsRequestWithoutResponse(
message, &validation_context);
if (!message_is_request)
return false;
return entry.request_validator(message->payload(), &validation_context);
}
template <typename T>
bool ValidateResponseGenericT(Message* message,
const char* class_name,
base::span<const T> info) {
if (!message->is_serialized() ||
ControlMessageHandler::IsControlMessage(message)) {
return true;
}
ValidationContext validation_context(message, class_name,
ValidationContext::kResponseValidator);
if (!ValidateMessageIsResponse(message, &validation_context))
return false;
auto entry = FindGenericValidationInfo(message->header()->name, info);
if (!entry.response_validator) {
ReportValidationError(&validation_context,
VALIDATION_ERROR_MESSAGE_HEADER_UNKNOWN_METHOD);
return false;
}
return entry.response_validator(message->payload(), &validation_context);
}
} // namespace
bool ValidateRequestGeneric(
Message* message,
const char* class_name,
base::span<const std::pair<uint32_t, GenericValidationInfo>> info) {
return ValidateRequestGenericT(message, class_name, info);
}
bool ValidateRequestGenericPacked(
Message* message,
const char* class_name,
base::span<const GenericValidationInfo> info) {
return ValidateRequestGenericT(message, class_name, info);
}
bool ValidateResponseGeneric(
Message* message,
const char* class_name,
base::span<const std::pair<uint32_t, GenericValidationInfo>> info) {
return ValidateResponseGenericT(message, class_name, info);
}
bool ValidateResponseGenericPacked(
Message* message,
const char* class_name,
base::span<const GenericValidationInfo> info) {
return ValidateResponseGenericT(message, class_name, info);
}
} // namespace internal
} // namespace mojo