/src/open62541/tests/fuzz/fuzz_binary_decode.cc
Line | Count | Source (jump to first uncovered line) |
1 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
2 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
3 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
4 | | * |
5 | | * Copyright 2019 (c) fortiss (Author: Stefan Profanter) |
6 | | */ |
7 | | |
8 | | #include "custom_memory_manager.h" |
9 | | |
10 | | #include <open62541/plugin/log_stdout.h> |
11 | | #include <open62541/server_config_default.h> |
12 | | #include <open62541/types.h> |
13 | | |
14 | | /* |
15 | | ** Main entry point. The fuzzer invokes this function with each |
16 | | ** fuzzed input. |
17 | | */ |
18 | 3.63k | extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
19 | 3.63k | if(size <= 6) |
20 | 4 | return 0; |
21 | | |
22 | | // set the available memory |
23 | 3.62k | if(!UA_memoryManager_setLimitFromLast4Bytes(data, size)) |
24 | 0 | return 0; |
25 | | |
26 | 3.62k | data += 4; |
27 | 3.62k | size -= 4; |
28 | | |
29 | | // get some random type |
30 | 3.62k | uint16_t typeIndex = (uint16_t)(data[0] | data[1] << 8); |
31 | 3.62k | data += 2; |
32 | 3.62k | size -= 2; |
33 | | |
34 | 3.62k | if(typeIndex >= UA_TYPES_COUNT) |
35 | 16 | return UA_FALSE; |
36 | | |
37 | 3.61k | void *dst = UA_new(&UA_TYPES[typeIndex]); |
38 | 3.61k | if(!dst) |
39 | 15 | return 0; |
40 | | |
41 | 3.59k | const UA_ByteString binary = { |
42 | 3.59k | size, //length |
43 | 3.59k | (UA_Byte *) (void *) data |
44 | 3.59k | }; |
45 | | |
46 | 3.59k | UA_StatusCode ret = UA_decodeBinary(&binary, dst, &UA_TYPES[typeIndex], NULL); |
47 | 3.59k | if(ret != UA_STATUSCODE_GOOD) { |
48 | 1.72k | UA_delete(dst, &UA_TYPES[typeIndex]); |
49 | 1.72k | return 0; |
50 | 1.72k | } |
51 | | |
52 | | // copy the datatype to test |
53 | 1.87k | void *dstCopy = UA_new(&UA_TYPES[typeIndex]); |
54 | 1.87k | if(!dstCopy) { |
55 | 5 | UA_delete(dst, &UA_TYPES[typeIndex]); |
56 | 5 | return 0; |
57 | 5 | } |
58 | 1.86k | ret = UA_copy(dst, dstCopy, &UA_TYPES[typeIndex]); |
59 | 1.86k | if(ret != UA_STATUSCODE_GOOD) { |
60 | 158 | UA_delete(dst, &UA_TYPES[typeIndex]); |
61 | 158 | UA_delete(dstCopy, &UA_TYPES[typeIndex]); |
62 | 158 | return 0; |
63 | 158 | } |
64 | | |
65 | | // compare with copy |
66 | 1.71k | UA_assert(UA_order(dst, dstCopy, &UA_TYPES[typeIndex]) == UA_ORDER_EQ); |
67 | 1.71k | UA_delete(dstCopy, &UA_TYPES[typeIndex]); |
68 | | |
69 | | // now also test encoding |
70 | 1.71k | size_t encSize = UA_calcSizeBinary(dst, &UA_TYPES[typeIndex], NULL); |
71 | 1.71k | UA_ByteString encoded; |
72 | 1.71k | ret = UA_ByteString_allocBuffer(&encoded, encSize); |
73 | 1.71k | if(ret != UA_STATUSCODE_GOOD) { |
74 | 0 | UA_delete(dst, &UA_TYPES[typeIndex]); |
75 | 0 | return 0; |
76 | 0 | } |
77 | | |
78 | 1.71k | ret = UA_encodeBinary(dst, &UA_TYPES[typeIndex], &encoded, NULL); |
79 | 1.71k | UA_assert(ret == UA_STATUSCODE_GOOD); |
80 | | |
81 | 1.71k | UA_ByteString_clear(&encoded); |
82 | 1.71k | UA_delete(dst, &UA_TYPES[typeIndex]); |
83 | 1.71k | return 0; |
84 | 1.71k | } |