File: fuzzer_scalar.cpp

package info (click to toggle)
libdivide 5.2.0-0.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 17,564 kB
  • sloc: ansic: 131,647; cpp: 70,136; python: 47; makefile: 3
file content (70 lines) | stat: -rw-r--r-- 1,745 bytes parent folder | download
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
#include <cstdint>
#include <cstring>
#include <limits>

#include "libdivide.h"

constexpr const std::size_t Nmax = 8;

template <typename Integer>
void applyOnScalars(const uint8_t* Data, size_t Size) {
    const auto N = sizeof(Integer);
    static_assert(N <= Nmax, "");
    if (Size < 2 * Nmax) return;

    Integer numerator, divisor;
    std::memcpy(&numerator, Data, N);
    Data += Nmax;
    std::memcpy(&divisor, Data, N);

    // avoid division by zero
    if (divisor == 0) {
        return;
    }

    // avoid signed integer overflow INT_MIN/-1
    if (std::is_signed_v<Integer> &&
        (numerator == std::numeric_limits<Integer>::min() && divisor == -1)) {
        return;
    }

    libdivide::divider<Integer, libdivide::BRANCHFULL> fast_d_branchfull(divisor);
    const auto quotient_full = numerator / fast_d_branchfull;

    if (quotient_full != numerator / divisor) {
        abort();
    }

    if (divisor != 1) {
        libdivide::divider<Integer, libdivide::BRANCHFREE> fast_d_branchfree(divisor);

        const auto quotient_free = numerator / fast_d_branchfree;

        if (quotient_free != numerator / divisor) {
            abort();
        }
    }
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
    if (Size < Nmax) return 0;
    auto action = Data[0];
    ++Data;
    --Size;

    switch (action) {
        case 0: {
            applyOnScalars<std::int64_t>(Data, Size);
        } break;
        case 1: {
            applyOnScalars<std::int32_t>(Data, Size);
        } break;
        case 2: {
            applyOnScalars<std::uint64_t>(Data, Size);
        } break;
        case 3: {
            applyOnScalars<std::uint32_t>(Data, Size);
        } break;
    }
    return 0;
}