blob: a004f6812dfba373805a3c64a4dfb56dc6acc3f9 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <string>
#include <utility>
#include <vector>
#include "base/values.h"
#include "components/cast_channel/cast_message_util.h"
#include "components/cast_channel/enum_table.h"
#include "components/cast_channel/fuzz_proto/fuzzer_inputs.pb.h"
#include "testing/libfuzzer/proto/lpm_interface.h"
using cast_util::EnumToString;
namespace cast_channel {
namespace fuzz {
namespace {
base::Value MakeValue(const JunkValue& junk) {
base::Value result(base::Value::Type::DICTIONARY);
for (int i = 0; i < junk.field_size(); i++) {
const auto& field = junk.field(i);
base::Value field_value = field.has_int_value()
? base::Value(field.int_value())
: field.has_string_value()
? base::Value(field.string_value())
: field.has_float_value()
? base::Value(field.float_value())
: base::Value(field.bool_value());
result.SetKey(field.name(), std::move(field_value));
}
return result;
}
template <typename Field, typename T = typename Field::value_type>
std::vector<T> MakeVector(const Field& field) {
return std::vector<T>(field.cbegin(), field.cend());
}
} // namespace
DEFINE_PROTO_FUZZER(const CastMessageUtilInputs& input_union) {
// TODO(crbug.com/796717): Add test for CreateAuthChallengeMessage()
switch (input_union.input_case()) {
case CastMessageUtilInputs::kCreateBroadcastRequestInput: {
const auto& input = input_union.create_broadcast_request_input();
CreateBroadcastRequest(input.source_id(), input.request_id(),
MakeVector(input.app_id()),
BroadcastRequest(input.broadcast_namespace(),
input.broadcast_message()));
break;
}
case CastMessageUtilInputs::kCreateLaunchRequestInput: {
const auto& input = input_union.create_launch_request_input();
absl::optional<base::Value> app_params;
if (input.has_app_params())
app_params = MakeValue(input.app_params());
CreateLaunchRequest(input.source_id(), input.request_id(), input.app_id(),
input.locale(),
MakeVector(input.supported_app_types()), app_params);
break;
}
case CastMessageUtilInputs::kCreateStopRequestInput: {
const auto& input = input_union.create_stop_request_input();
CreateStopRequest(input.source_id(), input.request_id(),
input.session_id());
break;
}
case CastMessageUtilInputs::kCreateCastMessageInput: {
const auto& input = input_union.create_cast_message_input();
base::Value body = MakeValue(input.body());
CreateCastMessage(input.message_namespace(), body, input.source_id(),
input.destination_id());
break;
}
case CastMessageUtilInputs::kCreateMediaRequestInput: {
const auto& input = input_union.create_media_request_input();
auto type = static_cast<V2MessageType>(input.type());
if (IsMediaRequestMessageType(type)) {
base::Value body = MakeValue(input.body());
body.SetKey("type", base::Value(*EnumToString(type)));
CreateMediaRequest(body, input.request_id(), input.source_id(),
input.destination_id());
}
break;
}
case CastMessageUtilInputs::kCreateSetVolumeRequestInput: {
const auto& input = input_union.create_set_volume_request_input();
base::Value body = MakeValue(input.body());
body.SetKey(
"type",
base::Value(
EnumToString<V2MessageType, V2MessageType::kSetVolume>()));
CreateSetVolumeRequest(body, input.request_id(), input.source_id());
break;
}
case CastMessageUtilInputs::kIntInput: {
IsMediaRequestMessageType(
static_cast<V2MessageType>(input_union.int_input()));
ToString(static_cast<GetAppAvailabilityResult>(input_union.int_input()));
ToString(static_cast<CastMessageType>(input_union.int_input()));
ToString(static_cast<V2MessageType>(input_union.int_input()));
break;
}
case CastMessageUtilInputs::kStringInput: {
IsCastReservedNamespace(input_union.string_input());
break;
}
case CastMessageUtilInputs::kCastMessage: {
const auto& message = input_union.cast_message();
IsCastMessageValid(message);
IsAuthMessage(message);
IsReceiverMessage(message);
IsPlatformSenderMessage(message);
break;
}
case CastMessageUtilInputs::kCreateVirtualConnectionRequestInput: {
const auto& input = input_union.create_virtual_connection_request_input();
CreateVirtualConnectionRequest(
input.source_id(), input.destination_id(),
static_cast<VirtualConnectionType>(input.connection_type()),
input.user_agent(), input.browser_version());
break;
}
case CastMessageUtilInputs::kCreateGetAppAvailabilityRequestInput: {
const auto& input =
input_union.create_get_app_availability_request_input();
CreateGetAppAvailabilityRequest(input.source_id(), input.request_id(),
input.app_id());
break;
}
case CastMessageUtilInputs::kGetRequestIdFromResponseInput: {
const auto& input = input_union.get_request_id_from_response_input();
base::Value payload = MakeValue(input.payload());
if (input.has_request_id())
payload.SetKey("requestId", base::Value(input.request_id()));
GetRequestIdFromResponse(payload);
break;
}
case CastMessageUtilInputs::kGetLaunchSessionResponseInput: {
const auto& input = input_union.get_launch_session_response_input();
base::Value payload = MakeValue(input.payload());
GetLaunchSessionResponse(payload);
break;
}
case CastMessageUtilInputs::kParseMessageTypeFromPayloadInput: {
const auto& input = input_union.parse_message_type_from_payload_input();
base::Value payload = MakeValue(input.payload());
if (input.has_type())
payload.SetKey("type", base::Value(input.type()));
ParseMessageTypeFromPayload(payload);
break;
}
case CastMessageUtilInputs::kCreateReceiverStatusRequestInput: {
const auto& input = input_union.create_receiver_status_request_input();
CreateReceiverStatusRequest(input.source_id(), input.request_id());
break;
}
case CastMessageUtilInputs::INPUT_NOT_SET:
break;
}
}
} // namespace fuzz
} // namespace cast_channel