annotate contrib/fuzz/mpatch.cc @ 40374:47c03042cd1d

branchmap: pass changelog into branchmap functions As part of building the branchmap, we loop over revs and call branchmap() or _branchmap(). Previously, these functions were accessing repo.changelog. We know from past experience that repo.changelog in loops is bad for performance. This commit teaches the branchmap code to pass a changelog instance into branchmap() and _branchmap() so we don't need to pay this penalty. On my MBP, this appears to show a speedup on a clone of the mozilla-unified repo: $ hg perfbranchmap --clear-revbranch ! base ! wall 21.078160 comb 21.070000 user 20.920000 sys 0.150000 (best of 3) ! wall 20.574682 comb 20.560000 user 20.400000 sys 0.160000 (best of 3) $ hg perfbranchmap ! base ! wall 4.880413 comb 4.870000 user 4.860000 sys 0.010000 (best of 3) ! wall 4.573968 comb 4.560000 user 4.550000 sys 0.010000 (best of 3) Differential Revision: https://phab.mercurial-scm.org/D5161
author Gregory Szorc <gregory.szorc@gmail.com>
date Fri, 19 Oct 2018 16:16:17 +0200
parents 46dcb9f14900
children 51a99e09c54b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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"