Mercurial > public > mercurial-scm > hg
annotate contrib/fuzz/mpatch.cc @ 40788:41f0529b5112 stable
commandserver: get around ETIMEDOUT raised by selectors2
selector.select() should exits with an empty event list on timed out, but
selectors2 raises OSError if timeout expires while recovering from EINTR.
Spotted while debugging new chg feature.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Mon, 03 Dec 2018 21:45:15 +0900 |
parents | 46dcb9f14900 |
children | 51a99e09c54b |
rev | line source |
---|---|
38246
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
1 /* |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
2 * mpatch.cc - fuzzer harness for mpatch.c |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
3 * |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
4 * Copyright 2018, Google Inc. |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
5 * |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
6 * This software may be used and distributed according to the terms of |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
7 * the GNU General Public License, incorporated herein by reference. |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
8 */ |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
9 #include <iostream> |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
10 #include <memory> |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
11 #include <stdint.h> |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
12 #include <stdlib.h> |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
13 #include <vector> |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
14 |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
15 #include "fuzzutil.h" |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
16 |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
17 // To avoid having too many OOMs from the fuzzer infrastructure, we'll |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
18 // skip patch application if the resulting fulltext would be bigger |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
19 // than 10MiB. |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
20 #define MAX_OUTPUT_SIZE 10485760 |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
21 |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
22 extern "C" { |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
23 #include "bitmanipulation.h" |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
24 #include "mpatch.h" |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
25 |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
26 struct mpatchbin { |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
27 std::unique_ptr<char[]> data; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
28 size_t len; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
29 }; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
30 |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
31 static mpatch_flist *getitem(void *vbins, ssize_t pos) |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
32 { |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
33 std::vector<mpatchbin> *bins = (std::vector<mpatchbin> *)vbins; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
34 const mpatchbin &bin = bins->at(pos + 1); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
35 struct mpatch_flist *res; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
36 LOG(2) << "mpatch_decode " << bin.len << std::endl; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
37 if (mpatch_decode(bin.data.get(), bin.len, &res) < 0) |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
38 return NULL; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
39 return res; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
40 } |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
41 |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
42 // input format: |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
43 // u8 number of inputs |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
44 // one u16 for each input, its length |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
45 // the inputs |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
46 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
47 { |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
48 if (!Size) { |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
49 return 0; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
50 } |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
51 // First byte of data is how many texts we expect, first text |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
52 // being the base the rest being the deltas. |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
53 ssize_t numtexts = Data[0]; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
54 if (numtexts < 2) { |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
55 // No point if we don't have at least a base text and a delta... |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
56 return 0; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
57 } |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
58 // Each text will be described by a byte for how long it |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
59 // should be, so give up if we don't have enough. |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
60 if ((Size - 1) < (numtexts * 2)) { |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
61 return 0; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
62 } |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
63 size_t consumed = 1 + (numtexts * 2); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
64 LOG(2) << "input contains " << Size << std::endl; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
65 LOG(2) << numtexts << " texts, consuming " << consumed << std::endl; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
66 std::vector<mpatchbin> bins; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
67 bins.reserve(numtexts); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
68 for (int i = 0; i < numtexts; ++i) { |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
69 mpatchbin bin; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
70 size_t nthsize = getbeuint16((char *)Data + 1 + (2 * i)); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
71 LOG(2) << "text " << i << " is " << nthsize << std::endl; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
72 char *start = (char *)Data + consumed; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
73 consumed += nthsize; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
74 if (consumed > Size) { |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
75 LOG(2) << "ran out of data, consumed " << consumed |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
76 << " of " << Size << std::endl; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
77 return 0; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
78 } |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
79 bin.len = nthsize; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
80 bin.data.reset(new char[nthsize]); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
81 memcpy(bin.data.get(), start, nthsize); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
82 bins.push_back(std::move(bin)); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
83 } |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
84 LOG(2) << "mpatch_flist" << std::endl; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
85 struct mpatch_flist *patch = |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
86 mpatch_fold(&bins, getitem, 0, numtexts - 1); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
87 if (!patch) { |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
88 return 0; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
89 } |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
90 LOG(2) << "mpatch_calcsize" << std::endl; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
91 ssize_t outlen = mpatch_calcsize(bins[0].len, patch); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
92 LOG(2) << "outlen " << outlen << std::endl; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
93 if (outlen < 0 || outlen > MAX_OUTPUT_SIZE) { |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
94 goto cleanup; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
95 } |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
96 { |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
97 char *dest = (char *)malloc(outlen); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
98 LOG(2) << "expecting " << outlen << " total bytes at " |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
99 << (void *)dest << std::endl; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
100 mpatch_apply(dest, bins[0].data.get(), bins[0].len, patch); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
101 free(dest); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
102 LOG(1) << "applied a complete patch" << std::endl; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
103 } |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
104 cleanup: |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
105 mpatch_lfree(patch); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
106 return 0; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
107 } |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
108 |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
109 #ifdef HG_FUZZER_INCLUDE_MAIN |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
110 int main(int argc, char **argv) |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
111 { |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
112 // One text, one patch. |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
113 const char data[] = "\x02\x00\0x1\x00\x0d" |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
114 // base text |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
115 "a" |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
116 // binary delta that will append a single b |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
117 "\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01b"; |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
118 return LLVMFuzzerTestOneInput((const uint8_t *)data, 19); |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
119 } |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
120 #endif |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
121 |
46dcb9f14900
fuzz: new fuzzer for the mpatch code
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
122 } // extern "C" |