1/*
2 *
3 * honggfuzz - run->dynamicFilefer mangling routines
4 * -----------------------------------------
5 *
6 * Author:
7 * Robert Swiecki <swiecki@google.com>
8 *
9 * Copyright 2010-2015 by Google Inc. All Rights Reserved.
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License"); you may
12 * not use this file except in compliance with the License. You may obtain
13 * a copy of the License at
14 *
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
20 * implied. See the License for the specific language governing
21 * permissions and limitations under the License.
22 *
23 */
24
25#include "mangle.h"
26
27#include <inttypes.h>
28#include <math.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <sys/mman.h>
33#include <unistd.h>
34
35#include "libcommon/common.h"
36#include "libcommon/log.h"
37#include "libcommon/util.h"
38
39static inline void mangle_Overwrite(run_t* run, const uint8_t* src, size_t off, size_t sz) {
40    size_t maxToCopy = run->dynamicFileSz - off;
41    if (sz > maxToCopy) {
42        sz = maxToCopy;
43    }
44
45    memmove(&run->dynamicFile[off], src, sz);
46}
47
48static inline void mangle_Move(run_t* run, size_t off_from, size_t off_to, size_t len) {
49    if (off_from >= run->dynamicFileSz) {
50        return;
51    }
52    if (off_to >= run->dynamicFileSz) {
53        return;
54    }
55
56    ssize_t len_from = (ssize_t)run->dynamicFileSz - off_from - 1;
57    ssize_t len_to = (ssize_t)run->dynamicFileSz - off_to - 1;
58
59    if ((ssize_t)len > len_from) {
60        len = len_from;
61    }
62    if ((ssize_t)len > len_to) {
63        len = len_to;
64    }
65
66    memmove(&run->dynamicFile[off_to], &run->dynamicFile[off_from], len);
67}
68
69static void mangle_Inflate(run_t* run, size_t off, size_t len) {
70    if (run->dynamicFileSz >= run->global->maxFileSz) {
71        return;
72    }
73    if (len > (run->global->maxFileSz - run->dynamicFileSz)) {
74        len = run->global->maxFileSz - run->dynamicFileSz;
75    }
76
77    run->dynamicFileSz += len;
78    mangle_Move(run, off, off + len, run->dynamicFileSz);
79}
80
81static void mangle_MemMove(run_t* run) {
82    size_t off_from = util_rndGet(0, run->dynamicFileSz - 1);
83    size_t off_to = util_rndGet(0, run->dynamicFileSz - 1);
84    size_t len = util_rndGet(0, run->dynamicFileSz);
85
86    mangle_Move(run, off_from, off_to, len);
87}
88
89static void mangle_Byte(run_t* run) {
90    size_t off = util_rndGet(0, run->dynamicFileSz - 1);
91    run->dynamicFile[off] = (uint8_t)util_rnd64();
92}
93
94static void mangle_Bytes(run_t* run) {
95    size_t off = util_rndGet(0, run->dynamicFileSz - 1);
96    uint32_t val = (uint32_t)util_rnd64();
97
98    /* Overwrite with random 2,3,4-byte values */
99    size_t toCopy = util_rndGet(2, 4);
100    mangle_Overwrite(run, (uint8_t*)&val, off, toCopy);
101}
102
103static void mangle_Bit(run_t* run) {
104    size_t off = util_rndGet(0, run->dynamicFileSz - 1);
105    run->dynamicFile[off] ^= (uint8_t)(1U << util_rndGet(0, 7));
106}
107
108static void mangle_DictionaryInsert(run_t* run) {
109    if (run->global->dictionaryCnt == 0) {
110        mangle_Bit(run);
111        return;
112    }
113
114    uint64_t choice = util_rndGet(0, run->global->dictionaryCnt - 1);
115    struct strings_t* str = TAILQ_FIRST(&run->global->dictq);
116    for (uint64_t i = 0; i < choice; i++) {
117        str = TAILQ_NEXT(str, pointers);
118    }
119
120    size_t off = util_rndGet(0, run->dynamicFileSz - 1);
121    mangle_Inflate(run, off, str->len);
122    mangle_Move(run, off, off + str->len, str->len);
123    mangle_Overwrite(run, (uint8_t*)str->s, off, str->len);
124}
125
126static void mangle_Dictionary(run_t* run) {
127    if (run->global->dictionaryCnt == 0) {
128        mangle_Bit(run);
129        return;
130    }
131
132    size_t off = util_rndGet(0, run->dynamicFileSz - 1);
133
134    uint64_t choice = util_rndGet(0, run->global->dictionaryCnt - 1);
135    struct strings_t* str = TAILQ_FIRST(&run->global->dictq);
136    for (uint64_t i = 0; i < choice; i++) {
137        str = TAILQ_NEXT(str, pointers);
138    }
139
140    mangle_Overwrite(run, (uint8_t*)str->s, off, str->len);
141}
142
143static void mangle_Magic(run_t* run) {
144    static const struct {
145        const uint8_t val[8];
146        const size_t size;
147    } mangleMagicVals[] = {
148        /* 1B - No endianness */
149        {"\x00\x00\x00\x00\x00\x00\x00\x00", 1},
150        {"\x01\x00\x00\x00\x00\x00\x00\x00", 1},
151        {"\x02\x00\x00\x00\x00\x00\x00\x00", 1},
152        {"\x03\x00\x00\x00\x00\x00\x00\x00", 1},
153        {"\x04\x00\x00\x00\x00\x00\x00\x00", 1},
154        {"\x05\x00\x00\x00\x00\x00\x00\x00", 1},
155        {"\x06\x00\x00\x00\x00\x00\x00\x00", 1},
156        {"\x07\x00\x00\x00\x00\x00\x00\x00", 1},
157        {"\x08\x00\x00\x00\x00\x00\x00\x00", 1},
158        {"\x09\x00\x00\x00\x00\x00\x00\x00", 1},
159        {"\x0A\x00\x00\x00\x00\x00\x00\x00", 1},
160        {"\x0B\x00\x00\x00\x00\x00\x00\x00", 1},
161        {"\x0C\x00\x00\x00\x00\x00\x00\x00", 1},
162        {"\x0D\x00\x00\x00\x00\x00\x00\x00", 1},
163        {"\x0E\x00\x00\x00\x00\x00\x00\x00", 1},
164        {"\x0F\x00\x00\x00\x00\x00\x00\x00", 1},
165        {"\x10\x00\x00\x00\x00\x00\x00\x00", 1},
166        {"\x20\x00\x00\x00\x00\x00\x00\x00", 1},
167        {"\x40\x00\x00\x00\x00\x00\x00\x00", 1},
168        {"\x7E\x00\x00\x00\x00\x00\x00\x00", 1},
169        {"\x7F\x00\x00\x00\x00\x00\x00\x00", 1},
170        {"\x80\x00\x00\x00\x00\x00\x00\x00", 1},
171        {"\x81\x00\x00\x00\x00\x00\x00\x00", 1},
172        {"\xC0\x00\x00\x00\x00\x00\x00\x00", 1},
173        {"\xFE\x00\x00\x00\x00\x00\x00\x00", 1},
174        {"\xFF\x00\x00\x00\x00\x00\x00\x00", 1},
175        /* 2B - NE */
176        {"\x00\x00\x00\x00\x00\x00\x00\x00", 2},
177        {"\x01\x01\x00\x00\x00\x00\x00\x00", 2},
178        {"\x80\x80\x00\x00\x00\x00\x00\x00", 2},
179        {"\xFF\xFF\x00\x00\x00\x00\x00\x00", 2},
180        /* 2B - BE */
181        {"\x00\x01\x00\x00\x00\x00\x00\x00", 2},
182        {"\x00\x02\x00\x00\x00\x00\x00\x00", 2},
183        {"\x00\x03\x00\x00\x00\x00\x00\x00", 2},
184        {"\x00\x04\x00\x00\x00\x00\x00\x00", 2},
185        {"\x00\x05\x00\x00\x00\x00\x00\x00", 2},
186        {"\x00\x06\x00\x00\x00\x00\x00\x00", 2},
187        {"\x00\x07\x00\x00\x00\x00\x00\x00", 2},
188        {"\x00\x08\x00\x00\x00\x00\x00\x00", 2},
189        {"\x00\x09\x00\x00\x00\x00\x00\x00", 2},
190        {"\x00\x0A\x00\x00\x00\x00\x00\x00", 2},
191        {"\x00\x0B\x00\x00\x00\x00\x00\x00", 2},
192        {"\x00\x0C\x00\x00\x00\x00\x00\x00", 2},
193        {"\x00\x0D\x00\x00\x00\x00\x00\x00", 2},
194        {"\x00\x0E\x00\x00\x00\x00\x00\x00", 2},
195        {"\x00\x0F\x00\x00\x00\x00\x00\x00", 2},
196        {"\x00\x10\x00\x00\x00\x00\x00\x00", 2},
197        {"\x00\x20\x00\x00\x00\x00\x00\x00", 2},
198        {"\x00\x40\x00\x00\x00\x00\x00\x00", 2},
199        {"\x00\x7E\x00\x00\x00\x00\x00\x00", 2},
200        {"\x00\x7F\x00\x00\x00\x00\x00\x00", 2},
201        {"\x00\x80\x00\x00\x00\x00\x00\x00", 2},
202        {"\x00\x81\x00\x00\x00\x00\x00\x00", 2},
203        {"\x00\xC0\x00\x00\x00\x00\x00\x00", 2},
204        {"\x00\xFE\x00\x00\x00\x00\x00\x00", 2},
205        {"\x00\xFF\x00\x00\x00\x00\x00\x00", 2},
206        {"\x7E\xFF\x00\x00\x00\x00\x00\x00", 2},
207        {"\x7F\xFF\x00\x00\x00\x00\x00\x00", 2},
208        {"\x80\x00\x00\x00\x00\x00\x00\x00", 2},
209        {"\x80\x01\x00\x00\x00\x00\x00\x00", 2},
210        {"\xFF\xFE\x00\x00\x00\x00\x00\x00", 2},
211        /* 2B - LE */
212        {"\x00\x00\x00\x00\x00\x00\x00\x00", 2},
213        {"\x01\x00\x00\x00\x00\x00\x00\x00", 2},
214        {"\x02\x00\x00\x00\x00\x00\x00\x00", 2},
215        {"\x03\x00\x00\x00\x00\x00\x00\x00", 2},
216        {"\x04\x00\x00\x00\x00\x00\x00\x00", 2},
217        {"\x05\x00\x00\x00\x00\x00\x00\x00", 2},
218        {"\x06\x00\x00\x00\x00\x00\x00\x00", 2},
219        {"\x07\x00\x00\x00\x00\x00\x00\x00", 2},
220        {"\x08\x00\x00\x00\x00\x00\x00\x00", 2},
221        {"\x09\x00\x00\x00\x00\x00\x00\x00", 2},
222        {"\x0A\x00\x00\x00\x00\x00\x00\x00", 2},
223        {"\x0B\x00\x00\x00\x00\x00\x00\x00", 2},
224        {"\x0C\x00\x00\x00\x00\x00\x00\x00", 2},
225        {"\x0D\x00\x00\x00\x00\x00\x00\x00", 2},
226        {"\x0E\x00\x00\x00\x00\x00\x00\x00", 2},
227        {"\x0F\x00\x00\x00\x00\x00\x00\x00", 2},
228        {"\x10\x00\x00\x00\x00\x00\x00\x00", 2},
229        {"\x20\x00\x00\x00\x00\x00\x00\x00", 2},
230        {"\x40\x00\x00\x00\x00\x00\x00\x00", 2},
231        {"\x7E\x00\x00\x00\x00\x00\x00\x00", 2},
232        {"\x7F\x00\x00\x00\x00\x00\x00\x00", 2},
233        {"\x80\x00\x00\x00\x00\x00\x00\x00", 2},
234        {"\x81\x00\x00\x00\x00\x00\x00\x00", 2},
235        {"\xC0\x00\x00\x00\x00\x00\x00\x00", 2},
236        {"\xFE\x00\x00\x00\x00\x00\x00\x00", 2},
237        {"\xFF\x00\x00\x00\x00\x00\x00\x00", 2},
238        {"\xFF\x7E\x00\x00\x00\x00\x00\x00", 2},
239        {"\xFF\x7F\x00\x00\x00\x00\x00\x00", 2},
240        {"\x00\x80\x00\x00\x00\x00\x00\x00", 2},
241        {"\x01\x80\x00\x00\x00\x00\x00\x00", 2},
242        {"\xFE\xFF\x00\x00\x00\x00\x00\x00", 2},
243        /* 4B - NE */
244        {"\x00\x00\x00\x00\x00\x00\x00\x00", 4},
245        {"\x01\x01\x01\x01\x00\x00\x00\x00", 4},
246        {"\x80\x80\x80\x80\x00\x00\x00\x00", 4},
247        {"\xFF\xFF\xFF\xFF\x00\x00\x00\x00", 4},
248        /* 4B - BE */
249        {"\x00\x00\x00\x01\x00\x00\x00\x00", 4},
250        {"\x00\x00\x00\x02\x00\x00\x00\x00", 4},
251        {"\x00\x00\x00\x03\x00\x00\x00\x00", 4},
252        {"\x00\x00\x00\x04\x00\x00\x00\x00", 4},
253        {"\x00\x00\x00\x05\x00\x00\x00\x00", 4},
254        {"\x00\x00\x00\x06\x00\x00\x00\x00", 4},
255        {"\x00\x00\x00\x07\x00\x00\x00\x00", 4},
256        {"\x00\x00\x00\x08\x00\x00\x00\x00", 4},
257        {"\x00\x00\x00\x09\x00\x00\x00\x00", 4},
258        {"\x00\x00\x00\x0A\x00\x00\x00\x00", 4},
259        {"\x00\x00\x00\x0B\x00\x00\x00\x00", 4},
260        {"\x00\x00\x00\x0C\x00\x00\x00\x00", 4},
261        {"\x00\x00\x00\x0D\x00\x00\x00\x00", 4},
262        {"\x00\x00\x00\x0E\x00\x00\x00\x00", 4},
263        {"\x00\x00\x00\x0F\x00\x00\x00\x00", 4},
264        {"\x00\x00\x00\x10\x00\x00\x00\x00", 4},
265        {"\x00\x00\x00\x20\x00\x00\x00\x00", 4},
266        {"\x00\x00\x00\x40\x00\x00\x00\x00", 4},
267        {"\x00\x00\x00\x7E\x00\x00\x00\x00", 4},
268        {"\x00\x00\x00\x7F\x00\x00\x00\x00", 4},
269        {"\x00\x00\x00\x80\x00\x00\x00\x00", 4},
270        {"\x00\x00\x00\x81\x00\x00\x00\x00", 4},
271        {"\x00\x00\x00\xC0\x00\x00\x00\x00", 4},
272        {"\x00\x00\x00\xFE\x00\x00\x00\x00", 4},
273        {"\x00\x00\x00\xFF\x00\x00\x00\x00", 4},
274        {"\x7E\xFF\xFF\xFF\x00\x00\x00\x00", 4},
275        {"\x7F\xFF\xFF\xFF\x00\x00\x00\x00", 4},
276        {"\x80\x00\x00\x00\x00\x00\x00\x00", 4},
277        {"\x80\x00\x00\x01\x00\x00\x00\x00", 4},
278        {"\xFF\xFF\xFF\xFE\x00\x00\x00\x00", 4},
279        /* 4B - LE */
280        {"\x00\x00\x00\x00\x00\x00\x00\x00", 4},
281        {"\x01\x00\x00\x00\x00\x00\x00\x00", 4},
282        {"\x02\x00\x00\x00\x00\x00\x00\x00", 4},
283        {"\x03\x00\x00\x00\x00\x00\x00\x00", 4},
284        {"\x04\x00\x00\x00\x00\x00\x00\x00", 4},
285        {"\x05\x00\x00\x00\x00\x00\x00\x00", 4},
286        {"\x06\x00\x00\x00\x00\x00\x00\x00", 4},
287        {"\x07\x00\x00\x00\x00\x00\x00\x00", 4},
288        {"\x08\x00\x00\x00\x00\x00\x00\x00", 4},
289        {"\x09\x00\x00\x00\x00\x00\x00\x00", 4},
290        {"\x0A\x00\x00\x00\x00\x00\x00\x00", 4},
291        {"\x0B\x00\x00\x00\x00\x00\x00\x00", 4},
292        {"\x0C\x00\x00\x00\x00\x00\x00\x00", 4},
293        {"\x0D\x00\x00\x00\x00\x00\x00\x00", 4},
294        {"\x0E\x00\x00\x00\x00\x00\x00\x00", 4},
295        {"\x0F\x00\x00\x00\x00\x00\x00\x00", 4},
296        {"\x10\x00\x00\x00\x00\x00\x00\x00", 4},
297        {"\x20\x00\x00\x00\x00\x00\x00\x00", 4},
298        {"\x40\x00\x00\x00\x00\x00\x00\x00", 4},
299        {"\x7E\x00\x00\x00\x00\x00\x00\x00", 4},
300        {"\x7F\x00\x00\x00\x00\x00\x00\x00", 4},
301        {"\x80\x00\x00\x00\x00\x00\x00\x00", 4},
302        {"\x81\x00\x00\x00\x00\x00\x00\x00", 4},
303        {"\xC0\x00\x00\x00\x00\x00\x00\x00", 4},
304        {"\xFE\x00\x00\x00\x00\x00\x00\x00", 4},
305        {"\xFF\x00\x00\x00\x00\x00\x00\x00", 4},
306        {"\xFF\xFF\xFF\x7E\x00\x00\x00\x00", 4},
307        {"\xFF\xFF\xFF\x7F\x00\x00\x00\x00", 4},
308        {"\x00\x00\x00\x80\x00\x00\x00\x00", 4},
309        {"\x01\x00\x00\x80\x00\x00\x00\x00", 4},
310        {"\xFE\xFF\xFF\xFF\x00\x00\x00\x00", 4},
311        /* 8B - NE */
312        {"\x00\x00\x00\x00\x00\x00\x00\x00", 8},
313        {"\x01\x01\x01\x01\x01\x01\x01\x01", 8},
314        {"\x80\x80\x80\x80\x80\x80\x80\x80", 8},
315        {"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8},
316        /* 8B - BE */
317        {"\x00\x00\x00\x00\x00\x00\x00\x01", 8},
318        {"\x00\x00\x00\x00\x00\x00\x00\x02", 8},
319        {"\x00\x00\x00\x00\x00\x00\x00\x03", 8},
320        {"\x00\x00\x00\x00\x00\x00\x00\x04", 8},
321        {"\x00\x00\x00\x00\x00\x00\x00\x05", 8},
322        {"\x00\x00\x00\x00\x00\x00\x00\x06", 8},
323        {"\x00\x00\x00\x00\x00\x00\x00\x07", 8},
324        {"\x00\x00\x00\x00\x00\x00\x00\x08", 8},
325        {"\x00\x00\x00\x00\x00\x00\x00\x09", 8},
326        {"\x00\x00\x00\x00\x00\x00\x00\x0A", 8},
327        {"\x00\x00\x00\x00\x00\x00\x00\x0B", 8},
328        {"\x00\x00\x00\x00\x00\x00\x00\x0C", 8},
329        {"\x00\x00\x00\x00\x00\x00\x00\x0D", 8},
330        {"\x00\x00\x00\x00\x00\x00\x00\x0E", 8},
331        {"\x00\x00\x00\x00\x00\x00\x00\x0F", 8},
332        {"\x00\x00\x00\x00\x00\x00\x00\x10", 8},
333        {"\x00\x00\x00\x00\x00\x00\x00\x20", 8},
334        {"\x00\x00\x00\x00\x00\x00\x00\x40", 8},
335        {"\x00\x00\x00\x00\x00\x00\x00\x7E", 8},
336        {"\x00\x00\x00\x00\x00\x00\x00\x7F", 8},
337        {"\x00\x00\x00\x00\x00\x00\x00\x80", 8},
338        {"\x00\x00\x00\x00\x00\x00\x00\x81", 8},
339        {"\x00\x00\x00\x00\x00\x00\x00\xC0", 8},
340        {"\x00\x00\x00\x00\x00\x00\x00\xFE", 8},
341        {"\x00\x00\x00\x00\x00\x00\x00\xFF", 8},
342        {"\x7E\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8},
343        {"\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8},
344        {"\x80\x00\x00\x00\x00\x00\x00\x00", 8},
345        {"\x80\x00\x00\x00\x00\x00\x00\x01", 8},
346        {"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE", 8},
347        /* 8B - LE */
348        {"\x00\x00\x00\x00\x00\x00\x00\x00", 8},
349        {"\x01\x00\x00\x00\x00\x00\x00\x00", 8},
350        {"\x02\x00\x00\x00\x00\x00\x00\x00", 8},
351        {"\x03\x00\x00\x00\x00\x00\x00\x00", 8},
352        {"\x04\x00\x00\x00\x00\x00\x00\x00", 8},
353        {"\x05\x00\x00\x00\x00\x00\x00\x00", 8},
354        {"\x06\x00\x00\x00\x00\x00\x00\x00", 8},
355        {"\x07\x00\x00\x00\x00\x00\x00\x00", 8},
356        {"\x08\x00\x00\x00\x00\x00\x00\x00", 8},
357        {"\x09\x00\x00\x00\x00\x00\x00\x00", 8},
358        {"\x0A\x00\x00\x00\x00\x00\x00\x00", 8},
359        {"\x0B\x00\x00\x00\x00\x00\x00\x00", 8},
360        {"\x0C\x00\x00\x00\x00\x00\x00\x00", 8},
361        {"\x0D\x00\x00\x00\x00\x00\x00\x00", 8},
362        {"\x0E\x00\x00\x00\x00\x00\x00\x00", 8},
363        {"\x0F\x00\x00\x00\x00\x00\x00\x00", 8},
364        {"\x10\x00\x00\x00\x00\x00\x00\x00", 8},
365        {"\x20\x00\x00\x00\x00\x00\x00\x00", 8},
366        {"\x40\x00\x00\x00\x00\x00\x00\x00", 8},
367        {"\x7E\x00\x00\x00\x00\x00\x00\x00", 8},
368        {"\x7F\x00\x00\x00\x00\x00\x00\x00", 8},
369        {"\x80\x00\x00\x00\x00\x00\x00\x00", 8},
370        {"\x81\x00\x00\x00\x00\x00\x00\x00", 8},
371        {"\xC0\x00\x00\x00\x00\x00\x00\x00", 8},
372        {"\xFE\x00\x00\x00\x00\x00\x00\x00", 8},
373        {"\xFF\x00\x00\x00\x00\x00\x00\x00", 8},
374        {"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7E", 8},
375        {"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F", 8},
376        {"\x00\x00\x00\x00\x00\x00\x00\x80", 8},
377        {"\x01\x00\x00\x00\x00\x00\x00\x80", 8},
378        {"\xFE\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8},
379    };
380
381    size_t off = util_rndGet(0, run->dynamicFileSz - 1);
382    uint64_t choice = util_rndGet(0, ARRAYSIZE(mangleMagicVals) - 1);
383    mangle_Overwrite(run, mangleMagicVals[choice].val, off, mangleMagicVals[choice].size);
384}
385
386static void mangle_MemSet(run_t* run) {
387    size_t off = util_rndGet(0, run->dynamicFileSz - 1);
388    size_t sz = util_rndGet(1, run->dynamicFileSz - off);
389    int val = (int)util_rndGet(0, UINT8_MAX);
390
391    memset(&run->dynamicFile[off], val, sz);
392}
393
394static void mangle_Random(run_t* run) {
395    size_t off = util_rndGet(0, run->dynamicFileSz - 1);
396    size_t len = util_rndGet(1, run->dynamicFileSz - off);
397    util_rndBuf(&run->dynamicFile[off], len);
398}
399
400static void mangle_AddSub(run_t* run) {
401    size_t off = util_rndGet(0, run->dynamicFileSz - 1);
402
403    /* 1,2,4,8 */
404    uint64_t varLen = 1U << util_rndGet(0, 3);
405    if ((run->dynamicFileSz - off) < varLen) {
406        varLen = 1;
407    }
408
409    int delta = (int)util_rndGet(0, 8192);
410    delta -= 4096;
411
412    switch (varLen) {
413        case 1: {
414            run->dynamicFile[off] += delta;
415            return;
416            break;
417        }
418        case 2: {
419            int16_t val;
420            memcpy(&val, &run->dynamicFile[off], sizeof(val));
421            if (util_rnd64() & 0x1) {
422                val += delta;
423            } else {
424                /* Foreign endianess */
425                val = __builtin_bswap16(val);
426                val += delta;
427                val = __builtin_bswap16(val);
428            }
429            mangle_Overwrite(run, (uint8_t*)&val, off, varLen);
430            return;
431            break;
432        }
433        case 4: {
434            int32_t val;
435            memcpy(&val, &run->dynamicFile[off], sizeof(val));
436            if (util_rnd64() & 0x1) {
437                val += delta;
438            } else {
439                /* Foreign endianess */
440                val = __builtin_bswap32(val);
441                val += delta;
442                val = __builtin_bswap32(val);
443            }
444            mangle_Overwrite(run, (uint8_t*)&val, off, varLen);
445            return;
446            break;
447        }
448        case 8: {
449            int64_t val;
450            memcpy(&val, &run->dynamicFile[off], sizeof(val));
451            if (util_rnd64() & 0x1) {
452                val += delta;
453            } else {
454                /* Foreign endianess */
455                val = __builtin_bswap64(val);
456                val += delta;
457                val = __builtin_bswap64(val);
458            }
459            mangle_Overwrite(run, (uint8_t*)&val, off, varLen);
460            return;
461            break;
462        }
463        default: {
464            LOG_F("Unknown variable length size: %" PRIu64, varLen);
465            break;
466        }
467    }
468}
469
470static void mangle_IncByte(run_t* run) {
471    size_t off = util_rndGet(0, run->dynamicFileSz - 1);
472    run->dynamicFile[off] += (uint8_t)1UL;
473}
474
475static void mangle_DecByte(run_t* run) {
476    size_t off = util_rndGet(0, run->dynamicFileSz - 1);
477    run->dynamicFile[off] -= (uint8_t)1UL;
478}
479
480static void mangle_NegByte(run_t* run) {
481    size_t off = util_rndGet(0, run->dynamicFileSz - 1);
482    run->dynamicFile[off] = ~(run->dynamicFile[off]);
483}
484
485static void mangle_CloneByte(run_t* run) {
486    size_t off1 = util_rndGet(0, run->dynamicFileSz - 1);
487    size_t off2 = util_rndGet(0, run->dynamicFileSz - 1);
488
489    uint8_t tmp = run->dynamicFile[off1];
490    run->dynamicFile[off1] = run->dynamicFile[off2];
491    run->dynamicFile[off2] = tmp;
492}
493
494static void mangle_Resize(run_t* run) {
495    run->dynamicFileSz = util_rndGet(0, run->global->maxFileSz);
496}
497
498static void mangle_Expand(run_t* run) {
499    size_t off = util_rndGet(0, run->dynamicFileSz - 1);
500    size_t len = util_rndGet(1, run->dynamicFileSz - off);
501
502    mangle_Inflate(run, off, len);
503    mangle_Move(run, off, off + len, run->dynamicFileSz);
504}
505
506static void mangle_Shrink(run_t* run) {
507    if (run->dynamicFileSz <= 1U) {
508        return;
509    }
510
511    size_t len = util_rndGet(1, run->dynamicFileSz - 1);
512    size_t off = util_rndGet(0, len);
513
514    mangle_Move(run, off + len, off, run->dynamicFileSz);
515    run->dynamicFileSz -= len;
516}
517
518static void mangle_InsertRnd(run_t* run) {
519    size_t off = util_rndGet(0, run->dynamicFileSz - 1);
520    size_t len = util_rndGet(1, run->dynamicFileSz - off);
521
522    mangle_Inflate(run, off, len);
523    mangle_Move(run, off, off + len, run->dynamicFileSz);
524    util_rndBuf(&run->dynamicFile[off], len);
525}
526
527static void mangle_ASCIIVal(run_t* run) {
528    char buf[32];
529    snprintf(buf, sizeof(buf), "%" PRId64, (int64_t)util_rnd64());
530    size_t off = util_rndGet(0, run->dynamicFileSz - 1);
531
532    mangle_Overwrite(run, (uint8_t*)buf, off, strlen(buf));
533}
534
535void mangle_mangleContent(run_t* run) {
536    if (run->mutationsPerRun == 0U) {
537        return;
538    }
539
540    /* 20% chance to change the file size */
541    if ((util_rnd64() % 5) == 0) {
542        mangle_Resize(run);
543    }
544
545    /* No point in modifying it if its size is 0 */
546    if (run->dynamicFileSz == 0UL) {
547        return;
548    }
549
550    static void (*const mangleFuncs[])(run_t * run) = {
551        mangle_Byte,
552        mangle_Bit,
553        mangle_Bytes,
554        mangle_Magic,
555        mangle_IncByte,
556        mangle_DecByte,
557        mangle_NegByte,
558        mangle_AddSub,
559        mangle_Dictionary,
560        mangle_DictionaryInsert,
561        mangle_MemMove,
562        mangle_MemSet,
563        mangle_Random,
564        mangle_CloneByte,
565        mangle_Expand,
566        mangle_Shrink,
567        mangle_InsertRnd,
568        mangle_ASCIIVal,
569    };
570
571    /* Max number of stacked changes is 6 */
572    uint64_t changesCnt = util_rndGet(1, run->global->mutationsPerRun);
573
574    for (uint64_t x = 0; x < changesCnt; x++) {
575        uint64_t choice = util_rndGet(0, ARRAYSIZE(mangleFuncs) - 1);
576        mangleFuncs[choice](run);
577    }
578}
579