#include <cstddef>
#include <cstdint>
#include <cstring>
#include <memory>
#include <vector>

#include <gtest/gtest.h>
#include "testing/fuzzing/fuzztest.h"
#include "absl/log/absl_log.h"
#include "upb/mem/arena.h"
#include "upb/message/compare.h"
#include "upb/message/convert.h"
#include "upb/message/message.h"
#include "upb/mini_table/extension_registry.h"
#include "upb/mini_table/field.h"
#include "upb/mini_table/internal/field.h"
#include "upb/mini_table/internal/message.h"
#include "upb/mini_table/internal/sub.h"
#include "upb/mini_table/message.h"
#include "upb/test/fuzz_util.h"
#include "upb/wire/decode.h"
#include "upb/wire/encode.h"

// Must be last.
#include "upb/port/def.inc"

namespace upb {
namespace {

const upb_MiniTable* SubsetMiniTable(const upb_MiniTable* src, uint64_t mask,
                                     upb_Arena* arena);

const upb_MiniTable* SubsetMiniTable(const upb_MiniTable* src, uint64_t mask,
                                     upb_Arena* arena) {
  std::vector<upb_MiniTableField> new_fields;
  std::vector<upb_MiniTableSub> new_subs;

  int field_count = upb_MiniTable_FieldCount(src);
  for (int i = 0; i < field_count; ++i) {
    const upb_MiniTableField* f = upb_MiniTable_GetFieldByIndex(src, i);
    if (mask & (1ULL << (i % 64))) {
      upb_MiniTableField new_f = *f;
      if (f->UPB_PRIVATE(submsg_ofs) != kUpb_NoSub) {
        new_subs.push_back(
            *UPB_PTR_AT(f, f->UPB_PRIVATE(submsg_ofs) * kUpb_SubmsgOffsetBytes,
                        const upb_MiniTableSub));
      }
      new_fields.push_back(new_f);
    }
  }

  size_t mt_size = sizeof(upb_MiniTable);
  size_t fields_bytes = new_fields.size() * sizeof(upb_MiniTableField);
  size_t subs_bytes = new_subs.size() * sizeof(upb_MiniTableSub);

  size_t mt_padded_size = UPB_ALIGN_UP(mt_size, 8);
  size_t fields_padded_size = UPB_ALIGN_UP(fields_bytes, 8);
  size_t total_size = mt_padded_size + fields_padded_size + subs_bytes;

  upb_MiniTable* new_mt = (upb_MiniTable*)upb_Arena_Malloc(arena, total_size);
  upb_MiniTableField* fields_ptr =
      UPB_PTR_AT(new_mt, mt_padded_size, upb_MiniTableField);
  upb_MiniTableSub* subs_ptr =
      UPB_PTR_AT(fields_ptr, fields_padded_size, upb_MiniTableSub);

  std::memcpy(new_mt, src, mt_size);
  if (!new_fields.empty()) {
    std::memcpy(fields_ptr, new_fields.data(), fields_bytes);
  }
  if (!new_subs.empty()) {
    std::memcpy(subs_ptr, new_subs.data(), subs_bytes);
  }

  int sub_idx = 0;
  for (size_t i = 0; i < new_fields.size(); ++i) {
    upb_MiniTableField* f = &fields_ptr[i];
    if (f->UPB_PRIVATE(submsg_ofs) != kUpb_NoSub) {
      uintptr_t f_addr = (uintptr_t)f;
      uintptr_t subs_addr = (uintptr_t)&subs_ptr[sub_idx++];

      size_t diff = subs_addr - f_addr;
      f->UPB_PRIVATE(submsg_ofs) = (uint16_t)(diff / kUpb_SubmsgOffsetBytes);
    }
  }

  new_mt->UPB_ONLYBITS(fields) = fields_ptr;
  new_mt->UPB_ONLYBITS(field_count) = (uint16_t)new_fields.size();
  new_mt->UPB_PRIVATE(dense_below) = 0;
  new_mt->UPB_PRIVATE(table_mask) = -1;

  return new_mt;
}

void ConvertFuzz(const upb::fuzz::MiniTableFuzzInput& input, uint64_t mask1,
                 uint64_t mask2, std::string proto_payload,
                 uint32_t decode_options, uint32_t encode_options) {
  std::unique_ptr<upb_Arena, decltype(&upb_Arena_Free)> upb_arena(
      upb_Arena_New(), &upb_Arena_Free);
  upb_Arena* arena = upb_arena.get();

  upb_ExtensionRegistry* exts;
  const upb_MiniTable* original_mt =
      upb::fuzz::BuildMiniTable(input, &exts, arena);
  if (!original_mt) {
    return;
  }

  const upb_MiniTable* src_mt = SubsetMiniTable(original_mt, mask1, arena);
  const upb_MiniTable* dst_mt = SubsetMiniTable(original_mt, mask2, arena);

  decode_options = upb_Decode_LimitDepth(decode_options, 80);
  encode_options = upb_Encode_LimitDepth(encode_options, 80);

  // We don't want to skip unknown fields or check required fields, as these
  // will cause the fuzz test to fail or exit early in ways that aren't
  // interesting.
  decode_options &= ~kUpb_DecodeOption_CheckRequired;
  encode_options &=
      ~(kUpb_EncodeOption_SkipUnknown | kUpb_EncodeOption_CheckRequired);

  upb_Message* msg_orig = upb_Message_New(original_mt, arena);
  upb_DecodeStatus status =
      upb_Decode(proto_payload.data(), proto_payload.size(), msg_orig,
                 original_mt, exts, decode_options, arena);

  if (status != kUpb_DecodeStatus_Ok) {
    return;
  }

  upb_Message* msg_src = upb_Message_New(src_mt, arena);
  status = upb_Decode(proto_payload.data(), proto_payload.size(), msg_src,
                      src_mt, exts, decode_options, arena);

  if (status != kUpb_DecodeStatus_Ok) {
    return;
  }

  const upb_Message* msg_dst = upb_Message_Convert(
      msg_src, src_mt, dst_mt, exts, decode_options, encode_options, arena);
  if (!msg_dst) {
    return;
  }

  size_t size;
  char* bytes;
  upb_EncodeStatus enc_status =
      upb_Encode(msg_dst, dst_mt, encode_options, arena, &bytes, &size);

  if (enc_status != kUpb_EncodeStatus_Ok) {
    return;
  }

  upb_Message* msg_final = upb_Message_New(original_mt, arena);
  status = upb_Decode(bytes, size, msg_final, original_mt, exts, decode_options,
                      arena);

  if (status != kUpb_DecodeStatus_Ok) {
    return;
  }

  bool equal = upb_Message_IsEqual(msg_final, msg_orig, original_mt,
                                   kUpb_CompareOption_IncludeUnknownFields);
  if (!equal) {
    ABSL_LOG(FATAL) << "The conversion produced a message that is not equal "
                       "to the original message.";
  }
}

FUZZ_TEST(ConvertFuzz, ConvertFuzz);

TEST(ConvertFuzz, Convert_IdenticalMinitables_ShallowCopy) {
  ConvertFuzz(
      upb::fuzz::MiniTableFuzzInput{
          {"\331", ""}, {"\257"}, "\351\210", {2147483645}},
      4867317803475403639ULL, 4867317803475403639ULL, "@B", 3220282077ULL,
      4189253947ULL);
}

TEST(ConvertFuzz, Convert_DifferentSubsets_DroppedFields_Complex) {
  ConvertFuzz(
      upb::fuzz::MiniTableFuzzInput{
          {"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
           "", ""},
          {"\306", "", "\331", ""},
          "\314Q\345\322\024\321\017\021\016\016\016",
          {1,          1,          0,          4294967295, 4294967295,
           1,          4294967295, 4294967295, 4294967295, 4294967295,
           4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
           1,          3135226496, 3135226496, 3135226496, 0,
           3708883408}},
      14162464183153632842ULL, 2939036597827910531ULL,
      "=\032\253\342K\221MQ\nj\n\304\361\364\304", 1620786928, 2077918455);
}

TEST(ConvertFuzz, Convert_DifferentSubsets_DroppedFields_Simple) {
  ConvertFuzz(upb::fuzz::MiniTableFuzzInput{{"", "", "", "", "", "", "", "", "",
                                             "", "", "", "", "", ""},
                                            {""},
                                            "",
                                            {4294967295, 4294967295, 0}},
              4453300303650383170ULL, 13549612121351043620ULL, "]]k\031\320",
              1804506072, 3299701550);
}

TEST(ConvertFuzz,
     Convert_DifferentSubsets_DroppedFields_Regression_89982ef4cfe52331) {
  ConvertFuzz(
      upb::fuzz::MiniTableFuzzInput{
          {"", "DD", "z", "", "", "\200"}, {"\031", "\031", "\031"}, "]]", {}},
      7595264386850118164ULL, 1703605996941841092ULL, "\300D\315\316\372D",
      3067512230, 2237854510);
}

TEST(ConvertFuzz, ManualUnknownFieldRepro) {
  ConvertFuzz(upb::fuzz::MiniTableFuzzInput{{"I", "a"}}, ~0ULL, 0ULL,
              "\010\000", 0, 0);
}

TEST(ConvertFuzz, Regression_FuzzerFinding_UnknownFields) {
  ConvertFuzz(
      upb::fuzz::MiniTableFuzzInput{
          {"", "", ""}, {"", "\211", "", "{", "\232", "2"}, "", {4294967295}},
      5205171011975038739ULL, 18014293590545137538ULL, "E\261k\333\334",
      590856108, 53173774);
}

TEST(ConvertFuzz, RepeatedFieldConfusion) {
  ConvertFuzz(upb::fuzz::MiniTableFuzzInput{{"\t", "\352", "R", "$\214\214\214",
                                             "\004", "$F", "\244", "$\374P"},
                                            {""},
                                            "{GGG",
                                            {4294967295}},
              3117542645911838959, 9223372036854775807, "", 2147221503, 16);
}

TEST(ConvertFuzz, ConvertFuzzRegression) {
  ConvertFuzz(
      upb::fuzz::MiniTableFuzzInput{{""}, {"\325\242"}, "", {2147483647}},
      18446744073709551615u, 10490713252739160816u, " u", 2, 4294967231);
}

TEST(ConvertFuzz, ConvertFuzzRegression_InvalidSkipValueInMiniTable) {
  ConvertFuzz(
      upb::fuzz::MiniTableFuzzInput{
          {"$V&H_B4"},
          {std::string("\x21\x21\x03\x03\x03\x03\x03\x03\x03\x03\x34\x00\x00"
                       "\x00\x00\x00\x6F\x6F\x6F\x00\x00\x36\x01",
                       23)},
          "\xE2",
          {0}},
      12581279990508548653ULL, 17241158217056387914ULL,
      std::string("\x12\x0A\x00\xF0\xC8\xCC\xED\xD1\x2C\x1B\x2C\x42", 12),
      993807397, 3961496750);
}

TEST(ConvertFuzz, ConvertFuzzRegression_Crash_ConvertInternal_2026_04_07) {
  ConvertFuzz(
      upb::fuzz::MiniTableFuzzInput{
          {""},
          {"", ">>", "", ""},
          "\357\357\357\357\357*"
          "\357\357\357\357\357\357\357\357\357\357\357\357\357\357\357\357\357"
          "\357\225\225\225\357\357\357\357\357\357\357\357\357\357\357\357\357"
          "\357\357\357\357\357\357\357\357\357",
          {4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
           4294967295, 4294967295, 4294967295, 1}},
      12411566311597166710ULL, 8799022017001952335ULL, "%%%%%%%%%%%%%%%%%ZZ%",
      2815879784ULL, 3243839465ULL);
}

TEST(ConvertFuzz, Convert_Fuzz_Crash_Regression) {
  ConvertFuzz(
      upb::fuzz::MiniTableFuzzInput{
          {"", "", ""}, {"", ""}, "\207\254", {4033684729, 4294967294}},
      7437277671727957814ULL, 9800553862402446025ULL,
      "\220Y\203\225\225\366\337\337\004", 3062476814ULL, 4041248646ULL);
}

TEST(ConvertFuzz, ConvertFuzzRegression2) {
  ConvertFuzz(upb::fuzz::MiniTableFuzzInput{{"", ""}, {""}, "", {1903095162}},
              8810965477460052779, 18446744073709551615u, "\030\030", 114210880,
              8190);
}

TEST(ConvertFuzz, ConvertFuzzRegression3) {
  ConvertFuzz(upb::fuzz::MiniTableFuzzInput{{""}, {}, "\373", {}}, 1,
              9223372036854775807, "uz\010\006\006", 4294967290, 2147483647);
}

TEST(ConvertFuzz, ConvertFuzzRegression4) {
  ConvertFuzz(
      upb::fuzz::MiniTableFuzzInput{
          {"$", "C", ""},
          {"r"},
          "\270N\270[",
          {3621539714, 3621539714, 3621539714, 3621539714, 3621539714,
           3621539714, 3621539714, 3621539714, 3621539714, 3621539714,
           3621539714, 3621539714, 3621539714, 3621539714, 3621539714,
           3621539714, 3621539714, 3621539714, 3621539714, 3621539714,
           3621539714, 3621539714, 3621539714, 3621539714, 3621539714,
           3621539714, 3621539714, 3621539714, 3621539714, 3621539714,
           3621539714, 3621539714, 3621539714, 3621539714, 3621539714,
           3621539714, 3621539714, 3621539714, 3621539714, 3621539714,
           3621539714, 3621539714, 3621539714, 3621539714}},
      13429813313754688149ULL, 6819704094736752274ULL, "\255\032\262\337))",
      1611082566, 466142871);
}

TEST(ConvertFuzz, ConvertFuzzRegression5) {
  ConvertFuzz(upb::fuzz::MiniTableFuzzInput{{""}, {"\362", "y"}, "\252", {}},
              8728619288361297649ULL, 13997967148621545864ULL,
              "%\311\311\311\303", 3383556142, 3604956055);
}

TEST(ConvertFuzz, ConvertFuzzRegression6) {
  ConvertFuzz(
      upb::fuzz::MiniTableFuzzInput{
          {"", "", "\341", "\341", "\341", "$", "", "", "\022", "\022", "", "",
           ""},
          {"\374", "\204"},
          "n\251PXq",
          {1,          1,          1,          1,          1,
           1,          1,          1413050348, 1,          1,
           1,          1,          1,          0,          0,
           1,          1,          1,          1,          1,
           1,          1,          1,          1,          1,
           1,          1,          1,          1,          4,
           4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
           4294967295, 4294967295, 4294967295, 1,          1,
           1,          1,          1,          1,          1,
           1,          1,          1,          3028396088, 1,
           1,          1,          1,          1,          4294967295,
           1,          1,          1,          1,          1,
           1,          1,          1,          1,          1,
           1,          1,          1,          1,          0,
           1,          1,          1,          1,          1,
           1,          1,          1,          1,          1}},
      304186569338573724ULL, 6555165345294515829ULL, "8W", 3970284081,
      1611359599);
}

TEST(ConvertFuzz, ConvertFuzzRegression7) {
  ConvertFuzz(
      upb::fuzz::MiniTableFuzzInput{
          {"$Rh&G"},
          {"I", "",  "I", "",  "I", "",  "I", "", "",  "",
           "",  "I", "",  "E", "",  "I", "I", "", "I", ""},
          "#====6",
          {2816219145}},
      436008099437115707ULL, 13573652747906983007ULL,
      std::string("\251\021\000\003\005X\315\002:\000\022\244\000\247("
                  "\245\255PPPPPPPPS\340\340\340\340PPPPPPP\"PPPPPPPPPPPPPP\nPP"
                  "PPPPPPPPPPPPPPPPPPPPPPP\310PPPPPPPPP\245\245PPPPPPPPPP{"
                  "PPPPP\235PRvPPPPPPPPPPPPPPPPPPPPPPPP\nPPRR\000\000\000\000"
                  "\000\000\000\000RRPPPTPPPPPPPPPPPPPPPPPPPPP\250PPPPPPPPPPPPP"
                  "PPPPPPP\320PPPP\000TbPPPPPPH(\000\000PPPPP\221\023P>"
                  "PPPUPPPPPPPPPPPPPPPPPPPPPpP\354\251;",
                  252),
      4098521408, 80);
}

TEST(ConvertFuzz, ConvertFuzzRegression8) {
  ConvertFuzz(
      upb::fuzz::MiniTableFuzzInput{{"$Rh&G"}, {"", ""}, "#j%### &", {}},
      11766057900109844910u, 3051086136682536822,
      std::string(
          "\251\005PPP\310\305QPPPPRrPPPPPPPDPPPPPPPMPRR\000R\r\rPPPPPPPPPPPP]]"
          "PPb\320T\266\225\r\r\253PPPPPPPPPPPPPPPPPPPPPiiPP}\276\177=\010\010|"
          "}N\320PPPPPPPP\rP\341PPP\221\023P>PUPPPPPPPPPPP;",
          128),
      3342580205, 67649);
}

TEST(ConvertFuzz, ConvertFuzzRegression_ConvertClosedEnumWithUnknown) {
  std::vector<std::string> enum_mds = {
      "!!\003\003\003\003\003\003\003\003@\000\000\000\000ooo\000\0006\001"};
  for (int i = 0; i < 1870; ++i) {
    enum_mds.push_back("/");
  }
  ConvertFuzz(upb::fuzz::MiniTableFuzzInput{{"$$H_B4"}, enum_mds, "", {0}},
              8159560341278556898ULL, 12315457061443390189ULL,
              std::string("\022\nCd_\213\356\000\001\020\234\013", 12),
              3740129997ULL, 2289667495ULL);
}

TEST(ConvertFuzz, ConvertFuzzEncodeRegression) {
  ConvertFuzz(
      upb::fuzz::MiniTableFuzzInput{{"$$$$$$$$$$$$$$$$$$", "", "", "", "", ""},
                                    {"", ""},
                                    "D",
                                    {2462394141, 2462394141, 2462394145}},
      555217012043469213, 13507447059222749214u,
      "pm\t\t\t\t\t\t\t\t\t\t\t\005o\t\t\t\t\t\trr\375\375\375r\251r", 32766,
      16);
}

void ArbitraryMiniTableConvertFuzz(const upb::fuzz::MiniTableFuzzInput& input1,
                                   const upb::fuzz::MiniTableFuzzInput& input2,
                                   std::string proto_payload,
                                   uint32_t decode_options,
                                   uint32_t encode_options) {
  std::unique_ptr<upb_Arena, decltype(&upb_Arena_Free)> upb_arena(
      upb_Arena_New(), &upb_Arena_Free);
  upb_Arena* arena = upb_arena.get();

  upb_ExtensionRegistry* exts1;
  const upb_MiniTable* mt1 = upb::fuzz::BuildMiniTable(input1, &exts1, arena);
  if (!mt1) {
    return;
  }

  upb_ExtensionRegistry* exts2;
  const upb_MiniTable* mt2 = upb::fuzz::BuildMiniTable(input2, &exts2, arena);
  if (!mt2) {
    return;
  }

  decode_options = upb_Decode_LimitDepth(decode_options, 80);
  encode_options = upb_Encode_LimitDepth(encode_options, 80);

  // We don't want to skip unknown fields or check required fields, as these
  // will cause the fuzz test to fail or exit early in ways that aren't
  // interesting.
  encode_options &=
      ~(kUpb_EncodeOption_SkipUnknown | kUpb_EncodeOption_CheckRequired);
  decode_options &= ~kUpb_DecodeOption_CheckRequired;

  upb_Message* msg_src = upb_Message_New(mt1, arena);
  upb_DecodeStatus status =
      upb_Decode(proto_payload.data(), proto_payload.size(), msg_src, mt1,
                 exts1, decode_options, arena);

  if (status != kUpb_DecodeStatus_Ok) {
    return;
  }

  // Path A: Direct conversion
  const upb_Message* msg_dst = upb_Message_Convert(
      msg_src, mt1, mt2, exts2, decode_options, encode_options, arena);
  if (!msg_dst) {
    return;
  }

  // Path B: Encoding-then-decoding path
  size_t wire_size;
  char* wire_bytes;
  upb_EncodeStatus enc_status =
      upb_Encode(msg_src, mt1, encode_options, arena, &wire_bytes, &wire_size);

  if (enc_status != kUpb_EncodeStatus_Ok) {
    if (enc_status == kUpb_EncodeStatus_MaxDepthExceeded) {
      return;
    }
    // Conversion succeeded, but encoding failed. This shouldn't happen.
    ABSL_LOG(FATAL) << "Conversion succeeded, but encoding failed: "
                    << enc_status;
  }

  upb_Message* msg_dst_roundtrip = upb_Message_New(mt2, arena);
  status = upb_Decode(wire_bytes, wire_size, msg_dst_roundtrip, mt2, exts2,
                      decode_options, arena);

  if (status != kUpb_DecodeStatus_Ok) {
    if (status == kUpb_DecodeStatus_MaxDepthExceeded) {
      return;
    }
    // Conversion succeeded, but decoding failed. This shouldn't happen.
    ABSL_LOG(FATAL) << "Conversion succeeded, but decoding failed: " << status;
  }

  // Check that both paths produce equivalent messages
  bool equal = upb_Message_IsEqual(msg_dst, msg_dst_roundtrip, mt2,
                                   kUpb_CompareOption_IncludeUnknownFields);
  if (!equal) {
    ABSL_LOG(FATAL) << "Direct conversion does not match the "
                       "encoding-then-decoding roundtrip result.";
  }
}

FUZZ_TEST(ConvertFuzz, ArbitraryMiniTableConvertFuzz);

TEST(ConvertFuzz, ArbitraryMiniTableConvertFuzzRegression) {
  ArbitraryMiniTableConvertFuzz(
      upb::fuzz::MiniTableFuzzInput{
          {"$$$$$)B&$$$$$$$$$$$$$$$$$$$$$"}, {"!!"}, "", {0}},
      upb::fuzz::MiniTableFuzzInput{
          {""},
          {"", "", "", "\205"},
          std::string("(\000%%", 4),
          {583690751, 583690751, 583690751, 583690751, 583690751, 583690751,
           583690751, 583690751, 583690751, 583690751, 583690751, 583690751,
           583690751, 583690751, 583690751, 583690751, 583690751, 583690751}},
      "M++8 0y((", 1075739120, 3567776688);
}

TEST(ConvertFuzz, ArbitraryMiniTableConvertFuzzRegression2) {
  ArbitraryMiniTableConvertFuzz(
      upb::fuzz::MiniTableFuzzInput{
          {"$$$$$)@*$$$$$$$$$$$$$$$$$$$$$"}, {"!!"}, "", {0}},
      upb::fuzz::MiniTableFuzzInput{
          {""},
          {"\205"},
          std::string("(\000%%", 4),
          {583690751, 583690751, 583690751, 583690751, 583690751, 583690751,
           583690751, 583690751, 583690751, 583690751, 583690751, 583690751,
           583690751, 583690751, 583690751, 583690751, 583690751, 583690751}},
      "M++\246\2468 0q", 3620340527, 1624945934);
}

TEST(ConvertFuzz, ArbitraryMiniTableConvertFuzzRegression3) {
  ArbitraryMiniTableConvertFuzz(
      upb::fuzz::MiniTableFuzzInput{
          {"$====$$$$$$$$$$$$$$$$$$$$$$$$$$$$"}, {}, "", {1, 0}},
      upb::fuzz::MiniTableFuzzInput{{""}, {}, "", {2147483647, 2147483647}},
      std::string("M++8J \321\010\220\000\000", 11), 1698778329, 268447861);
}

TEST(ConvertFuzz, ArbitraryMiniTableConvertFuzzRegression4) {
  ArbitraryMiniTableConvertFuzz(
      upb::fuzz::MiniTableFuzzInput{
          {"$====$$$$$$$$$$$$$$$$$$$$$$$$$$$$"}, {}, "", {1, 0}},
      upb::fuzz::MiniTableFuzzInput{{""}, {}, "", {2147483647, 2147483647}},
      std::string("M++8J \020\020\010\222\000\000", 12), 3565880130, 915768989);
}

TEST(ConvertFuzz, ArbitraryMiniTableConvertFuzzRegression5) {
  ArbitraryMiniTableConvertFuzz(
      upb::fuzz::MiniTableFuzzInput{
          {"$====$$$$$$$$$$$$$$$$$$$$$$$$$$$$"}, {""}, "", {0}},
      upb::fuzz::MiniTableFuzzInput{
          {""}, {"", "", ""}, "", {2147483647, 2147483647}},
      std::string("M+\030\030\030\030\030\030\0008J \321\000", 14), 3565882178,
      268447849);
}

TEST(ConvertFuzz, ArbitraryMiniTableConvertFuzzRegression6) {
  ArbitraryMiniTableConvertFuzz(
      upb::fuzz::MiniTableFuzzInput{{""}, {""}, "y", {}},
      upb::fuzz::MiniTableFuzzInput{{"$****NNNN*"}, {""}, "\340", {}},
      std::string("H\332\213\213\213\213\213\221\000", 9), 2051328899,
      3168645944);
}

TEST(ConvertFuzz, ArbitraryMiniTableConvertFuzzRegression7) {
  ArbitraryMiniTableConvertFuzz(
      upb::fuzz::MiniTableFuzzInput{{"$****NNNN*"}, {""}, "\203", {}},
      upb::fuzz::MiniTableFuzzInput{
          {"$****NNNN*"}, {"/", ""}, "\377\377\377\377\377\377\377\037", {}},
      std::string("H\332\260\213\213\213\213\213\221\000", 10), 3460373026,
      3168645944);
}

TEST(ConvertFuzz, ArbitraryMiniTableConvertFuzzRegression8) {
  ArbitraryMiniTableConvertFuzz(
      upb::fuzz::MiniTableFuzzInput{
          {"$$$FFFFFFFFFFFFFFFFF", "", ""}, {"&"}, "@C", {2147483642}},
      upb::fuzz::MiniTableFuzzInput{{"", ""}, {}, "", {}}, "[\\\010\003", 10,
      1153856912);
}

TEST(ConvertFuzz, ArbitraryMiniTableConvertFuzzRegression9) {
  ArbitraryMiniTableConvertFuzz(
      upb::fuzz::MiniTableFuzzInput{
          {"$1G2", "%1*", "\'"}, {"\260", "\260"}, "", {2147483647, 821344772}},
      upb::fuzz::MiniTableFuzzInput{
          {"", ""}, {"\002", "\371\377"}, std::string("\000", 1), {2147483647}},
      std::string("\022\003\n\001\025\022\000a\000\210\210\000\202\257\257\005",
                  16),
      4058141318, 2394867369);
}
TEST(ConvertFuzz, ArbitraryMiniTableConvertFuzzRegression_b522284547) {
  ArbitraryMiniTableConvertFuzz(
      upb::fuzz::MiniTableFuzzInput{
          {"$gYYYxYYYY111111"}, {"\037"}, "#8#####", {1}},
      upb::fuzz::MiniTableFuzzInput{{"&", "$a#&", ":"}, {}, "H", {4294967295}},
      std::string("\r\000\000\000\302@\000", 7), 224686147, 909543686);
}

TEST(ConvertFuzz, ArbitraryMiniTableConvertFuzzRegression_b522283360) {
  ArbitraryMiniTableConvertFuzz(
      upb::fuzz::MiniTableFuzzInput{
          {"$YYYYxYYYY111111"}, {}, "###d##h#", {1225118708}},
      upb::fuzz::MiniTableFuzzInput{{"&", ""},
                                    {"\210", "\210",
                                     "\210", "\210",
                                     "\210", "\210",
                                     "\210", "\210",
                                     "\210", "\210",
                                     "\210", "\210",
                                     "\210", "\210\005\005",
                                     "\010", std::string("\210\001\000", 3),
                                     "\210", "\210",
                                     "\210", "\210",
                                     "\210", "\210",
                                     "\210", "\210",
                                     "\210", "",
                                     "",     "",
                                     "\210", "",
                                     "\210", "\210",
                                     "\210", "\210",
                                     "\210", "\210",
                                     "\210", "\210",
                                     "\210", "\210"},
                                    "\235\274\235",
                                    {3130066253, 3556537314, 4294967293}},
      "\rM\035MMMB\377\301\037", 3129627418, 2812959198);
}

TEST(ConvertFuzz, ArbitraryMiniTableConvertFuzzRegression_b529945368) {
  ArbitraryMiniTableConvertFuzz(
      upb::fuzz::MiniTableFuzzInput{{"$gY11"}, {}, "#.", {}},
      upb::fuzz::MiniTableFuzzInput{{"$4#6;"}, {"", "!\030!rn\032"}, "l", {}},
      std::string("Q\004\205\344\000\010\010\t\030\010\230\245\351\221=}"
                  "\000\000\300\376",
                  20),
      372456973, 1140553636);
}
}  // namespace

}  // namespace upb
