pickle_fuzzer.cc 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // Copyright 2018 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 <fuzzer/FuzzedDataProvider.h>
  5. #include <tuple>
  6. #include "base/pickle.h"
  7. namespace {
  8. constexpr int kIterations = 16;
  9. constexpr int kReadControlBytes = 32;
  10. constexpr int kReadDataTypes = 17;
  11. constexpr int kMaxReadLength = 1024;
  12. constexpr int kMaxSkipBytes = 1024;
  13. } // namespace
  14. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  15. if (size < kReadControlBytes) {
  16. return 0;
  17. }
  18. // Use the first kReadControlBytes bytes of the fuzzer input to control how
  19. // the pickled data is read.
  20. FuzzedDataProvider data_provider(data, kReadControlBytes);
  21. data += kReadControlBytes;
  22. size -= kReadControlBytes;
  23. base::Pickle pickle(reinterpret_cast<const char*>(data), size);
  24. base::PickleIterator iter(pickle);
  25. for (int i = 0; i < kIterations; i++) {
  26. uint8_t read_type = data_provider.ConsumeIntegral<uint8_t>();
  27. switch (read_type % kReadDataTypes) {
  28. case 0: {
  29. bool result = 0;
  30. std::ignore = iter.ReadBool(&result);
  31. break;
  32. }
  33. case 1: {
  34. int result = 0;
  35. std::ignore = iter.ReadInt(&result);
  36. break;
  37. }
  38. case 2: {
  39. long result = 0;
  40. std::ignore = iter.ReadLong(&result);
  41. break;
  42. }
  43. case 3: {
  44. uint16_t result = 0;
  45. std::ignore = iter.ReadUInt16(&result);
  46. break;
  47. }
  48. case 4: {
  49. uint32_t result = 0;
  50. std::ignore = iter.ReadUInt32(&result);
  51. break;
  52. }
  53. case 5: {
  54. int64_t result = 0;
  55. std::ignore = iter.ReadInt64(&result);
  56. break;
  57. }
  58. case 6: {
  59. uint64_t result = 0;
  60. std::ignore = iter.ReadUInt64(&result);
  61. break;
  62. }
  63. case 7: {
  64. float result = 0;
  65. std::ignore = iter.ReadFloat(&result);
  66. break;
  67. }
  68. case 8: {
  69. double result = 0;
  70. std::ignore = iter.ReadDouble(&result);
  71. break;
  72. }
  73. case 9: {
  74. std::string result;
  75. std::ignore = iter.ReadString(&result);
  76. break;
  77. }
  78. case 10: {
  79. base::StringPiece result;
  80. std::ignore = iter.ReadStringPiece(&result);
  81. break;
  82. }
  83. case 11: {
  84. std::u16string result;
  85. std::ignore = iter.ReadString16(&result);
  86. break;
  87. }
  88. case 12: {
  89. base::StringPiece16 result;
  90. std::ignore = iter.ReadStringPiece16(&result);
  91. break;
  92. }
  93. case 13: {
  94. const char* data_result = nullptr;
  95. size_t length_result = 0;
  96. std::ignore = iter.ReadData(&data_result, &length_result);
  97. break;
  98. }
  99. case 14: {
  100. const char* data_result = nullptr;
  101. int read_length =
  102. data_provider.ConsumeIntegralInRange(0, kMaxReadLength);
  103. std::ignore =
  104. iter.ReadBytes(&data_result, static_cast<size_t>(read_length));
  105. break;
  106. }
  107. case 15: {
  108. size_t result = 0;
  109. std::ignore = iter.ReadLength(&result);
  110. break;
  111. }
  112. case 16: {
  113. std::ignore = iter.SkipBytes(static_cast<size_t>(
  114. data_provider.ConsumeIntegralInRange(0, kMaxSkipBytes)));
  115. break;
  116. }
  117. }
  118. }
  119. return 0;
  120. }