// 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 #include #include #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::Dict MakeDict(const JunkValue& junk) { base::Value::Dict result; 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.Set(field.name(), std::move(field_value)); } return result; } base::Value MakeValue(const JunkValue& junk) { return base::Value(MakeDict(junk)); } template std::vector MakeVector(const Field& field) { return std::vector(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 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(input.type()); if (IsMediaRequestMessageType(type)) { base::Value body = MakeValue(input.body()); body.GetDict().Set("type", *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.GetDict().Set( "type", EnumToString()); CreateSetVolumeRequest(body, input.request_id(), input.source_id()); break; } case CastMessageUtilInputs::kIntInput: { IsMediaRequestMessageType( static_cast(input_union.int_input())); ToString(static_cast(input_union.int_input())); ToString(static_cast(input_union.int_input())); ToString(static_cast(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(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::Dict payload = MakeDict(input.payload()); if (input.has_request_id()) payload.Set("requestId", input.request_id()); GetRequestIdFromResponse(payload); break; } case CastMessageUtilInputs::kGetLaunchSessionResponseInput: { const auto& input = input_union.get_launch_session_response_input(); base::Value::Dict payload = MakeDict(input.payload()); GetLaunchSessionResponse(payload); break; } case CastMessageUtilInputs::kParseMessageTypeFromPayloadInput: { const auto& input = input_union.parse_message_type_from_payload_input(); base::Value::Dict payload = MakeDict(input.payload()); if (input.has_type()) payload.Set("type", 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