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