UA_readNumberWithBase:
  110|    564|UA_readNumberWithBase(const UA_Byte *buf, size_t buflen, UA_UInt32 *number, UA_Byte base) {
  111|    564|    UA_assert(buf);
  ------------------
  |  |  399|    564|# define UA_assert(ignore) assert(ignore)
  ------------------
  |  Branch (111:5): [True: 564, False: 0]
  ------------------
  112|    564|    UA_assert(number);
  ------------------
  |  |  399|    564|# define UA_assert(ignore) assert(ignore)
  ------------------
  |  Branch (112:5): [True: 564, False: 0]
  ------------------
  113|    564|    u32 n = 0;
  114|    564|    size_t progress = 0;
  115|       |    /* read numbers until the end or a non-number character appears */
  116|  7.96M|    while(progress < buflen) {
  ------------------
  |  Branch (116:11): [True: 7.96M, False: 268]
  ------------------
  117|  7.96M|        u8 c = buf[progress];
  118|  7.96M|        if(c >= '0' && c <= '9' && c <= '0' + (base-1))
  ------------------
  |  Branch (118:12): [True: 7.96M, False: 204]
  |  Branch (118:24): [True: 7.96M, False: 92]
  |  Branch (118:36): [True: 7.96M, False: 0]
  ------------------
  119|  7.96M|           n = (n * base) + c - '0';
  120|    296|        else if(base > 9 && c >= 'a' && c <= 'z' && c <= 'a' + (base-11))
  ------------------
  |  Branch (120:17): [True: 296, False: 0]
  |  Branch (120:29): [True: 57, False: 239]
  |  Branch (120:41): [True: 19, False: 38]
  |  Branch (120:53): [True: 0, False: 19]
  ------------------
  121|      0|           n = (n * base) + c-'a' + 10;
  122|    296|        else if(base > 9 && c >= 'A' && c <= 'Z' && c <= 'A' + (base-11))
  ------------------
  |  Branch (122:17): [True: 296, False: 0]
  |  Branch (122:29): [True: 71, False: 225]
  |  Branch (122:41): [True: 9, False: 62]
  |  Branch (122:53): [True: 0, False: 9]
  ------------------
  123|      0|           n = (n * base) + c-'A' + 10;
  124|    296|        else
  125|    296|           break;
  126|  7.96M|        ++progress;
  127|  7.96M|    }
  128|    564|    *number = n;
  129|    564|    return progress;
  130|    564|}
UA_readNumber:
  133|    564|UA_readNumber(const UA_Byte *buf, size_t buflen, UA_UInt32 *number) {
  134|    564|    return UA_readNumberWithBase(buf, buflen, number, 10);
  135|    564|}
UA_parseEndpointUrl:
  146|    510|                    UA_UInt16 *outPort, UA_String *outPath) {
  147|    510|    if(!endpointUrl || !endpointUrl->data)
  ------------------
  |  Branch (147:8): [True: 0, False: 510]
  |  Branch (147:24): [True: 0, False: 510]
  ------------------
  148|      0|        return UA_STATUSCODE_BADTCPENDPOINTURLINVALID;
  ------------------
  |  |  500|      0|#define UA_STATUSCODE_BADTCPENDPOINTURLINVALID ((UA_StatusCode) 0x80830000)
  ------------------
  149|       |
  150|       |    /* Which type of schema is this? */
  151|    510|    unsigned schemaType = 0;
  152|    510|    size_t schemaLen = 0;
  153|  2.62k|    for(; schemaType < UA_SCHEMAS_SIZE; schemaType++) {
  ------------------
  |  |  137|  2.62k|#define UA_SCHEMAS_SIZE 6
  ------------------
  |  Branch (153:11): [True: 2.52k, False: 105]
  ------------------
  154|  2.52k|        schemaLen = strlen(schemas[schemaType]);
  155|  2.52k|        if(endpointUrl->length >= schemaLen &&
  ------------------
  |  Branch (155:12): [True: 2.06k, False: 459]
  ------------------
  156|  2.06k|           strncmp((char*)endpointUrl->data, schemas[schemaType], schemaLen) == 0)
  ------------------
  |  Branch (156:12): [True: 405, False: 1.65k]
  ------------------
  157|    405|            break;
  158|  2.52k|    }
  159|    510|    if(schemaType == UA_SCHEMAS_SIZE)
  ------------------
  |  |  137|    510|#define UA_SCHEMAS_SIZE 6
  ------------------
  |  Branch (159:8): [True: 105, False: 405]
  ------------------
  160|    105|        return UA_STATUSCODE_BADTCPENDPOINTURLINVALID;
  ------------------
  |  |  500|    105|#define UA_STATUSCODE_BADTCPENDPOINTURLINVALID ((UA_StatusCode) 0x80830000)
  ------------------
  161|       |
  162|       |    /* Forward the current position until the first colon or slash */
  163|    405|    size_t start = strlen(schemas[schemaType]);
  164|    405|    size_t curr = start;
  165|    405|    UA_Boolean ipv6 = false;
  166|    405|    if(endpointUrl->length > curr && endpointUrl->data[curr] == '[') {
  ------------------
  |  Branch (166:8): [True: 400, False: 5]
  |  Branch (166:38): [True: 128, False: 272]
  ------------------
  167|       |        /* IPv6: opc.tcp://[2001:0db8:85a3::8a2e:0370:7334]:1234/path */
  168|  8.80M|        for(; curr < endpointUrl->length; ++curr) {
  ------------------
  |  Branch (168:15): [True: 8.80M, False: 22]
  ------------------
  169|  8.80M|            if(endpointUrl->data[curr] == ']')
  ------------------
  |  Branch (169:16): [True: 106, False: 8.80M]
  ------------------
  170|    106|                break;
  171|  8.80M|        }
  172|    128|        if(curr == endpointUrl->length)
  ------------------
  |  Branch (172:12): [True: 22, False: 106]
  ------------------
  173|     22|            return UA_STATUSCODE_BADTCPENDPOINTURLINVALID;
  ------------------
  |  |  500|     22|#define UA_STATUSCODE_BADTCPENDPOINTURLINVALID ((UA_StatusCode) 0x80830000)
  ------------------
  174|    106|        curr++;
  175|    106|        ipv6 = true;
  176|    277|    } else {
  177|       |        /* IPv4 or hostname: opc.tcp://something.something:1234/path */
  178|  1.05M|        for(; curr < endpointUrl->length; ++curr) {
  ------------------
  |  Branch (178:15): [True: 1.05M, False: 55]
  ------------------
  179|  1.05M|            if(endpointUrl->data[curr] == ':' || endpointUrl->data[curr] == '/')
  ------------------
  |  Branch (179:16): [True: 170, False: 1.05M]
  |  Branch (179:50): [True: 52, False: 1.05M]
  ------------------
  180|    222|                break;
  181|  1.05M|        }
  182|    277|    }
  183|       |
  184|       |    /* Set the hostname */
  185|    383|    if(ipv6) {
  ------------------
  |  Branch (185:8): [True: 106, False: 277]
  ------------------
  186|       |        /* Skip the ipv6 '[]' container for getaddrinfo() later */
  187|    106|        outHostname->data = &endpointUrl->data[start+1];
  188|    106|        outHostname->length = curr - (start+2);
  189|    277|    } else {
  190|    277|        outHostname->data = &endpointUrl->data[start];
  191|    277|        outHostname->length = curr - start;
  192|    277|    }
  193|       |
  194|       |    /* Empty string? */
  195|    383|    if(outHostname->length == 0)
  ------------------
  |  Branch (195:8): [True: 207, False: 176]
  ------------------
  196|    207|        outHostname->data = NULL;
  197|       |
  198|       |    /* Already at the end */
  199|    383|    if(curr == endpointUrl->length) {
  ------------------
  |  Branch (199:8): [True: 97, False: 286]
  ------------------
  200|     97|        if(outHostname->length == 0)
  ------------------
  |  Branch (200:12): [True: 6, False: 91]
  ------------------
  201|      6|            return UA_STATUSCODE_BADTCPENDPOINTURLINVALID;
  ------------------
  |  |  500|      6|#define UA_STATUSCODE_BADTCPENDPOINTURLINVALID ((UA_StatusCode) 0x80830000)
  ------------------
  202|     91|        return UA_STATUSCODE_GOOD;
  ------------------
  |  |   17|     91|#define UA_STATUSCODE_GOOD ((UA_StatusCode) 0x00000000)
  ------------------
  203|     97|    }
  204|       |
  205|       |    /* Set the port - and for ETH set the VID.PCP postfix in the outpath string.
  206|       |     * We have to parse that externally. */
  207|    286|    if(endpointUrl->data[curr] == ':') {
  ------------------
  |  Branch (207:8): [True: 205, False: 81]
  ------------------
  208|    205|        if(++curr == endpointUrl->length)
  ------------------
  |  Branch (208:12): [True: 3, False: 202]
  ------------------
  209|      3|            return UA_STATUSCODE_BADTCPENDPOINTURLINVALID;
  ------------------
  |  |  500|      3|#define UA_STATUSCODE_BADTCPENDPOINTURLINVALID ((UA_StatusCode) 0x80830000)
  ------------------
  210|       |
  211|       |        /* ETH schema */
  212|    202|        if(schemaType == UA_ETH_SCHEMA_INDEX) {
  ------------------
  |  |  138|    202|#define UA_ETH_SCHEMA_INDEX 2
  ------------------
  |  Branch (212:12): [True: 2, False: 200]
  ------------------
  213|      2|            if(outPath != NULL) {
  ------------------
  |  Branch (213:16): [True: 2, False: 0]
  ------------------
  214|      2|                outPath->data = &endpointUrl->data[curr];
  215|      2|                outPath->length = endpointUrl->length - curr;
  216|      2|            }
  217|      2|            return UA_STATUSCODE_GOOD;
  ------------------
  |  |   17|      2|#define UA_STATUSCODE_GOOD ((UA_StatusCode) 0x00000000)
  ------------------
  218|      2|        }
  219|       |
  220|    200|        u32 largeNum;
  221|    200|        size_t progress = UA_readNumber(&endpointUrl->data[curr],
  222|    200|                                        endpointUrl->length - curr, &largeNum);
  223|    200|        if(progress == 0 || largeNum > 65535)
  ------------------
  |  Branch (223:12): [True: 49, False: 151]
  |  Branch (223:29): [True: 45, False: 106]
  ------------------
  224|     94|            return UA_STATUSCODE_BADTCPENDPOINTURLINVALID;
  ------------------
  |  |  500|     94|#define UA_STATUSCODE_BADTCPENDPOINTURLINVALID ((UA_StatusCode) 0x80830000)
  ------------------
  225|       |        /* Test if the end of a valid port was reached */
  226|    106|        curr += progress;
  227|    106|        if(curr == endpointUrl->length || endpointUrl->data[curr] == '/')
  ------------------
  |  Branch (227:12): [True: 52, False: 54]
  |  Branch (227:43): [True: 17, False: 37]
  ------------------
  228|     69|            *outPort = (u16)largeNum;
  229|    106|        if(curr == endpointUrl->length)
  ------------------
  |  Branch (229:12): [True: 52, False: 54]
  ------------------
  230|     52|            return UA_STATUSCODE_GOOD;
  ------------------
  |  |   17|     52|#define UA_STATUSCODE_GOOD ((UA_StatusCode) 0x00000000)
  ------------------
  231|    106|    }
  232|       |
  233|       |    /* Set the path */
  234|    135|    UA_assert(curr < endpointUrl->length);
  ------------------
  |  |  399|    135|# define UA_assert(ignore) assert(ignore)
  ------------------
  |  Branch (234:5): [True: 135, False: 0]
  ------------------
  235|    135|    if(endpointUrl->data[curr] != '/')
  ------------------
  |  Branch (235:8): [True: 65, False: 70]
  ------------------
  236|     65|        return UA_STATUSCODE_BADTCPENDPOINTURLINVALID;
  ------------------
  |  |  500|     65|#define UA_STATUSCODE_BADTCPENDPOINTURLINVALID ((UA_StatusCode) 0x80830000)
  ------------------
  237|     70|    if(++curr == endpointUrl->length)
  ------------------
  |  Branch (237:8): [True: 5, False: 65]
  ------------------
  238|      5|        return UA_STATUSCODE_GOOD;
  ------------------
  |  |   17|      5|#define UA_STATUSCODE_GOOD ((UA_StatusCode) 0x00000000)
  ------------------
  239|     65|    if(outPath != NULL) {
  ------------------
  |  Branch (239:8): [True: 65, False: 0]
  ------------------
  240|     65|        outPath->data = &endpointUrl->data[curr];
  241|     65|        outPath->length = endpointUrl->length - curr;
  242|       |
  243|       |        /* Remove trailing slash from the path */
  244|     65|        if(endpointUrl->data[endpointUrl->length - 1] == '/')
  ------------------
  |  Branch (244:12): [True: 13, False: 52]
  ------------------
  245|     13|            outPath->length--;
  246|       |
  247|       |        /* Empty string? */
  248|     65|        if(outPath->length == 0)
  ------------------
  |  Branch (248:12): [True: 13, False: 52]
  ------------------
  249|     13|            outPath->data = NULL;
  250|     65|    }
  251|       |
  252|     65|    return UA_STATUSCODE_GOOD;
  ------------------
  |  |   17|     65|#define UA_STATUSCODE_GOOD ((UA_StatusCode) 0x00000000)
  ------------------
  253|     70|}
UA_parseEndpointUrlEthernet:
  257|    378|                            UA_UInt16 *vid, UA_Byte *pcp) {
  258|       |    /* Url must begin with "opc.eth://" */
  259|    378|    if(endpointUrl->length < 11) {
  ------------------
  |  Branch (259:8): [True: 7, False: 371]
  ------------------
  260|      7|        return UA_STATUSCODE_BADINTERNALERROR;
  ------------------
  |  |   29|      7|#define UA_STATUSCODE_BADINTERNALERROR ((UA_StatusCode) 0x80020000)
  ------------------
  261|      7|    }
  262|    371|    if(strncmp((char*) endpointUrl->data, "opc.eth://", 10) != 0) {
  ------------------
  |  Branch (262:8): [True: 93, False: 278]
  ------------------
  263|     93|        return UA_STATUSCODE_BADINTERNALERROR;
  ------------------
  |  |   29|     93|#define UA_STATUSCODE_BADINTERNALERROR ((UA_StatusCode) 0x80020000)
  ------------------
  264|     93|    }
  265|       |
  266|       |    /* Where does the host address end? */
  267|    278|    size_t curr = 10;
  268|  1.11M|    for(; curr < endpointUrl->length; ++curr) {
  ------------------
  |  Branch (268:11): [True: 1.11M, False: 21]
  ------------------
  269|  1.11M|        if(endpointUrl->data[curr] == ':') {
  ------------------
  |  Branch (269:12): [True: 257, False: 1.11M]
  ------------------
  270|    257|           break;
  271|    257|        }
  272|  1.11M|    }
  273|       |
  274|       |    /* set host address */
  275|    278|    target->data = &endpointUrl->data[10];
  276|    278|    target->length = curr - 10;
  277|    278|    if(curr == endpointUrl->length) {
  ------------------
  |  Branch (277:8): [True: 21, False: 257]
  ------------------
  278|     21|        return UA_STATUSCODE_GOOD;
  ------------------
  |  |   17|     21|#define UA_STATUSCODE_GOOD ((UA_StatusCode) 0x00000000)
  ------------------
  279|     21|    }
  280|       |
  281|       |    /* Set VLAN */
  282|    257|    u32 value = 0;
  283|    257|    curr++;  /* skip ':' */
  284|    257|    size_t progress = UA_readNumber(&endpointUrl->data[curr],
  285|    257|                                    endpointUrl->length - curr, &value);
  286|    257|    if(progress == 0 || value > 4096) {
  ------------------
  |  Branch (286:8): [True: 28, False: 229]
  |  Branch (286:25): [True: 51, False: 178]
  ------------------
  287|     79|        return UA_STATUSCODE_BADINTERNALERROR;
  ------------------
  |  |   29|     79|#define UA_STATUSCODE_BADINTERNALERROR ((UA_StatusCode) 0x80020000)
  ------------------
  288|     79|    }
  289|    178|    curr += progress;
  290|    178|    if(curr == endpointUrl->length || endpointUrl->data[curr] == '.') {
  ------------------
  |  Branch (290:8): [True: 35, False: 143]
  |  Branch (290:39): [True: 107, False: 36]
  ------------------
  291|    142|        *vid = (UA_UInt16) value;
  292|    142|    }
  293|    178|    if(curr == endpointUrl->length) {
  ------------------
  |  Branch (293:8): [True: 35, False: 143]
  ------------------
  294|     35|        return UA_STATUSCODE_GOOD;
  ------------------
  |  |   17|     35|#define UA_STATUSCODE_GOOD ((UA_StatusCode) 0x00000000)
  ------------------
  295|     35|    }
  296|       |
  297|       |    /* Set priority */
  298|    143|    if(endpointUrl->data[curr] != '.') {
  ------------------
  |  Branch (298:8): [True: 36, False: 107]
  ------------------
  299|     36|        return UA_STATUSCODE_BADINTERNALERROR;
  ------------------
  |  |   29|     36|#define UA_STATUSCODE_BADINTERNALERROR ((UA_StatusCode) 0x80020000)
  ------------------
  300|     36|    }
  301|    107|    curr++;  /* skip '.' */
  302|    107|    progress = UA_readNumber(&endpointUrl->data[curr],
  303|    107|                             endpointUrl->length - curr, &value);
  304|    107|    if(progress == 0 || value > 7) {
  ------------------
  |  Branch (304:8): [True: 6, False: 101]
  |  Branch (304:25): [True: 63, False: 38]
  ------------------
  305|     69|        return UA_STATUSCODE_BADINTERNALERROR;
  ------------------
  |  |   29|     69|#define UA_STATUSCODE_BADINTERNALERROR ((UA_StatusCode) 0x80020000)
  ------------------
  306|     69|    }
  307|     38|    curr += progress;
  308|     38|    if(curr != endpointUrl->length) {
  ------------------
  |  Branch (308:8): [True: 28, False: 10]
  ------------------
  309|     28|        return UA_STATUSCODE_BADINTERNALERROR;
  ------------------
  |  |   29|     28|#define UA_STATUSCODE_BADINTERNALERROR ((UA_StatusCode) 0x80020000)
  ------------------
  310|     28|    }
  311|     10|    *pcp = (UA_Byte) value;
  312|       |
  313|     10|    return UA_STATUSCODE_GOOD;
  ------------------
  |  |   17|     10|#define UA_STATUSCODE_GOOD ((UA_StatusCode) 0x00000000)
  ------------------
  314|     38|}

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

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

