main.cpp 2.4 KB

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