Coverage Report

Created: 2025-07-01 07:01

/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
}