/src/zstd/tests/fuzz/zstd_helpers.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2016-present, Facebook, Inc. |
3 | | * All rights reserved. |
4 | | * |
5 | | * This source code is licensed under both the BSD-style license (found in the |
6 | | * LICENSE file in the root directory of this source tree) and the GPLv2 (found |
7 | | * in the COPYING file in the root directory of this source tree). |
8 | | */ |
9 | | |
10 | | #define ZSTD_STATIC_LINKING_ONLY |
11 | | #define ZDICT_STATIC_LINKING_ONLY |
12 | | |
13 | | #include <string.h> |
14 | | |
15 | | #include "zstd_helpers.h" |
16 | | #include "fuzz_helpers.h" |
17 | | #include "zstd.h" |
18 | | #include "zdict.h" |
19 | | |
20 | | static void set(ZSTD_CCtx *cctx, ZSTD_cParameter param, int value) |
21 | 0 | { |
22 | 0 | FUZZ_ZASSERT(ZSTD_CCtx_setParameter(cctx, param, value)); |
23 | 0 | } |
24 | | |
25 | | static void setRand(ZSTD_CCtx *cctx, ZSTD_cParameter param, unsigned min, |
26 | 0 | unsigned max, uint32_t *state) { |
27 | 0 | unsigned const value = FUZZ_rand32(state, min, max); |
28 | 0 | set(cctx, param, value); |
29 | 0 | } |
30 | | |
31 | | ZSTD_compressionParameters FUZZ_randomCParams(size_t srcSize, uint32_t *state) |
32 | 0 | { |
33 | 0 | /* Select compression parameters */ |
34 | 0 | ZSTD_compressionParameters cParams; |
35 | 0 | cParams.windowLog = FUZZ_rand32(state, ZSTD_WINDOWLOG_MIN, 15); |
36 | 0 | cParams.hashLog = FUZZ_rand32(state, ZSTD_HASHLOG_MIN, 15); |
37 | 0 | cParams.chainLog = FUZZ_rand32(state, ZSTD_CHAINLOG_MIN, 16); |
38 | 0 | cParams.searchLog = FUZZ_rand32(state, ZSTD_SEARCHLOG_MIN, 9); |
39 | 0 | cParams.minMatch = FUZZ_rand32(state, ZSTD_MINMATCH_MIN, |
40 | 0 | ZSTD_MINMATCH_MAX); |
41 | 0 | cParams.targetLength = FUZZ_rand32(state, 0, 512); |
42 | 0 | cParams.strategy = FUZZ_rand32(state, ZSTD_STRATEGY_MIN, ZSTD_STRATEGY_MAX); |
43 | 0 | return ZSTD_adjustCParams(cParams, srcSize, 0); |
44 | 0 | } |
45 | | |
46 | | ZSTD_frameParameters FUZZ_randomFParams(uint32_t *state) |
47 | 0 | { |
48 | 0 | /* Select frame parameters */ |
49 | 0 | ZSTD_frameParameters fParams; |
50 | 0 | fParams.contentSizeFlag = FUZZ_rand32(state, 0, 1); |
51 | 0 | fParams.checksumFlag = FUZZ_rand32(state, 0, 1); |
52 | 0 | fParams.noDictIDFlag = FUZZ_rand32(state, 0, 1); |
53 | 0 | return fParams; |
54 | 0 | } |
55 | | |
56 | | ZSTD_parameters FUZZ_randomParams(size_t srcSize, uint32_t *state) |
57 | 0 | { |
58 | 0 | ZSTD_parameters params; |
59 | 0 | params.cParams = FUZZ_randomCParams(srcSize, state); |
60 | 0 | params.fParams = FUZZ_randomFParams(state); |
61 | 0 | return params; |
62 | 0 | } |
63 | | |
64 | | void FUZZ_setRandomParameters(ZSTD_CCtx *cctx, size_t srcSize, uint32_t *state) |
65 | 0 | { |
66 | 0 | ZSTD_compressionParameters cParams = FUZZ_randomCParams(srcSize, state); |
67 | 0 | set(cctx, ZSTD_c_windowLog, cParams.windowLog); |
68 | 0 | set(cctx, ZSTD_c_hashLog, cParams.hashLog); |
69 | 0 | set(cctx, ZSTD_c_chainLog, cParams.chainLog); |
70 | 0 | set(cctx, ZSTD_c_searchLog, cParams.searchLog); |
71 | 0 | set(cctx, ZSTD_c_minMatch, cParams.minMatch); |
72 | 0 | set(cctx, ZSTD_c_targetLength, cParams.targetLength); |
73 | 0 | set(cctx, ZSTD_c_strategy, cParams.strategy); |
74 | 0 | /* Select frame parameters */ |
75 | 0 | setRand(cctx, ZSTD_c_contentSizeFlag, 0, 1, state); |
76 | 0 | setRand(cctx, ZSTD_c_checksumFlag, 0, 1, state); |
77 | 0 | setRand(cctx, ZSTD_c_dictIDFlag, 0, 1, state); |
78 | 0 | /* Select long distance matching parameters */ |
79 | 0 | setRand(cctx, ZSTD_c_enableLongDistanceMatching, 0, 1, state); |
80 | 0 | setRand(cctx, ZSTD_c_ldmHashLog, ZSTD_HASHLOG_MIN, 16, state); |
81 | 0 | setRand(cctx, ZSTD_c_ldmMinMatch, ZSTD_LDM_MINMATCH_MIN, |
82 | 0 | ZSTD_LDM_MINMATCH_MAX, state); |
83 | 0 | setRand(cctx, ZSTD_c_ldmBucketSizeLog, 0, ZSTD_LDM_BUCKETSIZELOG_MAX, |
84 | 0 | state); |
85 | 0 | setRand(cctx, ZSTD_c_ldmHashRateLog, ZSTD_LDM_HASHRATELOG_MIN, |
86 | 0 | ZSTD_LDM_HASHRATELOG_MAX, state); |
87 | 0 | /* Set misc parameters */ |
88 | 0 | setRand(cctx, ZSTD_c_nbWorkers, 0, 2, state); |
89 | 0 | setRand(cctx, ZSTD_c_rsyncable, 0, 1, state); |
90 | 0 | setRand(cctx, ZSTD_c_forceMaxWindow, 0, 1, state); |
91 | 0 | setRand(cctx, ZSTD_c_literalCompressionMode, 0, 2, state); |
92 | 0 | setRand(cctx, ZSTD_c_forceAttachDict, 0, 2, state); |
93 | 0 | } |
94 | | |
95 | | FUZZ_dict_t FUZZ_train(void const* src, size_t srcSize, uint32_t *state) |
96 | 5.82k | { |
97 | 5.82k | size_t const dictSize = MAX(srcSize / 8, 1024); |
98 | 5.82k | size_t const totalSampleSize = dictSize * 11; |
99 | 5.82k | FUZZ_dict_t dict = { malloc(dictSize), dictSize }; |
100 | 5.82k | char* const samples = (char*)malloc(totalSampleSize); |
101 | 5.82k | unsigned nbSamples = 100; |
102 | 5.82k | size_t* const samplesSizes = (size_t*)malloc(sizeof(size_t) * nbSamples); |
103 | 5.82k | size_t pos = 0; |
104 | 5.82k | size_t sample = 0; |
105 | 5.82k | ZDICT_fastCover_params_t params; |
106 | 5.82k | FUZZ_ASSERT(dict.buff && samples && samplesSizes); |
107 | 5.82k | |
108 | 588k | for (sample = 0; sample < nbSamples; ++sample) { |
109 | 582k | size_t const remaining = totalSampleSize - pos; |
110 | 582k | size_t const offset = FUZZ_rand32(state, 0, MAX(srcSize, 1) - 1); |
111 | 582k | size_t const limit = MIN(srcSize - offset, remaining); |
112 | 582k | size_t const toCopy = MIN(limit, remaining / (nbSamples - sample)); |
113 | 582k | memcpy(samples + pos, src + offset, toCopy); |
114 | 582k | pos += toCopy; |
115 | 582k | samplesSizes[sample] = toCopy; |
116 | 582k | |
117 | 582k | } |
118 | 5.82k | memset(samples + pos, 0, totalSampleSize - pos); |
119 | 5.82k | |
120 | 5.82k | memset(¶ms, 0, sizeof(params)); |
121 | 5.82k | params.accel = 5; |
122 | 5.82k | params.k = 40; |
123 | 5.82k | params.d = 8; |
124 | 5.82k | params.f = 14; |
125 | 5.82k | params.zParams.compressionLevel = 1; |
126 | 5.82k | dict.size = ZDICT_trainFromBuffer_fastCover(dict.buff, dictSize, |
127 | 5.82k | samples, samplesSizes, nbSamples, params); |
128 | 5.82k | if (ZSTD_isError(dict.size)) { |
129 | 2.52k | free(dict.buff); |
130 | 2.52k | memset(&dict, 0, sizeof(dict)); |
131 | 2.52k | } |
132 | 5.82k | |
133 | 5.82k | free(samplesSizes); |
134 | 5.82k | free(samples); |
135 | 5.82k | |
136 | 5.82k | return dict; |
137 | 5.82k | } |