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

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

LLVMFuzzerTestOneInput:
   42|    890|extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   43|       |
   44|    890|    if (!UA_memoryManager_setLimitFromLast4Bytes(data, size))
  ------------------
  |  Branch (44:9): [True: 2, False: 888]
  ------------------
   45|      2|        return 0;
   46|    888|    size -= 4;
   47|       |
   48|    888|    if (size == 0)
  ------------------
  |  Branch (48:9): [True: 1, False: 887]
  ------------------
   49|      1|        return 0;
   50|       |
   51|       |    // use first byte to decide which function should be fuzzed
   52|       |
   53|    887|    const uint8_t select = data[0];
   54|       |
   55|    887|    const uint8_t *newData = &data[1];
   56|    887|    size_t  newSize = size-1;
   57|       |
   58|    887|    switch(select) {
   59|    510|        case 0:
  ------------------
  |  Branch (59:9): [True: 510, False: 377]
  ------------------
   60|    510|            return tortureParseEndpointUrl(newData, newSize);
   61|    374|        case 1:
  ------------------
  |  Branch (61:9): [True: 374, False: 513]
  ------------------
   62|    374|            return tortureParseEndpointUrlEthernet(newData, newSize);
   63|      3|        default:
  ------------------
  |  Branch (63:9): [True: 3, False: 884]
  ------------------
   64|      3|            return 0;
   65|    887|    }
   66|       |
   67|    887|}
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|    374|static int tortureParseEndpointUrlEthernet(const uint8_t *data, size_t size) {
   27|    374|    const UA_String endpointUrl = {
   28|    374|        size, (UA_Byte* )(void*)data
   29|    374|    };
   30|       |
   31|    374|    UA_String target;
   32|    374|    UA_UInt16 vid;
   33|    374|    UA_Byte prid;
   34|    374|    UA_parseEndpointUrlEthernet(&endpointUrl, &target, &vid, &prid);
   35|    374|    return 0;
   36|    374|}

