UA_readNumberWithBase:
  122|    593|                      UA_UInt32 *number, UA_Byte base) {
  123|    593|    UA_assert(buf);
  ------------------
  |  |  248|    593|# define UA_assert(ignore) assert(ignore)
  ------------------
  |  Branch (123:5): [True: 593, False: 0]
  ------------------
  124|    593|    UA_assert(number);
  ------------------
  |  |  248|    593|# define UA_assert(ignore) assert(ignore)
  ------------------
  |  Branch (124:5): [True: 593, False: 0]
  ------------------
  125|       |    /* Accumulate in 64 bits. n stays below 2^32 between the digits, so n * base
  126|       |     * + digit cannot overflow for any base up to 36. */
  127|    593|    u64 n = 0;
  128|    593|    size_t progress = 0;
  129|       |    /* read numbers until the end or a non-number character appears */
  130|   943k|    while(progress < buflen) {
  ------------------
  |  Branch (130:11): [True: 942k, False: 275]
  ------------------
  131|   942k|        u8 c = buf[progress];
  132|   942k|        u32 digit;
  133|   942k|        if(c >= '0' && c <= '9' && c <= '0' + (base-1))
  ------------------
  |  Branch (133:12): [True: 942k, False: 205]
  |  Branch (133:24): [True: 942k, False: 96]
  |  Branch (133:36): [True: 942k, False: 0]
  ------------------
  134|   942k|           digit = c - '0';
  135|    301|        else if(base > 9 && c >= 'a' && c <= 'z' && c <= 'a' + (base-11))
  ------------------
  |  Branch (135:17): [True: 301, False: 0]
  |  Branch (135:29): [True: 70, False: 231]
  |  Branch (135:41): [True: 21, False: 49]
  |  Branch (135:53): [True: 0, False: 21]
  ------------------
  136|      0|           digit = c-'a' + 10;
  137|    301|        else if(base > 9 && c >= 'A' && c <= 'Z' && c <= 'A' + (base-11))
  ------------------
  |  Branch (137:17): [True: 301, False: 0]
  |  Branch (137:29): [True: 85, False: 216]
  |  Branch (137:41): [True: 11, False: 74]
  |  Branch (137:53): [True: 0, False: 11]
  ------------------
  138|      0|           digit = c-'A' + 10;
  139|    301|        else
  140|    301|           break;
  141|   942k|        n = (n * base) + digit;
  142|       |        /* The number does not fit into 32 bits. Report no valid digits
  143|       |         * instead of returning a wrapped value. */
  144|   942k|        if(n > UA_UINT32_MAX)
  ------------------
  |  |  110|   942k|#define UA_UINT32_MAX 4294967295UL
  ------------------
  |  Branch (144:12): [True: 17, False: 942k]
  ------------------
  145|     17|            return 0;
  146|   942k|        ++progress;
  147|   942k|    }
  148|    576|    *number = (u32)n;
  149|    576|    return progress;
  150|    593|}
UA_readNumber:
  153|    593|UA_readNumber(const UA_Byte *buf, size_t buflen, UA_UInt32 *number) {
  154|    593|    return UA_readNumberWithBase(buf, buflen, number, 10);
  155|    593|}
UA_parseEndpointUrl:
  167|    535|                    UA_UInt16 *outPort, UA_String *outPath) {
  168|    535|    if(!endpointUrl || !endpointUrl->data)
  ------------------
  |  Branch (168:8): [True: 0, False: 535]
  |  Branch (168:24): [True: 0, False: 535]
  ------------------
  169|      0|        return UA_STATUSCODE_BADTCPENDPOINTURLINVALID;
  ------------------
  |  |  500|      0|#define UA_STATUSCODE_BADTCPENDPOINTURLINVALID ((UA_StatusCode) 0x80830000)
  ------------------
  170|       |
  171|       |    /* Which type of schema is this? */
  172|    535|    unsigned schemaType = 0;
  173|    535|    size_t schemaLen = 0;
  174|  3.36k|    for(; schemaType < UA_SCHEMAS_SIZE; schemaType++) {
  ------------------
  |  |  157|  3.36k|#define UA_SCHEMAS_SIZE 8
  ------------------
  |  Branch (174:11): [True: 3.25k, False: 114]
  ------------------
  175|  3.25k|        schemaLen = strlen(schemas[schemaType]);
  176|  3.25k|        if(endpointUrl->length >= schemaLen &&
  ------------------
  |  Branch (176:12): [True: 2.61k, False: 643]
  ------------------
  177|  2.61k|           strncmp((char*)endpointUrl->data, schemas[schemaType], schemaLen) == 0)
  ------------------
  |  Branch (177:12): [True: 421, False: 2.19k]
  ------------------
  178|    421|            break;
  179|  3.25k|    }
  180|    535|    if(schemaType == UA_SCHEMAS_SIZE)
  ------------------
  |  |  157|    535|#define UA_SCHEMAS_SIZE 8
  ------------------
  |  Branch (180:8): [True: 114, False: 421]
  ------------------
  181|    114|        return UA_STATUSCODE_BADTCPENDPOINTURLINVALID;
  ------------------
  |  |  500|    114|#define UA_STATUSCODE_BADTCPENDPOINTURLINVALID ((UA_StatusCode) 0x80830000)
  ------------------
  182|       |
  183|       |    /* Forward the current position until the first colon or slash */
  184|    421|    size_t start = strlen(schemas[schemaType]);
  185|    421|    size_t curr = start;
  186|    421|    UA_Boolean ipv6 = false;
  187|    421|    if(endpointUrl->length > curr && endpointUrl->data[curr] == '[') {
  ------------------
  |  Branch (187:8): [True: 414, False: 7]
  |  Branch (187:38): [True: 129, False: 285]
  ------------------
  188|       |        /* IPv6: opc.tcp://[2001:0db8:85a3::8a2e:0370:7334]:1234/path */
  189|  9.21M|        for(; curr < endpointUrl->length; ++curr) {
  ------------------
  |  Branch (189:15): [True: 9.21M, False: 18]
  ------------------
  190|  9.21M|            if(endpointUrl->data[curr] == ']')
  ------------------
  |  Branch (190:16): [True: 111, False: 9.20M]
  ------------------
  191|    111|                break;
  192|  9.21M|        }
  193|    129|        if(curr == endpointUrl->length)
  ------------------
  |  Branch (193:12): [True: 18, False: 111]
  ------------------
  194|     18|            return UA_STATUSCODE_BADTCPENDPOINTURLINVALID;
  ------------------
  |  |  500|     18|#define UA_STATUSCODE_BADTCPENDPOINTURLINVALID ((UA_StatusCode) 0x80830000)
  ------------------
  195|    111|        curr++;
  196|    111|        ipv6 = true;
  197|    292|    } else {
  198|       |        /* IPv4 or hostname: opc.tcp://something.something:1234/path */
  199|  1.29M|        for(; curr < endpointUrl->length; ++curr) {
  ------------------
  |  Branch (199:15): [True: 1.29M, False: 57]
  ------------------
  200|  1.29M|            if(endpointUrl->data[curr] == ':' || endpointUrl->data[curr] == '/')
  ------------------
  |  Branch (200:16): [True: 189, False: 1.29M]
  |  Branch (200:50): [True: 46, False: 1.29M]
  ------------------
  201|    235|                break;
  202|  1.29M|        }
  203|    292|    }
  204|       |
  205|       |    /* Set the hostname */
  206|    403|    if(ipv6) {
  ------------------
  |  Branch (206:8): [True: 111, False: 292]
  ------------------
  207|       |        /* Skip the ipv6 '[]' container for getaddrinfo() later */
  208|    111|        outHostname->data = &endpointUrl->data[start+1];
  209|    111|        outHostname->length = curr - (start+2);
  210|    292|    } else {
  211|    292|        outHostname->data = &endpointUrl->data[start];
  212|    292|        outHostname->length = curr - start;
  213|    292|    }
  214|       |
  215|       |    /* Empty string? */
  216|    403|    if(outHostname->length == 0)
  ------------------
  |  Branch (216:8): [True: 213, False: 190]
  ------------------
  217|    213|        outHostname->data = NULL;
  218|       |
  219|       |    /* Already at the end */
  220|    403|    if(curr == endpointUrl->length) {
  ------------------
  |  Branch (220:8): [True: 102, False: 301]
  ------------------
  221|    102|        if(outHostname->length == 0)
  ------------------
  |  Branch (221:12): [True: 8, False: 94]
  ------------------
  222|      8|            return UA_STATUSCODE_BADTCPENDPOINTURLINVALID;
  ------------------
  |  |  500|      8|#define UA_STATUSCODE_BADTCPENDPOINTURLINVALID ((UA_StatusCode) 0x80830000)
  ------------------
  223|     94|        return UA_STATUSCODE_GOOD;
  ------------------
  |  |   17|     94|#define UA_STATUSCODE_GOOD ((UA_StatusCode) 0x00000000)
  ------------------
  224|    102|    }
  225|       |
  226|       |    /* Set the port - and for ETH set the VID.PCP postfix in the outpath string.
  227|       |     * We have to parse that externally. */
  228|    301|    if(endpointUrl->data[curr] == ':') {
  ------------------
  |  Branch (228:8): [True: 225, False: 76]
  ------------------
  229|    225|        if(++curr == endpointUrl->length)
  ------------------
  |  Branch (229:12): [True: 1, False: 224]
  ------------------
  230|      1|            return UA_STATUSCODE_BADTCPENDPOINTURLINVALID;
  ------------------
  |  |  500|      1|#define UA_STATUSCODE_BADTCPENDPOINTURLINVALID ((UA_StatusCode) 0x80830000)
  ------------------
  231|       |
  232|       |        /* ETH schema */
  233|    224|        if(schemaType == UA_ETH_SCHEMA_INDEX) {
  ------------------
  |  |  158|    224|#define UA_ETH_SCHEMA_INDEX 2
  ------------------
  |  Branch (233:12): [True: 1, False: 223]
  ------------------
  234|      1|            if(outPath != NULL) {
  ------------------
  |  Branch (234:16): [True: 1, False: 0]
  ------------------
  235|      1|                outPath->data = &endpointUrl->data[curr];
  236|      1|                outPath->length = endpointUrl->length - curr;
  237|      1|            }
  238|      1|            return UA_STATUSCODE_GOOD;
  ------------------
  |  |   17|      1|#define UA_STATUSCODE_GOOD ((UA_StatusCode) 0x00000000)
  ------------------
  239|      1|        }
  240|       |
  241|    223|        u32 largeNum;
  242|    223|        size_t progress = UA_readNumber(&endpointUrl->data[curr],
  243|    223|                                        endpointUrl->length - curr, &largeNum);
  244|    223|        if(progress == 0 || largeNum > 65535)
  ------------------
  |  Branch (244:12): [True: 54, False: 169]
  |  Branch (244:29): [True: 57, False: 112]
  ------------------
  245|    111|            return UA_STATUSCODE_BADTCPENDPOINTURLINVALID;
  ------------------
  |  |  500|    111|#define UA_STATUSCODE_BADTCPENDPOINTURLINVALID ((UA_StatusCode) 0x80830000)
  ------------------
  246|       |        /* Test if the end of a valid port was reached */
  247|    112|        curr += progress;
  248|    112|        if(curr == endpointUrl->length || endpointUrl->data[curr] == '/')
  ------------------
  |  Branch (248:12): [True: 53, False: 59]
  |  Branch (248:43): [True: 19, False: 40]
  ------------------
  249|     72|            *outPort = (u16)largeNum;
  250|    112|        if(curr == endpointUrl->length)
  ------------------
  |  Branch (250:12): [True: 53, False: 59]
  ------------------
  251|     53|            return UA_STATUSCODE_GOOD;
  ------------------
  |  |   17|     53|#define UA_STATUSCODE_GOOD ((UA_StatusCode) 0x00000000)
  ------------------
  252|    112|    }
  253|       |
  254|       |    /* Set the path */
  255|    135|    UA_assert(curr < endpointUrl->length);
  ------------------
  |  |  248|    135|# define UA_assert(ignore) assert(ignore)
  ------------------
  |  Branch (255:5): [True: 135, False: 0]
  ------------------
  256|    135|    if(endpointUrl->data[curr] != '/')
  ------------------
  |  Branch (256:8): [True: 69, False: 66]
  ------------------
  257|     69|        return UA_STATUSCODE_BADTCPENDPOINTURLINVALID;
  ------------------
  |  |  500|     69|#define UA_STATUSCODE_BADTCPENDPOINTURLINVALID ((UA_StatusCode) 0x80830000)
  ------------------
  258|     66|    if(++curr == endpointUrl->length)
  ------------------
  |  Branch (258:8): [True: 7, False: 59]
  ------------------
  259|      7|        return UA_STATUSCODE_GOOD;
  ------------------
  |  |   17|      7|#define UA_STATUSCODE_GOOD ((UA_StatusCode) 0x00000000)
  ------------------
  260|     59|    if(outPath != NULL) {
  ------------------
  |  Branch (260:8): [True: 59, False: 0]
  ------------------
  261|     59|        outPath->data = &endpointUrl->data[curr];
  262|     59|        outPath->length = endpointUrl->length - curr;
  263|       |
  264|       |        /* Remove trailing slash from the path */
  265|     59|        if(endpointUrl->data[endpointUrl->length - 1] == '/')
  ------------------
  |  Branch (265:12): [True: 13, False: 46]
  ------------------
  266|     13|            outPath->length--;
  267|       |
  268|       |        /* Empty string? */
  269|     59|        if(outPath->length == 0)
  ------------------
  |  Branch (269:12): [True: 13, False: 46]
  ------------------
  270|     13|            outPath->data = NULL;
  271|     59|    }
  272|       |
  273|     59|    return UA_STATUSCODE_GOOD;
  ------------------
  |  |   17|     59|#define UA_STATUSCODE_GOOD ((UA_StatusCode) 0x00000000)
  ------------------
  274|     66|}
UA_parseEndpointUrlEthernet:
  278|    381|                            UA_UInt16 *vid, UA_Byte *pcp) {
  279|       |    /* Url must begin with "opc.eth://" */
  280|    381|    if(endpointUrl->length < 11)
  ------------------
  |  Branch (280:8): [True: 6, False: 375]
  ------------------
  281|      6|        return UA_STATUSCODE_BADINTERNALERROR;
  ------------------
  |  |   29|      6|#define UA_STATUSCODE_BADINTERNALERROR ((UA_StatusCode) 0x80020000)
  ------------------
  282|    375|    if(strncmp((char*) endpointUrl->data, "opc.eth://", 10) != 0)
  ------------------
  |  Branch (282:8): [True: 92, False: 283]
  ------------------
  283|     92|        return UA_STATUSCODE_BADINTERNALERROR;
  ------------------
  |  |   29|     92|#define UA_STATUSCODE_BADINTERNALERROR ((UA_StatusCode) 0x80020000)
  ------------------
  284|       |
  285|       |    /* Where does the host address end? */
  286|    283|    size_t curr = 10;
  287|  1.13M|    for(; curr < endpointUrl->length; ++curr) {
  ------------------
  |  Branch (287:11): [True: 1.13M, False: 16]
  ------------------
  288|  1.13M|        if(endpointUrl->data[curr] == ':') {
  ------------------
  |  Branch (288:12): [True: 267, False: 1.13M]
  ------------------
  289|    267|           break;
  290|    267|        }
  291|  1.13M|    }
  292|       |
  293|       |    /* set host address */
  294|    283|    target->data = &endpointUrl->data[10];
  295|    283|    target->length = curr - 10;
  296|    283|    if(curr == endpointUrl->length)
  ------------------
  |  Branch (296:8): [True: 16, False: 267]
  ------------------
  297|     16|        return UA_STATUSCODE_GOOD;
  ------------------
  |  |   17|     16|#define UA_STATUSCODE_GOOD ((UA_StatusCode) 0x00000000)
  ------------------
  298|       |
  299|       |    /* Set VLAN */
  300|    267|    u32 value = 0;
  301|    267|    curr++;  /* skip ':' */
  302|    267|    size_t progress = UA_readNumber(&endpointUrl->data[curr],
  303|    267|                                    endpointUrl->length - curr, &value);
  304|    267|    if(progress == 0 || value > 4096)
  ------------------
  |  Branch (304:8): [True: 40, False: 227]
  |  Branch (304:25): [True: 56, False: 171]
  ------------------
  305|     96|        return UA_STATUSCODE_BADINTERNALERROR;
  ------------------
  |  |   29|     96|#define UA_STATUSCODE_BADINTERNALERROR ((UA_StatusCode) 0x80020000)
  ------------------
  306|    171|    curr += progress;
  307|    171|    if(curr == endpointUrl->length || endpointUrl->data[curr] == '.')
  ------------------
  |  Branch (307:8): [True: 32, False: 139]
  |  Branch (307:39): [True: 103, False: 36]
  ------------------
  308|    135|        *vid = (UA_UInt16) value;
  309|    171|    if(curr == endpointUrl->length)
  ------------------
  |  Branch (309:8): [True: 32, False: 139]
  ------------------
  310|     32|        return UA_STATUSCODE_GOOD;
  ------------------
  |  |   17|     32|#define UA_STATUSCODE_GOOD ((UA_StatusCode) 0x00000000)
  ------------------
  311|       |
  312|       |    /* Set priority */
  313|    139|    if(endpointUrl->data[curr] != '.')
  ------------------
  |  Branch (313:8): [True: 36, False: 103]
  ------------------
  314|     36|        return UA_STATUSCODE_BADINTERNALERROR;
  ------------------
  |  |   29|     36|#define UA_STATUSCODE_BADINTERNALERROR ((UA_StatusCode) 0x80020000)
  ------------------
  315|    103|    curr++;  /* skip '.' */
  316|    103|    progress = UA_readNumber(&endpointUrl->data[curr],
  317|    103|                             endpointUrl->length - curr, &value);
  318|    103|    if(progress == 0 || value > 7)
  ------------------
  |  Branch (318:8): [True: 5, False: 98]
  |  Branch (318:25): [True: 55, False: 43]
  ------------------
  319|     60|        return UA_STATUSCODE_BADINTERNALERROR;
  ------------------
  |  |   29|     60|#define UA_STATUSCODE_BADINTERNALERROR ((UA_StatusCode) 0x80020000)
  ------------------
  320|     43|    curr += progress;
  321|     43|    if(curr != endpointUrl->length)
  ------------------
  |  Branch (321:8): [True: 36, False: 7]
  ------------------
  322|     36|        return UA_STATUSCODE_BADINTERNALERROR;
  ------------------
  |  |   29|     36|#define UA_STATUSCODE_BADINTERNALERROR ((UA_StatusCode) 0x80020000)
  ------------------
  323|      7|    *pcp = (UA_Byte) value;
  324|       |
  325|      7|    return UA_STATUSCODE_GOOD;
  ------------------
  |  |   17|      7|#define UA_STATUSCODE_GOOD ((UA_StatusCode) 0x00000000)
  ------------------
  326|     43|}

UA_memoryManager_setLimitFromLast4Bytes:
  161|    923|int UA_memoryManager_setLimitFromLast4Bytes(const uint8_t *data, size_t size) {
  162|    923|    UA_mallocSingleton = UA_memoryManager_malloc;
  163|    923|    UA_freeSingleton = UA_memoryManager_free;
  164|    923|    UA_callocSingleton = UA_memoryManager_calloc;
  165|    923|    UA_reallocSingleton = UA_memoryManager_realloc;
  166|    923|    if(size <4)
  ------------------
  |  Branch (166:8): [True: 2, False: 921]
  ------------------
  167|      2|        return 0;
  168|       |    // just cast the last 4 bytes to uint32
  169|    921|    uint32_t limit;
  170|    921|    memcpy(&limit, &data[size-4], sizeof(uint32_t));
  171|    921|    memoryLimit = limit;
  172|    921|    return 1;
  173|    923|}

LLVMFuzzerTestOneInput:
   42|    923|extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   43|       |
   44|    923|    if (!UA_memoryManager_setLimitFromLast4Bytes(data, size))
  ------------------
  |  Branch (44:9): [True: 2, False: 921]
  ------------------
   45|      2|        return 0;
   46|    921|    size -= 4;
   47|       |
   48|    921|    if (size == 0)
  ------------------
  |  Branch (48:9): [True: 1, False: 920]
  ------------------
   49|      1|        return 0;
   50|       |
   51|       |    // use first byte to decide which function should be fuzzed
   52|       |
   53|    920|    const uint8_t select = data[0];
   54|       |
   55|    920|    const uint8_t *newData = &data[1];
   56|    920|    size_t  newSize = size-1;
   57|       |
   58|    920|    switch(select) {
   59|    535|        case 0:
  ------------------
  |  Branch (59:9): [True: 535, False: 385]
  ------------------
   60|    535|            return tortureParseEndpointUrl(newData, newSize);
   61|    381|        case 1:
  ------------------
  |  Branch (61:9): [True: 381, False: 539]
  ------------------
   62|    381|            return tortureParseEndpointUrlEthernet(newData, newSize);
   63|      4|        default:
  ------------------
  |  Branch (63:9): [True: 4, False: 916]
  ------------------
   64|      4|            return 0;
   65|    920|    }
   66|       |
   67|    920|}
fuzz_src_ua_util.cc:_ZL23tortureParseEndpointUrlPKhm:
   14|    535|static int tortureParseEndpointUrl(const uint8_t *data, size_t size) {
   15|    535|    const UA_String endpointUrl = {
   16|    535|        size, (UA_Byte* )(void*)data
   17|    535|    };
   18|       |
   19|    535|    UA_String hostname;
   20|    535|    UA_UInt16 port;
   21|    535|    UA_String path;
   22|    535|    UA_parseEndpointUrl(&endpointUrl, &hostname, &port, &path);
   23|    535|    return 0;
   24|    535|}
fuzz_src_ua_util.cc:_ZL31tortureParseEndpointUrlEthernetPKhm:
   26|    381|static int tortureParseEndpointUrlEthernet(const uint8_t *data, size_t size) {
   27|    381|    const UA_String endpointUrl = {
   28|    381|        size, (UA_Byte* )(void*)data
   29|    381|    };
   30|       |
   31|    381|    UA_String target;
   32|    381|    UA_UInt16 vid;
   33|    381|    UA_Byte prid;
   34|    381|    UA_parseEndpointUrlEthernet(&endpointUrl, &target, &vid, &prid);
   35|    381|    return 0;
   36|    381|}

