UA_unbase64:
   75|     89|UA_unbase64(const unsigned char *src, size_t len, size_t *out_len) {
   76|       |    /* Empty base64 results in an empty byte-string */
   77|     89|    if(len == 0) {
  ------------------
  |  Branch (77:8): [True: 0, False: 89]
  ------------------
   78|      0|        *out_len = 0;
   79|      0|        return (unsigned char*)UA_EMPTY_ARRAY_SENTINEL;
  ------------------
  |  |  757|      0|#define UA_EMPTY_ARRAY_SENTINEL ((void*)0x01)
  ------------------
   80|      0|    }
   81|       |
   82|       |    /* Allocate the output string. Append four bytes to allow missing padding */
   83|     89|    size_t olen = (len / 4 * 3) + 4;
   84|     89|    unsigned char *out = (unsigned char*)UA_malloc(olen);
  ------------------
  |  |   22|     89|#define UA_malloc(size) UA_mallocSingleton(size)
  ------------------
   85|     89|    if(!out)
  ------------------
  |  Branch (85:8): [True: 0, False: 89]
  ------------------
   86|      0|        return NULL;
   87|       |
   88|       |    /* Iterate over the input */
   89|     89|    size_t pad = 0;
   90|     89|    unsigned char count = 0;
   91|     89|    unsigned char block[4];
   92|     89|    unsigned char *pos = out;
   93|  2.56M|    for(size_t i = 0; i < len; i++) {
  ------------------
  |  Branch (93:23): [True: 2.56M, False: 61]
  ------------------
   94|  2.56M|        if(src[i] & 0x80)
  ------------------
  |  Branch (94:12): [True: 14, False: 2.56M]
  ------------------
   95|     14|            goto error; /* Non-ASCII input */
   96|  2.56M|        unsigned char tmp = dtable[src[i]];
   97|  2.56M|        if(tmp == 0x80)
  ------------------
  |  Branch (97:12): [True: 10, False: 2.56M]
  ------------------
   98|     10|            goto error; /* Not an allowed character */
   99|  2.56M|        if(tmp == 0x7f)
  ------------------
  |  Branch (99:12): [True: 247, False: 2.56M]
  ------------------
  100|    247|            continue; /* Whitespace is ignored to accomodate RFC 2045, used in
  101|       |                       * XML for xs:base64Binary. */
  102|  2.56M|        block[count++] = tmp;
  103|       |
  104|       |        /* Padding */
  105|  2.56M|        if(src[i] == '=') {
  ------------------
  |  Branch (105:12): [True: 471, False: 2.56M]
  ------------------
  106|    471|            if(count < 3) /* Padding can only be the last two bytes of a block */
  ------------------
  |  Branch (106:16): [True: 2, False: 469]
  ------------------
  107|      2|                goto error;
  108|    469|            block[count-1] = 0;
  109|    469|            pad++;
  110|  2.56M|        } else if(pad > 0) {
  ------------------
  |  Branch (110:19): [True: 2, False: 2.56M]
  ------------------
  111|      2|            goto error; /* Padding not terminated correctly */
  112|      2|        }
  113|       |
  114|       |        /* Write three output characters for four characters of input */
  115|  2.56M|        if(count == 4) {
  ------------------
  |  Branch (115:12): [True: 641k, False: 1.92M]
  ------------------
  116|   641k|            if(pad > 2)
  ------------------
  |  Branch (116:16): [True: 0, False: 641k]
  ------------------
  117|      0|                goto error; /* Invalid padding */
  118|   641k|            *pos++ = (block[0] << 2) | (block[1] >> 4);
  119|   641k|            *pos++ = (block[1] << 4) | (block[2] >> 2);
  120|   641k|            *pos++ = (block[2] << 6) | block[3];
  121|   641k|            count = 0;
  122|   641k|            pos -= pad;
  123|   641k|            pad = 0;
  124|   641k|        }
  125|  2.56M|    }
  126|       |
  127|       |    /* Base64URL permits omitting the padding in the final block. A single
  128|       |     * character cannot encode a byte, and explicit padding must be complete. */
  129|     61|    if(count == 1 || pad > 0)
  ------------------
  |  Branch (129:8): [True: 12, False: 49]
  |  Branch (129:22): [True: 2, False: 47]
  ------------------
  130|     14|        goto error;
  131|     47|    if(count >= 2) {
  ------------------
  |  Branch (131:8): [True: 13, False: 34]
  ------------------
  132|     13|        *pos++ = (block[0] << 2) | (block[1] >> 4);
  133|     13|        if(count == 3)
  ------------------
  |  Branch (133:12): [True: 4, False: 9]
  ------------------
  134|      4|            *pos++ = (block[1] << 4) | (block[2] >> 2);
  135|     13|    }
  136|       |
  137|     47|    *out_len = (size_t)(pos - out);
  138|     47|    if(*out_len == 0) {
  ------------------
  |  Branch (138:8): [True: 9, False: 38]
  ------------------
  139|      9|        UA_free(out);
  ------------------
  |  |   23|      9|#define UA_free(ptr) UA_freeSingleton(ptr)
  ------------------
  140|      9|        return (unsigned char*)UA_EMPTY_ARRAY_SENTINEL;
  ------------------
  |  |  757|      9|#define UA_EMPTY_ARRAY_SENTINEL ((void*)0x01)
  ------------------
  141|      9|    }
  142|     38|    return out;
  143|       |
  144|     42| error:
  145|     42|    UA_free(out);
  ------------------
  |  |   23|     42|#define UA_free(ptr) UA_freeSingleton(ptr)
  ------------------
  146|       |    return NULL;
  147|     47|}

LLVMFuzzerTestOneInput:
   18|     89|LLVMFuzzerTestOneInput(uint8_t *data, size_t size) {
   19|     89|    size_t retLen;
   20|     89|    unsigned char* ret = UA_unbase64(data, size, &retLen);
   21|     89|    if (retLen > 0)
  ------------------
  |  Branch (21:9): [True: 80, False: 9]
  ------------------
   22|     80|        free(ret);
   23|     89|    return 0;
   24|     89|}

