cast_message_util_fuzzer.cc 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // Copyright 2019 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. #include <string>
  5. #include <utility>
  6. #include <vector>
  7. #include "base/values.h"
  8. #include "components/cast_channel/cast_message_util.h"
  9. #include "components/cast_channel/enum_table.h"
  10. #include "components/cast_channel/fuzz_proto/fuzzer_inputs.pb.h"
  11. #include "testing/libfuzzer/proto/lpm_interface.h"
  12. using cast_util::EnumToString;
  13. namespace cast_channel {
  14. namespace fuzz {
  15. namespace {
  16. base::Value::Dict MakeDict(const JunkValue& junk) {
  17. base::Value::Dict result;
  18. for (int i = 0; i < junk.field_size(); i++) {
  19. const auto& field = junk.field(i);
  20. base::Value field_value = field.has_int_value()
  21. ? base::Value(field.int_value())
  22. : field.has_string_value()
  23. ? base::Value(field.string_value())
  24. : field.has_float_value()
  25. ? base::Value(field.float_value())
  26. : base::Value(field.bool_value());
  27. result.Set(field.name(), std::move(field_value));
  28. }
  29. return result;
  30. }
  31. base::Value MakeValue(const JunkValue& junk) {
  32. return base::Value(MakeDict(junk));
  33. }
  34. template <typename Field, typename T = typename Field::value_type>
  35. std::vector<T> MakeVector(const Field& field) {
  36. return std::vector<T>(field.cbegin(), field.cend());
  37. }
  38. } // namespace
  39. DEFINE_PROTO_FUZZER(const CastMessageUtilInputs& input_union) {
  40. // TODO(crbug.com/796717): Add test for CreateAuthChallengeMessage()
  41. switch (input_union.input_case()) {
  42. case CastMessageUtilInputs::kCreateBroadcastRequestInput: {
  43. const auto& input = input_union.create_broadcast_request_input();
  44. CreateBroadcastRequest(input.source_id(), input.request_id(),
  45. MakeVector(input.app_id()),
  46. BroadcastRequest(input.broadcast_namespace(),
  47. input.broadcast_message()));
  48. break;
  49. }
  50. case CastMessageUtilInputs::kCreateLaunchRequestInput: {
  51. const auto& input = input_union.create_launch_request_input();
  52. absl::optional<base::Value> app_params;
  53. if (input.has_app_params())
  54. app_params = MakeValue(input.app_params());
  55. CreateLaunchRequest(input.source_id(), input.request_id(), input.app_id(),
  56. input.locale(),
  57. MakeVector(input.supported_app_types()), app_params);
  58. break;
  59. }
  60. case CastMessageUtilInputs::kCreateStopRequestInput: {
  61. const auto& input = input_union.create_stop_request_input();
  62. CreateStopRequest(input.source_id(), input.request_id(),
  63. input.session_id());
  64. break;
  65. }
  66. case CastMessageUtilInputs::kCreateCastMessageInput: {
  67. const auto& input = input_union.create_cast_message_input();
  68. base::Value body = MakeValue(input.body());
  69. CreateCastMessage(input.message_namespace(), body, input.source_id(),
  70. input.destination_id());
  71. break;
  72. }
  73. case CastMessageUtilInputs::kCreateMediaRequestInput: {
  74. const auto& input = input_union.create_media_request_input();
  75. auto type = static_cast<V2MessageType>(input.type());
  76. if (IsMediaRequestMessageType(type)) {
  77. base::Value body = MakeValue(input.body());
  78. body.GetDict().Set("type", *EnumToString(type));
  79. CreateMediaRequest(body, input.request_id(), input.source_id(),
  80. input.destination_id());
  81. }
  82. break;
  83. }
  84. case CastMessageUtilInputs::kCreateSetVolumeRequestInput: {
  85. const auto& input = input_union.create_set_volume_request_input();
  86. base::Value body = MakeValue(input.body());
  87. body.GetDict().Set(
  88. "type", EnumToString<V2MessageType, V2MessageType::kSetVolume>());
  89. CreateSetVolumeRequest(body, input.request_id(), input.source_id());
  90. break;
  91. }
  92. case CastMessageUtilInputs::kIntInput: {
  93. IsMediaRequestMessageType(
  94. static_cast<V2MessageType>(input_union.int_input()));
  95. ToString(static_cast<GetAppAvailabilityResult>(input_union.int_input()));
  96. ToString(static_cast<CastMessageType>(input_union.int_input()));
  97. ToString(static_cast<V2MessageType>(input_union.int_input()));
  98. break;
  99. }
  100. case CastMessageUtilInputs::kStringInput: {
  101. IsCastReservedNamespace(input_union.string_input());
  102. break;
  103. }
  104. case CastMessageUtilInputs::kCastMessage: {
  105. const auto& message = input_union.cast_message();
  106. IsCastMessageValid(message);
  107. IsAuthMessage(message);
  108. IsReceiverMessage(message);
  109. IsPlatformSenderMessage(message);
  110. break;
  111. }
  112. case CastMessageUtilInputs::kCreateVirtualConnectionRequestInput: {
  113. const auto& input = input_union.create_virtual_connection_request_input();
  114. CreateVirtualConnectionRequest(
  115. input.source_id(), input.destination_id(),
  116. static_cast<VirtualConnectionType>(input.connection_type()),
  117. input.user_agent(), input.browser_version());
  118. break;
  119. }
  120. case CastMessageUtilInputs::kCreateGetAppAvailabilityRequestInput: {
  121. const auto& input =
  122. input_union.create_get_app_availability_request_input();
  123. CreateGetAppAvailabilityRequest(input.source_id(), input.request_id(),
  124. input.app_id());
  125. break;
  126. }
  127. case CastMessageUtilInputs::kGetRequestIdFromResponseInput: {
  128. const auto& input = input_union.get_request_id_from_response_input();
  129. base::Value::Dict payload = MakeDict(input.payload());
  130. if (input.has_request_id())
  131. payload.Set("requestId", input.request_id());
  132. GetRequestIdFromResponse(payload);
  133. break;
  134. }
  135. case CastMessageUtilInputs::kGetLaunchSessionResponseInput: {
  136. const auto& input = input_union.get_launch_session_response_input();
  137. base::Value::Dict payload = MakeDict(input.payload());
  138. GetLaunchSessionResponse(payload);
  139. break;
  140. }
  141. case CastMessageUtilInputs::kParseMessageTypeFromPayloadInput: {
  142. const auto& input = input_union.parse_message_type_from_payload_input();
  143. base::Value::Dict payload = MakeDict(input.payload());
  144. if (input.has_type())
  145. payload.Set("type", input.type());
  146. ParseMessageTypeFromPayload(payload);
  147. break;
  148. }
  149. case CastMessageUtilInputs::kCreateReceiverStatusRequestInput: {
  150. const auto& input = input_union.create_receiver_status_request_input();
  151. CreateReceiverStatusRequest(input.source_id(), input.request_id());
  152. break;
  153. }
  154. case CastMessageUtilInputs::INPUT_NOT_SET:
  155. break;
  156. }
  157. }
  158. } // namespace fuzz
  159. } // namespace cast_channel