Coverage Report

Created: 2026-03-31 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/open62541/tests/fuzz/fuzz_binary_decode.cc
Line
Count
Source
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.58k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
19
3.58k
    if(size <= 6)
20
4
        return 0;
21
22
    // set the available memory
23
3.58k
    if(!UA_memoryManager_setLimitFromLast4Bytes(data, size))
24
0
        return 0;
25
26
3.58k
    data += 4;
27
3.58k
    size -= 4;
28
29
    // get some random type
30
3.58k
    uint16_t typeIndex = (uint16_t)(data[0] | data[1] << 8);
31
3.58k
    data += 2;
32
3.58k
    size -= 2;
33
34
3.58k
    if(typeIndex >= UA_TYPES_COUNT)
35
12
        return UA_FALSE;
36
37
3.57k
    void *dst = UA_new(&UA_TYPES[typeIndex]);
38
3.57k
    if(!dst)
39
12
        return 0;
40
41
3.56k
    const UA_ByteString binary = {
42
3.56k
            size, //length
43
3.56k
            (UA_Byte *) (void *) data
44
3.56k
    };
45
46
3.56k
    UA_StatusCode ret = UA_decodeBinary(&binary, dst, &UA_TYPES[typeIndex], NULL);
47
3.56k
    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.83k
    void *dstCopy = UA_new(&UA_TYPES[typeIndex]);
54
1.83k
    if(!dstCopy) {
55
3
        UA_delete(dst, &UA_TYPES[typeIndex]);
56
3
        return 0;
57
3
    }
58
1.83k
    ret = UA_copy(dst, dstCopy, &UA_TYPES[typeIndex]);
59
1.83k
    if(ret != UA_STATUSCODE_GOOD) {
60
177
        UA_delete(dst, &UA_TYPES[typeIndex]);
61
177
        UA_delete(dstCopy, &UA_TYPES[typeIndex]);
62
177
        return 0;
63
177
    }
64
    
65
    // compare with copy
66
1.65k
    UA_assert(UA_order(dst, dstCopy, &UA_TYPES[typeIndex]) == UA_ORDER_EQ);
67
1.65k
    UA_delete(dstCopy, &UA_TYPES[typeIndex]);
68
    
69
    // now also test encoding
70
1.65k
    size_t encSize = UA_calcSizeBinary(dst, &UA_TYPES[typeIndex], NULL);
71
1.65k
    UA_ByteString encoded;
72
1.65k
    ret = UA_ByteString_allocBuffer(&encoded, encSize);
73
1.65k
    if(ret != UA_STATUSCODE_GOOD) {
74
0
        UA_delete(dst, &UA_TYPES[typeIndex]);
75
0
        return 0;
76
0
    }
77
78
1.65k
    ret = UA_encodeBinary(dst, &UA_TYPES[typeIndex], &encoded, NULL);
79
1.65k
    UA_assert(ret == UA_STATUSCODE_GOOD);
80
81
1.65k
    UA_ByteString_clear(&encoded);
82
1.65k
    UA_delete(dst, &UA_TYPES[typeIndex]);
83
1.65k
    return 0;
84
1.65k
}