main.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #include <contrib/libs/protobuf-mutator/src/libfuzzer/libfuzzer_macro.h>
  2. #include <google/protobuf/stubs/logging.h>
  3. #include <library/cpp/blockcodecs/codecs.h>
  4. #include <library/cpp/blockcodecs/fuzz/proto/case.pb.h>
  5. #include <library/cpp/blockcodecs/stream.h>
  6. #include <util/stream/input.h>
  7. #include <util/stream/length.h>
  8. #include <util/stream/mem.h>
  9. #include <util/stream/null.h>
  10. #include <util/stream/str.h>
  11. using NBlockCodecs::NFuzz::TPackUnpackCase;
  12. using NBlockCodecs::TCodedOutput;
  13. using NBlockCodecs::TDecodedInput;
  14. static void ValidateBufferSize(const ui32 size) {
  15. Y_ENSURE(size > 0 && size <= 16ULL * 1024);
  16. }
  17. static void DoOnlyDecode(const TPackUnpackCase& case_) {
  18. if (!case_.GetPacked()) {
  19. return;
  20. }
  21. TMemoryInput mi(case_.GetData().data(), case_.GetData().size());
  22. TDecodedInput di(&mi);
  23. TNullOutput no;
  24. TCountingOutput cno(&no);
  25. TransferData(&di, &cno);
  26. }
  27. static void DoDecodeEncode(const TPackUnpackCase& case_) {
  28. auto* const codec = NBlockCodecs::Codec(case_.GetCodecName());
  29. Y_ENSURE(codec);
  30. TMemoryInput mi(case_.GetData().data(), case_.GetData().size());
  31. TDecodedInput di(&mi, codec);
  32. TStringStream decoded;
  33. TransferData(&di, &decoded);
  34. TNullOutput no;
  35. TCountingOutput cno(&no);
  36. TCodedOutput co(&cno, codec, case_.GetBufferLength());
  37. TransferData(&decoded, &co);
  38. co.Flush();
  39. Y_VERIFY((case_.GetData().size() > 0) == (cno.Counter() > 0));
  40. Y_VERIFY((case_.GetData().size() > 0) == (decoded.Str().size() > 0));
  41. }
  42. static void DoEncodeDecode(const TPackUnpackCase& case_) {
  43. auto* const codec = NBlockCodecs::Codec(case_.GetCodecName());
  44. Y_ENSURE(codec);
  45. TMemoryInput mi(case_.GetData().data(), case_.GetData().size());
  46. TStringStream encoded;
  47. TCodedOutput co(&encoded, codec, case_.GetBufferLength());
  48. TransferData(&mi, &co);
  49. co.Flush();
  50. TStringStream decoded;
  51. TDecodedInput di(&encoded, codec);
  52. TransferData(&di, &decoded);
  53. Y_VERIFY((case_.GetData().size() > 0) == (encoded.Str().size() > 0));
  54. Y_VERIFY(case_.GetData() == decoded.Str());
  55. }
  56. DEFINE_BINARY_PROTO_FUZZER(const TPackUnpackCase& case_) {
  57. try {
  58. if (!case_.GetCodecName()) {
  59. DoOnlyDecode(case_);
  60. return;
  61. }
  62. ValidateBufferSize(case_.GetBufferLength());
  63. if (case_.GetPacked()) {
  64. DoDecodeEncode(case_);
  65. } else {
  66. DoEncodeDecode(case_);
  67. }
  68. } catch (const std::exception&) {
  69. }
  70. }