_Z8mem_openPKhm:
   55|      1|TSK_IMG_INFO *mem_open(const uint8_t *data, size_t size) {
   56|      1|  IMG_MEM_INFO *inmemory_img =
   57|      1|      reinterpret_cast<IMG_MEM_INFO *>(malloc(sizeof(IMG_MEM_INFO)));
   58|      1|  TSK_IMG_INFO *img;
   59|      1|  if (inmemory_img == nullptr) {
  ------------------
  |  Branch (59:7): [True: 0, False: 1]
  ------------------
   60|      0|    return nullptr;
   61|      0|  }
   62|      1|  img = reinterpret_cast<TSK_IMG_INFO *>(inmemory_img);
   63|      1|  img->itype = TSK_IMG_TYPE_RAW;
   64|      1|  img->read = mem_read;
   65|      1|  img->close = mem_close;
   66|      1|  img->imgstat = mem_imgstat;
   67|      1|  img->size = size;
   68|      1|  img->sector_size = 512;
   69|      1|  tsk_init_lock(&(img->cache_lock));
   70|      1|  inmemory_img->data = data;
   71|      1|  inmemory_img->size = size;
   72|      1|  return img;
   73|      1|}
sleuthkit_mmls_fuzzer.cc:_ZL8mem_readP12TSK_IMG_INFOlPcm:
   30|      1|                        size_t len) {
   31|      1|  IMG_MEM_INFO *mem_info = reinterpret_cast<IMG_MEM_INFO *>(img_info);
   32|       |  // Bounds-checking exists in the real drivers.
   33|      1|  if (offset > mem_info->size) {
  ------------------
  |  Branch (33:7): [True: 0, False: 1]
  ------------------
   34|      0|    return -1;
   35|      0|  }
   36|      1|  ssize_t read_len = len;
   37|      1|  if (offset + len > mem_info->size) {
  ------------------
  |  Branch (37:7): [True: 0, False: 1]
  ------------------
   38|      0|    read_len = mem_info->size - offset;
   39|      0|  }
   40|      1|  if (memcpy(buf, mem_info->data + offset, read_len) == nullptr) {
  ------------------
  |  Branch (40:7): [True: 0, False: 1]
  ------------------
   41|      0|    return -1;
   42|      1|  } else {
   43|      1|    return read_len;
   44|      1|  }
   45|      1|}
sleuthkit_mmls_fuzzer.cc:_ZL9mem_closeP12TSK_IMG_INFO:
   47|      1|static void mem_close(TSK_IMG_INFO *img_info) {
   48|      1|  IMG_MEM_INFO *mem_info = reinterpret_cast<IMG_MEM_INFO *>(img_info);
   49|      1|  tsk_deinit_lock(&(img_info->cache_lock));
   50|      1|  free(mem_info);
   51|      1|}

tsk_malloc:
   29|      2|{
   30|      2|    void *ptr;
   31|       |
   32|      2|    if ((ptr = calloc(len, 1)) == 0) {
  ------------------
  |  Branch (32:9): [True: 0, False: 2]
  ------------------
   33|      0|        tsk_error_reset();
   34|      0|        tsk_error_set_errno(TSK_ERR_AUX_MALLOC);
  ------------------
  |  |  307|      0|#define TSK_ERR_AUX_MALLOC	(TSK_ERR_AUX | 0)
  |  |  ------------------
  |  |  |  |  298|      0|#define TSK_ERR_AUX	0x01000000
  |  |  ------------------
  ------------------
   35|      0|        tsk_error_set_errstr("tsk_malloc: %s (%" PRIuSIZE" requested)", strerror(errno), len);
   36|      0|    }
   37|       |
   38|      2|    return ptr;
   39|      2|}

tsk_guess_end_u16:
   35|      2|{
   36|       |    /* try little */
   37|      2|    if (tsk_getu16(TSK_LIT_ENDIAN, x) == val) {
  ------------------
  |  |   86|      2|#define tsk_getu16(endian, x)   \
  |  |   87|      2|(uint16_t)(((endian) == TSK_LIT_ENDIAN) ? \
  |  |  ------------------
  |  |  |  Branch (87:12): [Folded - Ignored]
  |  |  ------------------
  |  |   88|      2|           (((uint8_t *)(x))[0] + (((uint8_t *)(x))[1] << 8)) :    \
  |  |   89|      2|           (((uint8_t *)(x))[1] + (((uint8_t *)(x))[0] << 8)) )
  ------------------
  |  Branch (37:9): [True: 0, False: 2]
  ------------------
   38|      0|        *flag = TSK_LIT_ENDIAN;
   39|      0|        return 0;
   40|      0|    }
   41|       |
   42|       |    /* ok, big now */
   43|      2|    if (tsk_getu16(TSK_BIG_ENDIAN, x) == val) {
  ------------------
  |  |   86|      2|#define tsk_getu16(endian, x)   \
  |  |   87|      2|(uint16_t)(((endian) == TSK_LIT_ENDIAN) ? \
  |  |  ------------------
  |  |  |  Branch (87:12): [Folded - Ignored]
  |  |  ------------------
  |  |   88|      2|           (((uint8_t *)(x))[0] + (((uint8_t *)(x))[1] << 8)) :    \
  |  |   89|      2|           (((uint8_t *)(x))[1] + (((uint8_t *)(x))[0] << 8)) )
  ------------------
  |  Branch (43:9): [True: 0, False: 2]
  ------------------
   44|      0|        *flag = TSK_BIG_ENDIAN;
   45|      0|        return 0;
   46|      0|    }
   47|       |
   48|       |    /* didn't find it */
   49|      2|    return 1;
   50|      2|}

tsk_error_get_info:
  148|      4|{
  149|      4|    TSK_ERROR_INFO *ptr = NULL;
  150|      4|    (void) pthread_once(&pt_tls_key_once, make_pt_tls_key);
  151|      4|    if ((ptr = (TSK_ERROR_INFO *) pthread_getspecific(pt_tls_key)) == 0) {
  ------------------
  |  Branch (151:9): [True: 1, False: 3]
  ------------------
  152|       |        // Under high memory pressure malloc will return NULL.
  153|      1|        ptr = (TSK_ERROR_INFO *) malloc(sizeof(TSK_ERROR_INFO));
  154|       |
  155|      1|        if( ptr != NULL ) {
  ------------------
  |  Branch (155:13): [True: 1, False: 0]
  ------------------
  156|      1|            ptr->t_errno = 0;
  157|      1|            ptr->errstr[0] = 0;
  158|      1|            ptr->errstr2[0] = 0;
  159|      1|        }
  160|      1|        (void) pthread_setspecific(pt_tls_key, ptr);
  161|      1|    }
  162|      4|    return ptr;
  163|      4|}
tsk_error_set_errno:
  308|      1|{
  309|      1|    tsk_error_get_info()->t_errno = t_errno;
  310|      1|}
tsk_error_set_errstr:
  332|      1|{
  333|      1|    va_list args;
  334|      1|    va_start(args, format);
  335|      1|    vsnprintf(tsk_error_get_info()->errstr, TSK_ERROR_STRING_MAX_LENGTH,
  ------------------
  |  |   67|      1|#define TSK_ERROR_STRING_MAX_LENGTH 1024
  ------------------
  336|      1|        format, args);
  337|      1|    va_end(args);
  338|      1|}
tsk_error_reset:
  444|      2|{
  445|      2|    TSK_ERROR_INFO *info = tsk_error_get_info();
  446|       |
  447|      2|    if( info != NULL ) {
  ------------------
  |  Branch (447:9): [True: 2, False: 0]
  ------------------
  448|      2|       info->t_errno = 0;
  449|      2|       info->errstr[0] = 0;
  450|      2|       info->errstr2[0] = 0;
  451|      2|       info->errstr_print[0] = 0;
  452|      2|    }
  453|      2|}
tsk_error.c:make_pt_tls_key:
  142|      1|{
  143|      1|    (void) pthread_key_create(&pt_tls_key, free_error_info);
  144|      1|}

tsk_init_lock:
   46|      1|{
   47|      1|    pthread_mutexattr_t attr;
   48|      1|    pthread_mutexattr_init(&attr);
   49|       |
   50|       |    // Locks on Linux are not recursive (unlike on Windows), so things
   51|       |    // will hang if the current thread tries to take the lock again.
   52|       |    // While debugging, it's sometimes useful to call
   53|       |    //
   54|       |    //  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
   55|       |    //
   56|       |    // which will provoke an immediate error rather than a hang.
   57|       |    //
   58|       |    // PTHREAD_MUTEX_ERRORCHECK is not defined by default on Linux,
   59|       |    // but it is portable if you have the right_XOPEN_SOURCE settings.
   60|       |    // However, that macro affects the availability of other features
   61|       |    // like BSD-style u_int types used in afflib.
   62|       |    // PTHREAD_MUTEX_ERRORCHECK -is- available by default on Mac.
   63|       |    //
   64|       |    // PTHREAD_MUTEX_ERRORCHECK_NP is the Linux/gcc non-portable
   65|       |    // equivalent which does not require _XOPEN_SOURCE.
   66|       |    //
   67|       |    // Other interesting attributes are PTHREAD_MUTEX_RECURSIVE (and
   68|       |    // PTHREAD_MUTEX_RECURSIVE_NP).  We avoided those out of portability
   69|       |    // concerns with the _XOPEN_SOURCE settings.
   70|       |
   71|      1|    int e = pthread_mutex_init(&lock->mutex, &attr);
   72|      1|    pthread_mutexattr_destroy(&attr);
   73|      1|    if (e != 0) {
  ------------------
  |  Branch (73:9): [True: 0, False: 1]
  ------------------
   74|      0|        fprintf(stderr, "tsk_init_lock: thread_mutex_init failed %d\n", e);
   75|      0|        assert(0);
   76|      0|    }
   77|      1|}
tsk_deinit_lock:
   81|      1|{
   82|      1|    pthread_mutex_destroy(&lock->mutex);
   83|      1|}
tsk_take_lock:
   87|      2|{
   88|      2|    int e = pthread_mutex_lock(&lock->mutex);
   89|      2|    if (e != 0) {
  ------------------
  |  Branch (89:9): [True: 0, False: 2]
  ------------------
   90|      0|        fprintf(stderr, "tsk_take_lock: thread_mutex_lock failed %d\n", e);
   91|      0|        assert(0);
   92|      0|    }
   93|      2|}
tsk_release_lock:
   97|      2|{
   98|      2|    int e = pthread_mutex_unlock(&lock->mutex);
   99|      2|    if (e != 0) {
  ------------------
  |  Branch (99:9): [True: 0, False: 2]
  ------------------
  100|      0|        fprintf(stderr,
  101|      0|            "tsk_release_lock: thread_mutex_unlock failed %d\n", e);
  102|      0|        assert(0);
  103|      0|    }
  104|      2|}

tsk_img_read:
   60|      2|{
   61|      2|#define CACHE_AGE   1000
   62|      2|    ssize_t read_count = 0;
   63|      2|    int cache_index = 0;
   64|      2|    int cache_next = 0;         // index to lowest age cache (to use next)
   65|      2|    size_t len2 = 0;
   66|       |
   67|      2|    if (a_img_info == NULL) {
  ------------------
  |  Branch (67:9): [True: 0, False: 2]
  ------------------
   68|      0|        tsk_error_reset();
   69|      0|        tsk_error_set_errno(TSK_ERR_IMG_ARG);
  ------------------
  |  |  320|      0|#define TSK_ERR_IMG_ARG	    (TSK_ERR_IMG | 9)
  |  |  ------------------
  |  |  |  |  299|      0|#define TSK_ERR_IMG	0x02000000
  |  |  ------------------
  ------------------
   70|      0|        tsk_error_set_errstr("tsk_img_read: a_img_info: NULL");
   71|      0|        return -1;
   72|      0|    }
   73|       |
   74|       |    // Do not allow a_buf to be NULL.
   75|      2|    if (a_buf == NULL) {
  ------------------
  |  Branch (75:9): [True: 0, False: 2]
  ------------------
   76|      0|        tsk_error_reset();
   77|      0|        tsk_error_set_errno(TSK_ERR_IMG_ARG);
  ------------------
  |  |  320|      0|#define TSK_ERR_IMG_ARG	    (TSK_ERR_IMG | 9)
  |  |  ------------------
  |  |  |  |  299|      0|#define TSK_ERR_IMG	0x02000000
  |  |  ------------------
  ------------------
   78|      0|        tsk_error_set_errstr("tsk_img_read: a_buf: NULL");
   79|      0|        return -1;
   80|      0|    }
   81|       |
   82|       |    // The function cannot handle negative offsets.
   83|      2|    if (a_off < 0) {
  ------------------
  |  Branch (83:9): [True: 0, False: 2]
  ------------------
   84|      0|        tsk_error_reset();
   85|      0|        tsk_error_set_errno(TSK_ERR_IMG_ARG);
  ------------------
  |  |  320|      0|#define TSK_ERR_IMG_ARG	    (TSK_ERR_IMG | 9)
  |  |  ------------------
  |  |  |  |  299|      0|#define TSK_ERR_IMG	0x02000000
  |  |  ------------------
  ------------------
   86|      0|        tsk_error_set_errstr("tsk_img_read: a_off: %" PRIdOFF, a_off);
  ------------------
  |  |  269|      0|#define PRIdOFF		PRId64
  ------------------
   87|      0|        return -1;
   88|      0|    }
   89|       |
   90|       |    // Protect a_off against overflowing when a_len is added since TSK_OFF_T
   91|       |    // maps to an int64 we prefer it over size_t although likely checking
   92|       |    // for ( a_len > SSIZE_MAX ) is better but the code does not seem to
   93|       |    // use that approach.
   94|       |
   95|      2|    if ((TSK_OFF_T) a_len < 0) {
  ------------------
  |  Branch (95:9): [True: 0, False: 2]
  ------------------
   96|      0|        tsk_error_reset();
   97|      0|        tsk_error_set_errno(TSK_ERR_IMG_ARG);
  ------------------
  |  |  320|      0|#define TSK_ERR_IMG_ARG	    (TSK_ERR_IMG | 9)
  |  |  ------------------
  |  |  |  |  299|      0|#define TSK_ERR_IMG	0x02000000
  |  |  ------------------
  ------------------
   98|      0|        tsk_error_set_errstr("tsk_img_read: a_len: %zd", a_len);
   99|      0|        return -1;
  100|      0|    }
  101|       |
  102|       |    /* cache_lock is used for both the cache in IMG_INFO and 
  103|       |     * the shared variables in the img type specific INFO structs.
  104|       |     * grab it now so that it is held before any reads.
  105|       |     */
  106|      2|    tsk_take_lock(&(a_img_info->cache_lock));
  107|       |
  108|       |    // if they ask for more than the cache length, skip the cache
  109|      2|    if ((a_len + (a_off % 512)) > TSK_IMG_INFO_CACHE_LEN) {
  ------------------
  |  |   85|      2|#define TSK_IMG_INFO_CACHE_LEN  65536
  ------------------
  |  Branch (109:9): [True: 0, False: 2]
  ------------------
  110|      0|        read_count = tsk_img_read_no_cache(a_img_info, a_off, a_buf, a_len);
  111|      0|        tsk_release_lock(&(a_img_info->cache_lock));
  112|      0|        return read_count;
  113|      0|    }
  114|       |
  115|       |    // TODO: why not just return 0 here (and be POSIX compliant)?
  116|       |    // and why not check earlier for this condition?
  117|      2|    if (a_off >= a_img_info->size) {
  ------------------
  |  Branch (117:9): [True: 0, False: 2]
  ------------------
  118|      0|        tsk_release_lock(&(a_img_info->cache_lock));
  119|      0|        tsk_error_reset();
  120|      0|        tsk_error_set_errno(TSK_ERR_IMG_READ_OFF);
  ------------------
  |  |  319|      0|#define TSK_ERR_IMG_READ_OFF	(TSK_ERR_IMG | 8)
  |  |  ------------------
  |  |  |  |  299|      0|#define TSK_ERR_IMG	0x02000000
  |  |  ------------------
  ------------------
  121|      0|        tsk_error_set_errstr("tsk_img_read - %" PRIdOFF, a_off);
  ------------------
  |  |  269|      0|#define PRIdOFF		PRId64
  ------------------
  122|      0|        return -1;
  123|      0|    }
  124|       |
  125|       |    /* See if the requested length is going to be too long.
  126|       |     * we'll use this length when checking the cache. */
  127|      2|    len2 = a_len;
  128|       |
  129|       |    // Protect against INT64_MAX + INT64_MAX > value
  130|      2|    if (((TSK_OFF_T) len2 > a_img_info->size)
  ------------------
  |  Branch (130:9): [True: 0, False: 2]
  ------------------
  131|      2|        || (a_off >= (a_img_info->size - (TSK_OFF_T)len2))) {
  ------------------
  |  Branch (131:12): [True: 0, False: 2]
  ------------------
  132|      0|        len2 = (size_t) (a_img_info->size - a_off);
  133|      0|    }
  134|       |
  135|       |    // check if it is in the cache
  136|      2|    for (cache_index = 0;
  137|     66|        cache_index < TSK_IMG_INFO_CACHE_NUM; cache_index++) {
  ------------------
  |  |   84|     66|#define TSK_IMG_INFO_CACHE_NUM  32
  ------------------
  |  Branch (137:9): [True: 64, False: 2]
  ------------------
  138|       |
  139|       |        // Look into the in-use cache entries
  140|     64|        if (a_img_info->cache_len[cache_index] > 0) {
  ------------------
  |  Branch (140:13): [True: 1, False: 63]
  ------------------
  141|       |
  142|       |            // the read_count check makes sure we don't go back in after data was read
  143|      1|            if ((read_count == 0)
  ------------------
  |  Branch (143:17): [True: 1, False: 0]
  ------------------
  144|      1|                && (a_img_info->cache_off[cache_index] <= a_off)
  ------------------
  |  Branch (144:20): [True: 1, False: 0]
  ------------------
  145|      1|                && (a_img_info->cache_off[cache_index] +
  ------------------
  |  Branch (145:20): [True: 1, False: 0]
  ------------------
  146|      1|                    a_img_info->cache_len[cache_index] >= a_off + len2)) {
  147|       |
  148|       |                /*
  149|       |                   if (tsk_verbose)
  150|       |                   fprintf(stderr,
  151|       |                   "tsk_img_read: Read found in cache %d\n",  cache_index );
  152|       |                 */
  153|       |
  154|       |                // We found it...
  155|      1|                memcpy(a_buf,
  156|      1|                    &a_img_info->cache[cache_index][a_off -
  157|      1|                        a_img_info->cache_off[cache_index]], len2);
  158|      1|                read_count = (ssize_t) len2;
  159|       |
  160|       |                // reset its "age" since it was useful
  161|      1|                a_img_info->cache_age[cache_index] = CACHE_AGE;
  ------------------
  |  |   61|      1|#define CACHE_AGE   1000
  ------------------
  162|       |
  163|       |                // we don't break out of the loop so that we update all ages
  164|      1|            }
  165|      0|            else {
  166|       |                /* decrease its "age" since it was not useful.
  167|       |                 * We don't let used ones go below 1 so that they are not
  168|       |                 * confused with entries that have never been used. */
  169|      0|                a_img_info->cache_age[cache_index]--;
  170|       |
  171|       |                // see if this is the most eligible replacement
  172|      0|                if ((a_img_info->cache_len[cache_next] > 0)
  ------------------
  |  Branch (172:21): [True: 0, False: 0]
  ------------------
  173|      0|                    && (a_img_info->cache_age[cache_index] <
  ------------------
  |  Branch (173:24): [True: 0, False: 0]
  ------------------
  174|      0|                        a_img_info->cache_age[cache_next]))
  175|      0|                    cache_next = cache_index;
  176|      0|            }
  177|      1|        }
  178|     63|        else {
  179|     63|            cache_next = cache_index;
  180|     63|        }
  181|     64|    }
  182|       |
  183|       |    // if we didn't find it, then load it into the cache_next entry
  184|      2|    if (read_count == 0) {
  ------------------
  |  Branch (184:9): [True: 1, False: 1]
  ------------------
  185|      1|        size_t read_size = 0;
  186|       |
  187|       |        // round the offset down to a sector boundary
  188|      1|        a_img_info->cache_off[cache_next] = (a_off / 512) * 512;
  189|       |
  190|       |        /*
  191|       |           if (tsk_verbose)
  192|       |           fprintf(stderr,
  193|       |           "tsk_img_read: Loading data into cache %d (%" PRIdOFF
  194|       |           ")\n", cache_next, a_img_info->cache_off[cache_next]);
  195|       |         */
  196|       |
  197|       |        // Read a full cache block or the remaining data.
  198|      1|        read_size = TSK_IMG_INFO_CACHE_LEN;
  ------------------
  |  |   85|      1|#define TSK_IMG_INFO_CACHE_LEN  65536
  ------------------
  199|       |
  200|      1|        if ((a_img_info->cache_off[cache_next] + (TSK_OFF_T)read_size) >
  ------------------
  |  Branch (200:13): [True: 0, False: 1]
  ------------------
  201|      1|            a_img_info->size) {
  202|      0|            read_size =
  203|      0|                (size_t) (a_img_info->size -
  204|      0|                a_img_info->cache_off[cache_next]);
  205|      0|        }
  206|       |
  207|      1|        read_count = a_img_info->read(a_img_info,
  208|      1|            a_img_info->cache_off[cache_next],
  209|      1|            a_img_info->cache[cache_next], read_size);
  210|       |
  211|       |        // if no error, then set the variables and copy the data
  212|       |        // Although a read_count of -1 indicates an error,
  213|       |        // since read_count is used in the calculation it may not be negative.
  214|       |        // Also it does not make sense to copy data when the read_count is 0.
  215|      1|        if (read_count > 0) {
  ------------------
  |  Branch (215:13): [True: 1, False: 0]
  ------------------
  216|       |
  217|      1|            TSK_OFF_T rel_off = 0;
  218|      1|            a_img_info->cache_age[cache_next] = CACHE_AGE;
  ------------------
  |  |   61|      1|#define CACHE_AGE   1000
  ------------------
  219|      1|            a_img_info->cache_len[cache_next] = read_count;
  220|       |
  221|       |            // Determine the offset relative to the start of the cached data.
  222|      1|            rel_off = a_off - a_img_info->cache_off[cache_next];
  223|       |
  224|       |            // Make sure we were able to read sufficient data into the cache.
  225|      1|            if (rel_off > (TSK_OFF_T) read_count) {
  ------------------
  |  Branch (225:17): [True: 0, False: 1]
  ------------------
  226|      0|                len2 = 0;
  227|      0|            }
  228|       |            // Make sure not to copy more than is available in the cache.
  229|      1|            else if ((rel_off + (TSK_OFF_T) len2) > (TSK_OFF_T) read_count) {
  ------------------
  |  Branch (229:22): [True: 0, False: 1]
  ------------------
  230|      0|                len2 = (size_t) (read_count - rel_off);
  231|      0|            }
  232|       |            // Only copy data when we have something to copy.
  233|      1|            if (len2 > 0) {
  ------------------
  |  Branch (233:17): [True: 1, False: 0]
  ------------------
  234|      1|                memcpy(a_buf, &(a_img_info->cache[cache_next][rel_off]), len2);
  235|      1|            }
  236|      1|            read_count = (ssize_t) len2;
  237|      1|        }
  238|      0|        else {
  239|      0|            a_img_info->cache_len[cache_next] = 0;
  240|      0|            a_img_info->cache_age[cache_next] = 0;
  241|      0|            a_img_info->cache_off[cache_next] = 0;
  242|       |
  243|       |            // Something went wrong so let's try skipping the cache
  244|      0|            read_count = tsk_img_read_no_cache(a_img_info, a_off, a_buf, a_len);
  245|      0|        }
  246|      1|    }
  247|       |
  248|      2|    tsk_release_lock(&(a_img_info->cache_lock));
  249|      2|    return read_count;
  250|      2|}

tsk_vs_read_block:
   33|      2|{
   34|      2|    if (a_len % a_vs->block_size) {
  ------------------
  |  Branch (34:9): [True: 0, False: 2]
  ------------------
   35|      0|        tsk_error_reset();
   36|      0|        tsk_error_set_errno(TSK_ERR_VS_READ);
  ------------------
  |  |  329|      0|#define TSK_ERR_VS_READ		(TSK_ERR_VS | 2)
  |  |  ------------------
  |  |  |  |  300|      0|#define TSK_ERR_VS	0x04000000
  |  |  ------------------
  ------------------
   37|      0|        tsk_error_set_errstr("tsk_vs_read_block: length %" PRIuSIZE ""
   38|      0|            " not a multiple of %d", a_len, a_vs->block_size);
   39|      0|        return -1;
   40|      0|    }
   41|       |
   42|      2|    return tsk_img_read(a_vs->img_info,
   43|      2|        a_vs->offset + (TSK_OFF_T) (a_addr * a_vs->block_size),
   44|      2|        a_buf, a_len);
   45|      2|}

tsk_vs_open:
   37|      1|{
   38|      1|    if (img_info == NULL) {
  ------------------
  |  Branch (38:9): [True: 0, False: 1]
  ------------------
   39|       |        /* Opening the image file(s) failed, if attempted. */
   40|      0|        tsk_error_reset();
   41|      0|        tsk_error_set_errno(TSK_ERR_IMG_NOFILE);
  ------------------
  |  |  311|      0|#define TSK_ERR_IMG_NOFILE	(TSK_ERR_IMG | 0)
  |  |  ------------------
  |  |  |  |  299|      0|#define TSK_ERR_IMG	0x02000000
  |  |  ------------------
  ------------------
   42|      0|        tsk_error_set_errstr("mm_open");
   43|      0|        return NULL;
   44|      0|    }
   45|       |
   46|      1|	if (img_info->itype == TSK_IMG_TYPE_LOGICAL) {
  ------------------
  |  Branch (46:6): [True: 0, False: 1]
  ------------------
   47|      0|		tsk_error_reset();
   48|      0|		tsk_error_set_errno(TSK_ERR_VS_UNSUPTYPE);
  ------------------
  |  |  328|      0|#define TSK_ERR_VS_UNSUPTYPE	(TSK_ERR_VS | 1)
  |  |  ------------------
  |  |  |  |  300|      0|#define TSK_ERR_VS	0x04000000
  |  |  ------------------
  ------------------
   49|      0|		tsk_error_set_errstr("Logical image type can not have a volume system");
   50|      0|		return NULL;
   51|      0|	}
   52|       |
   53|       |    /* Autodetect mode 
   54|       |     * We need to try all of them in case there are multiple 
   55|       |     * installations
   56|       |     *
   57|       |     * NOte that errors that are encountered during the testing process
   58|       |     * will not be reported
   59|       |     */
   60|      1|    if (type == TSK_VS_TYPE_DETECT) {
  ------------------
  |  Branch (60:9): [True: 0, False: 1]
  ------------------
   61|      0|        TSK_VS_INFO *vs, *prev_vs = NULL;
   62|      0|        char *prev_type = NULL;
   63|       |
   64|      0|        if ((vs = tsk_vs_dos_open(img_info, offset, 1)) != NULL) {
  ------------------
  |  Branch (64:13): [True: 0, False: 0]
  ------------------
   65|      0|            prev_type = "DOS";
   66|      0|            prev_vs = vs;
   67|      0|        }
   68|      0|        else {
   69|      0|            tsk_error_reset();
   70|      0|        }
   71|       |        
   72|      0|        if ((vs = tsk_vs_bsd_open(img_info, offset)) != NULL) {
  ------------------
  |  Branch (72:13): [True: 0, False: 0]
  ------------------
   73|       |            // if (prev_type == NULL) {
   74|       |            // In this case, BSD takes priority because BSD partitions start off with
   75|       |            // the DOS magic value in the first sector with the boot code.
   76|      0|            prev_type = "BSD";
   77|      0|            prev_vs = vs;
   78|       |            /*
   79|       |               }
   80|       |               else {
   81|       |               prev_vs->close(prev_vs);
   82|       |               vs->close(vs);
   83|       |               tsk_error_reset();
   84|       |               tsk_error_set_errno(TSK_ERR_VS_UNKTYPE);
   85|       |               tsk_error_set_errstr(
   86|       |               "BSD or %s at %" PRIuDADDR, prev_type, offset);
   87|       |               tsk_errstr2[0] = '\0';
   88|       |               return NULL;
   89|       |               }
   90|       |             */
   91|      0|        }
   92|      0|        else {
   93|      0|            tsk_error_reset();
   94|      0|        }
   95|       |        
   96|      0|        if ((vs = tsk_vs_gpt_open(img_info, offset)) != NULL) {
  ------------------
  |  Branch (96:13): [True: 0, False: 0]
  ------------------
   97|       |
   98|      0|            if ((prev_type != NULL) && (strcmp(prev_type, "DOS") == 0) && (vs->is_backup)) {
  ------------------
  |  Branch (98:17): [True: 0, False: 0]
  |  Branch (98:40): [True: 0, False: 0]
  |  Branch (98:75): [True: 0, False: 0]
  ------------------
   99|       |                /* In this case we've found a DOS partition and a backup GPT partition.
  100|       |                 * The DOS partition takes priority in this case (and are already in prev_type and prev_vs) */
  101|      0|                vs->close(vs);
  102|      0|                if (tsk_verbose)
  ------------------
  |  Branch (102:21): [True: 0, False: 0]
  ------------------
  103|      0|                    tsk_fprintf(stderr,
  104|      0|                        "mm_open: Ignoring secondary GPT Partition\n");
  105|      0|            }
  106|      0|            else {
  107|      0|                if (prev_type != NULL) {
  ------------------
  |  Branch (107:21): [True: 0, False: 0]
  ------------------
  108|       |
  109|       |                    /* GPT drives have a DOS Safety partition table.
  110|       |                     * Test to see if the GPT has a safety partiiton
  111|       |                     * and then we can igore the DOS */
  112|      0|                    if (strcmp(prev_type, "DOS") == 0) {
  ------------------
  |  Branch (112:25): [True: 0, False: 0]
  ------------------
  113|      0|                        TSK_VS_PART_INFO *tmp_set;
  114|      0|                        for (tmp_set = prev_vs->part_list; tmp_set;
  ------------------
  |  Branch (114:60): [True: 0, False: 0]
  ------------------
  115|      0|                            tmp_set = tmp_set->next) {
  116|      0|                            if ((tmp_set->desc)
  ------------------
  |  Branch (116:33): [True: 0, False: 0]
  ------------------
  117|      0|                                && (strncmp(tmp_set->desc, "GPT Safety",
  ------------------
  |  Branch (117:36): [True: 0, False: 0]
  ------------------
  118|      0|                                    10) == 0)
  119|      0|                                && (tmp_set->start <= 63)) {
  ------------------
  |  Branch (119:36): [True: 0, False: 0]
  ------------------
  120|       |
  121|      0|                                if (tsk_verbose)
  ------------------
  |  Branch (121:37): [True: 0, False: 0]
  ------------------
  122|      0|                                    tsk_fprintf(stderr,
  123|      0|                                        "mm_open: Ignoring DOS Safety GPT Partition\n");
  124|      0|                                prev_type = NULL;
  125|      0|                                prev_vs->close(prev_vs);
  126|      0|                                prev_vs = NULL;
  127|      0|                                break;
  128|      0|                            }
  129|      0|                        }
  130|      0|                    }
  131|       |
  132|       |                    /* If we never found the safety, then we have a conflict. */
  133|      0|                    if (prev_type != NULL) {
  ------------------
  |  Branch (133:25): [True: 0, False: 0]
  ------------------
  134|      0|                        prev_vs->close(prev_vs);
  135|      0|                        vs->close(vs);
  136|      0|                        tsk_error_reset();
  137|      0|                        tsk_error_set_errno(TSK_ERR_VS_MULTTYPE);
  ------------------
  |  |  336|      0|#define TSK_ERR_VS_MULTTYPE     (TSK_ERR_VS | 9)
  |  |  ------------------
  |  |  |  |  300|      0|#define TSK_ERR_VS	0x04000000
  |  |  ------------------
  ------------------
  138|      0|                        tsk_error_set_errstr("GPT or %s at %" PRIuDADDR, prev_type,
  ------------------
  |  |  264|      0|#define PRIuDADDR   PRIu64
  ------------------
  139|      0|                            offset);
  140|      0|                        return NULL;
  141|      0|                    }
  142|      0|                }
  143|      0|                prev_type = "GPT";
  144|      0|                prev_vs = vs;
  145|      0|            }
  146|      0|        }
  147|      0|        else {
  148|      0|            tsk_error_reset();
  149|      0|        }
  150|       |
  151|      0|        if ((vs = tsk_vs_sun_open(img_info, offset)) != NULL) {
  ------------------
  |  Branch (151:13): [True: 0, False: 0]
  ------------------
  152|      0|            if (prev_type == NULL) {
  ------------------
  |  Branch (152:17): [True: 0, False: 0]
  ------------------
  153|      0|                prev_type = "Sun";
  154|      0|                prev_vs = vs;
  155|      0|            }
  156|      0|            else {
  157|      0|                prev_vs->close(prev_vs);
  158|      0|                vs->close(vs);
  159|      0|                tsk_error_reset();
  160|      0|                tsk_error_set_errno(TSK_ERR_VS_MULTTYPE);
  ------------------
  |  |  336|      0|#define TSK_ERR_VS_MULTTYPE     (TSK_ERR_VS | 9)
  |  |  ------------------
  |  |  |  |  300|      0|#define TSK_ERR_VS	0x04000000
  |  |  ------------------
  ------------------
  161|      0|                tsk_error_set_errstr("Sun or %s at %" PRIuDADDR, prev_type,
  ------------------
  |  |  264|      0|#define PRIuDADDR   PRIu64
  ------------------
  162|      0|                    offset);
  163|      0|                return NULL;
  164|      0|            }
  165|      0|        }
  166|      0|        else {
  167|      0|            tsk_error_reset();
  168|      0|        }
  169|       |
  170|      0|        if ((vs = tsk_vs_mac_open(img_info, offset)) != NULL) {
  ------------------
  |  Branch (170:13): [True: 0, False: 0]
  ------------------
  171|      0|            if (prev_type == NULL) {
  ------------------
  |  Branch (171:17): [True: 0, False: 0]
  ------------------
  172|      0|                prev_type = "Mac";
  173|      0|                prev_vs = vs;
  174|      0|            }
  175|      0|            else {
  176|      0|                prev_vs->close(prev_vs);
  177|      0|                vs->close(vs);
  178|      0|                tsk_error_reset();
  179|      0|                tsk_error_set_errno(TSK_ERR_VS_MULTTYPE);
  ------------------
  |  |  336|      0|#define TSK_ERR_VS_MULTTYPE     (TSK_ERR_VS | 9)
  |  |  ------------------
  |  |  |  |  300|      0|#define TSK_ERR_VS	0x04000000
  |  |  ------------------
  ------------------
  180|      0|                tsk_error_set_errstr("Mac or %s at %" PRIuDADDR, prev_type,
  ------------------
  |  |  264|      0|#define PRIuDADDR   PRIu64
  ------------------
  181|      0|                    offset);
  182|      0|                return NULL;
  183|      0|            }
  184|      0|        }
  185|      0|        else {
  186|      0|            tsk_error_reset();
  187|      0|        }
  188|       |
  189|      0|        if (prev_vs == NULL) {
  ------------------
  |  Branch (189:13): [True: 0, False: 0]
  ------------------
  190|      0|            tsk_error_reset();
  191|       |
  192|       |            // Check whether the volume system appears to be encrypted.
  193|       |            // Note that detectDiskEncryption does not do an entropy calculation - high entropy 
  194|       |            // files will be reported by tsk_fs_open_img().
  195|      0|            encryption_detected_result* result = detectDiskEncryption(img_info, offset);
  196|      0|            if (result != NULL) {
  ------------------
  |  Branch (196:17): [True: 0, False: 0]
  ------------------
  197|      0|                if (result->encryptionType == ENCRYPTION_DETECTED_SIGNATURE) {
  ------------------
  |  Branch (197:21): [True: 0, False: 0]
  ------------------
  198|      0|                    tsk_error_set_errno(TSK_ERR_VS_ENCRYPTED);
  ------------------
  |  |  335|      0|#define TSK_ERR_VS_ENCRYPTED    (TSK_ERR_VS | 8)
  |  |  ------------------
  |  |  |  |  300|      0|#define TSK_ERR_VS	0x04000000
  |  |  ------------------
  ------------------
  199|      0|                    tsk_error_set_errstr("%s", result->desc);
  200|      0|                }
  201|      0|                free(result);
  202|      0|                result = NULL;
  203|      0|            }
  204|      0|            else {
  205|      0|                tsk_error_set_errno(TSK_ERR_VS_UNKTYPE);
  ------------------
  |  |  327|      0|#define TSK_ERR_VS_UNKTYPE	(TSK_ERR_VS | 0)
  |  |  ------------------
  |  |  |  |  300|      0|#define TSK_ERR_VS	0x04000000
  |  |  ------------------
  ------------------
  206|      0|            }
  207|      0|            return NULL;
  208|      0|        }
  209|       |
  210|      0|        return prev_vs;
  211|      0|    }
  212|       |    
  213|       |    // Not autodetect
  214|      1|    else {
  215|       |
  216|      1|        switch (type) {
  217|      0|        case TSK_VS_TYPE_DOS:
  ------------------
  |  Branch (217:9): [True: 0, False: 1]
  ------------------
  218|      0|            return tsk_vs_dos_open(img_info, offset, 0);
  219|      0|        case TSK_VS_TYPE_MAC:
  ------------------
  |  Branch (219:9): [True: 0, False: 1]
  ------------------
  220|      0|            return tsk_vs_mac_open(img_info, offset);
  221|      0|        case TSK_VS_TYPE_BSD:
  ------------------
  |  Branch (221:9): [True: 0, False: 1]
  ------------------
  222|      0|            return tsk_vs_bsd_open(img_info, offset);
  223|      1|        case TSK_VS_TYPE_SUN:
  ------------------
  |  Branch (223:9): [True: 1, False: 0]
  ------------------
  224|      1|            return tsk_vs_sun_open(img_info, offset);
  225|      0|        case TSK_VS_TYPE_GPT:
  ------------------
  |  Branch (225:9): [True: 0, False: 1]
  ------------------
  226|      0|            return tsk_vs_gpt_open(img_info, offset);
  227|      0|        case TSK_VS_TYPE_APFS: // Not supported yet
  ------------------
  |  Branch (227:9): [True: 0, False: 1]
  ------------------
  228|      0|        case TSK_VS_TYPE_UNSUPP:
  ------------------
  |  Branch (228:9): [True: 0, False: 1]
  ------------------
  229|      0|        default:
  ------------------
  |  Branch (229:9): [True: 0, False: 1]
  ------------------
  230|      0|            tsk_error_reset();
  231|      0|            tsk_error_set_errno(TSK_ERR_VS_UNSUPTYPE);
  ------------------
  |  |  328|      0|#define TSK_ERR_VS_UNSUPTYPE	(TSK_ERR_VS | 1)
  |  |  ------------------
  |  |  |  |  300|      0|#define TSK_ERR_VS	0x04000000
  |  |  ------------------
  ------------------
  232|      0|            tsk_error_set_errstr("%d", type);
  233|      0|            return NULL;
  234|      1|        }
  235|      1|    }
  236|      1|}

tsk_vs_part_free:
  177|      1|{
  178|      1|    TSK_VS_PART_INFO *part = a_vs->part_list;
  179|      1|    TSK_VS_PART_INFO *part2;
  180|       |
  181|      1|    while (part) {
  ------------------
  |  Branch (181:12): [True: 0, False: 1]
  ------------------
  182|      0|        free(part->desc);
  183|      0|        part->tag = 0;
  184|      0|        part2 = part->next;
  185|      0|        free(part);
  186|      0|        part = part2;
  187|      0|    }
  188|      1|    a_vs->part_list = NULL;
  189|      1|}

tsk_vs_sun_open:
  353|      1|{
  354|      1|    TSK_VS_INFO *vs;
  355|       |
  356|       |    // clean up any errors that are lying around
  357|      1|    tsk_error_reset();
  358|       |
  359|      1|    if (img_info->sector_size == 0) {
  ------------------
  |  Branch (359:9): [True: 0, False: 1]
  ------------------
  360|      0|        tsk_error_reset();
  361|      0|        tsk_error_set_errno(TSK_ERR_VS_ARG);
  ------------------
  |  |  334|      0|#define TSK_ERR_VS_ARG	    (TSK_ERR_VS | 7)
  |  |  ------------------
  |  |  |  |  300|      0|#define TSK_ERR_VS	0x04000000
  |  |  ------------------
  ------------------
  362|      0|        tsk_error_set_errstr("tsk_vs_sun_open: sector size is 0");
  363|      0|        return NULL;
  364|      0|    }
  365|       |
  366|      1|    vs = (TSK_VS_INFO *) tsk_malloc(sizeof(*vs));
  367|      1|    if (vs == NULL)
  ------------------
  |  Branch (367:9): [True: 0, False: 1]
  ------------------
  368|      0|        return NULL;
  369|       |
  370|      1|    vs->img_info = img_info;
  371|      1|    vs->vstype = TSK_VS_TYPE_SUN;
  372|      1|    vs->tag = TSK_VS_INFO_TAG;
  ------------------
  |  |   82|      1|#define TSK_VS_INFO_TAG  0x52301642
  ------------------
  373|       |
  374|      1|    vs->offset = offset;
  375|       |
  376|       |    /* initialize settings */
  377|      1|    vs->part_list = NULL;
  378|      1|    vs->part_count = 0;
  379|      1|    vs->endian = 0;
  380|      1|    vs->block_size = img_info->sector_size;
  381|       |
  382|       |    /* Assign functions */
  383|      1|    vs->close = sun_close;
  384|       |
  385|       |    /* Load the partitions into the sorted list */
  386|      1|    if (sun_load_table(vs)) {
  ------------------
  |  Branch (386:9): [True: 1, False: 0]
  ------------------
  387|      1|        sun_close(vs);
  388|      1|        return NULL;
  389|      1|    }
  390|       |
  391|       |    /* fill in the sorted list with the 'unknown' values */
  392|      0|    if (tsk_vs_part_unused(vs)) {
  ------------------
  |  Branch (392:9): [True: 0, False: 0]
  ------------------
  393|      0|        sun_close(vs);
  394|      0|        return NULL;
  395|      0|    }
  396|       |
  397|      0|    return vs;
  398|      0|}
sun.c:sun_close:
  345|      1|{
  346|      1|    vs->tag = 0;
  347|      1|    tsk_vs_part_free(vs);
  348|      1|    free(vs);
  349|      1|}
sun.c:sun_load_table:
  221|      1|{
  222|      1|    sun_dlabel_sparc *dlabel_sp;
  223|      1|    sun_dlabel_i386 *dlabel_x86;
  224|      1|    char *buf;
  225|      1|    ssize_t cnt;
  226|      1|    TSK_DADDR_T taddr =
  227|      1|        vs->offset / vs->block_size + SUN_SPARC_PART_SOFFSET;
  ------------------
  |  |  115|      1|#define SUN_SPARC_PART_SOFFSET	0
  ------------------
  228|      1|    int result = 0;
  229|       |
  230|       |
  231|       |    /* Sanity check in case label sizes change */
  232|      1|    if ((sizeof(*dlabel_sp) > vs->block_size) ||
  ------------------
  |  Branch (232:9): [True: 0, False: 1]
  ------------------
  233|      1|        (sizeof(*dlabel_x86) > vs->block_size)) {
  ------------------
  |  Branch (233:9): [True: 0, False: 1]
  ------------------
  234|      0|        tsk_error_reset();
  235|      0|        tsk_error_set_errno(TSK_ERR_VS_BUF);
  ------------------
  |  |  332|      0|#define TSK_ERR_VS_BUF		(TSK_ERR_VS | 5)
  |  |  ------------------
  |  |  |  |  300|      0|#define TSK_ERR_VS	0x04000000
  |  |  ------------------
  ------------------
  236|      0|        tsk_error_set_errstr
  237|      0|            ("sun_load_table: disk labels bigger than block size");
  238|      0|        return 1;
  239|      0|    }
  240|       |
  241|      1|    if (tsk_verbose)
  ------------------
  |  Branch (241:9): [True: 0, False: 1]
  ------------------
  242|      0|        tsk_fprintf(stderr,
  243|      0|            "sun_load_table: Trying sector: %" PRIuDADDR "\n", taddr);
  244|       |
  245|      1|    if ((buf = tsk_malloc(vs->block_size)) == NULL) {
  ------------------
  |  Branch (245:9): [True: 0, False: 1]
  ------------------
  246|      0|        goto on_error;
  247|      0|    }
  248|       |
  249|       |    /* Try the given offset */
  250|      1|    cnt = tsk_vs_read_block
  251|      1|        (vs, SUN_SPARC_PART_SOFFSET, buf, vs->block_size);
  ------------------
  |  |  115|      1|#define SUN_SPARC_PART_SOFFSET	0
  ------------------
  252|       |
  253|       |    /* If -1 is returned, tsk_errno is already set */
  254|      1|    if (cnt != vs->block_size) {
  ------------------
  |  Branch (254:9): [True: 0, False: 1]
  ------------------
  255|      0|        if (cnt >= 0) {
  ------------------
  |  Branch (255:13): [True: 0, False: 0]
  ------------------
  256|      0|            tsk_error_reset();
  257|      0|            tsk_error_set_errno(TSK_ERR_VS_READ);
  ------------------
  |  |  329|      0|#define TSK_ERR_VS_READ		(TSK_ERR_VS | 2)
  |  |  ------------------
  |  |  |  |  300|      0|#define TSK_ERR_VS	0x04000000
  |  |  ------------------
  ------------------
  258|      0|        }
  259|      0|        tsk_error_set_errstr2("SUN Disk Label in Sector: %" PRIuDADDR,
  ------------------
  |  |  264|      0|#define PRIuDADDR   PRIu64
  ------------------
  260|      0|            taddr);
  261|      0|        goto on_error;
  262|      0|    }
  263|       |
  264|       |
  265|       |    /* Check the magic value 
  266|       |     * Both intel and sparc have the magic value in the same location
  267|       |     *
  268|       |     * We try both in case someone specifies the exact location of the
  269|       |     * intel disk label.
  270|       |     * */
  271|      1|    dlabel_sp = (sun_dlabel_sparc *) buf;
  272|      1|    dlabel_x86 = (sun_dlabel_i386 *) buf;
  273|      1|    if (tsk_vs_guessu16(vs, dlabel_sp->magic, SUN_MAGIC) == 0) {
  ------------------
  |  |   40|      1|    tsk_guess_end_u16(&(vs->endian), (x), (mag))
  ------------------
  |  Branch (273:9): [True: 0, False: 1]
  ------------------
  274|      0|        if (tsk_getu32(vs->endian, dlabel_sp->sanity) == SUN_SANITY) {
  ------------------
  |  |  119|      0|#define tsk_getu32(endian, x)	\
  |  |  120|      0|(uint32_t)( ((endian) == TSK_LIT_ENDIAN)  ?	\
  |  |  ------------------
  |  |  |  Branch (120:13): [True: 0, False: 0]
  |  |  ------------------
  |  |  121|      0|            ((((uint8_t *)(x))[0] <<  0) + \
  |  |  122|      0|             (((uint8_t *)(x))[1] <<  8) + \
  |  |  123|      0|             (((uint8_t *)(x))[2] << 16) + \
  |  |  124|      0|             ((uint32_t)((uint8_t *)(x))[3] << 24) ) \
  |  |  125|      0|                                          :	\
  |  |  126|      0|            ((((uint8_t *)(x))[3] <<  0) + \
  |  |  127|      0|             (((uint8_t *)(x))[2] <<  8) + \
  |  |  128|      0|             (((uint8_t *)(x))[1] << 16) + \
  |  |  129|      0|             ((uint32_t)((uint8_t *)(x))[0] << 24) ) )
  ------------------
                      if (tsk_getu32(vs->endian, dlabel_sp->sanity) == SUN_SANITY) {
  ------------------
  |  |  110|      0|#define SUN_SANITY	0x600DDEEE
  ------------------
  |  Branch (274:13): [True: 0, False: 0]
  ------------------
  275|      0|            result = sun_load_table_sparc(vs, dlabel_sp);
  276|       |            // TODO: I assume based on the existing free that the previous function
  277|       |            // does not take ownership of buf.
  278|      0|            free(buf);
  279|      0|            return result;
  280|      0|        }
  281|      0|        else if (tsk_getu32(vs->endian, dlabel_x86->sanity) == SUN_SANITY) {
  ------------------
  |  |  119|      0|#define tsk_getu32(endian, x)	\
  |  |  120|      0|(uint32_t)( ((endian) == TSK_LIT_ENDIAN)  ?	\
  |  |  ------------------
  |  |  |  Branch (120:13): [True: 0, False: 0]
  |  |  ------------------
  |  |  121|      0|            ((((uint8_t *)(x))[0] <<  0) + \
  |  |  122|      0|             (((uint8_t *)(x))[1] <<  8) + \
  |  |  123|      0|             (((uint8_t *)(x))[2] << 16) + \
  |  |  124|      0|             ((uint32_t)((uint8_t *)(x))[3] << 24) ) \
  |  |  125|      0|                                          :	\
  |  |  126|      0|            ((((uint8_t *)(x))[3] <<  0) + \
  |  |  127|      0|             (((uint8_t *)(x))[2] <<  8) + \
  |  |  128|      0|             (((uint8_t *)(x))[1] << 16) + \
  |  |  129|      0|             ((uint32_t)((uint8_t *)(x))[0] << 24) ) )
  ------------------
                      else if (tsk_getu32(vs->endian, dlabel_x86->sanity) == SUN_SANITY) {
  ------------------
  |  |  110|      0|#define SUN_SANITY	0x600DDEEE
  ------------------
  |  Branch (281:18): [True: 0, False: 0]
  ------------------
  282|      0|            result = sun_load_table_i386(vs, dlabel_x86);
  283|       |            // TODO: I assume based on the existing free that the previous function
  284|       |            // does not take ownership of buf.
  285|      0|            free(buf);
  286|      0|            return result;
  287|      0|        }
  288|      0|    }
  289|       |
  290|       |
  291|       |    /* Now try the next sector, which is where the intel 
  292|       |     * could be stored */
  293|       |
  294|      1|    taddr = vs->offset / vs->block_size / SUN_I386_PART_SOFFSET;
  ------------------
  |  |  116|      1|#define SUN_I386_PART_SOFFSET	1
  ------------------
  295|      1|    if (tsk_verbose)
  ------------------
  |  Branch (295:9): [True: 0, False: 1]
  ------------------
  296|      0|        tsk_fprintf(stderr,
  297|      0|            "sun_load_table: Trying sector: %" PRIuDADDR "\n", taddr + 1);
  298|       |
  299|      1|    cnt = tsk_vs_read_block
  300|      1|        (vs, SUN_I386_PART_SOFFSET, buf, vs->block_size);
  ------------------
  |  |  116|      1|#define SUN_I386_PART_SOFFSET	1
  ------------------
  301|       |
  302|      1|    if (cnt != vs->block_size) {
  ------------------
  |  Branch (302:9): [True: 0, False: 1]
  ------------------
  303|      0|        if (cnt >= 0) {
  ------------------
  |  Branch (303:13): [True: 0, False: 0]
  ------------------
  304|      0|            tsk_error_reset();
  305|      0|            tsk_error_set_errno(TSK_ERR_VS_READ);
  ------------------
  |  |  329|      0|#define TSK_ERR_VS_READ		(TSK_ERR_VS | 2)
  |  |  ------------------
  |  |  |  |  300|      0|#define TSK_ERR_VS	0x04000000
  |  |  ------------------
  ------------------
  306|      0|        }
  307|      0|        tsk_error_set_errstr2("SUN (Intel) Disk Label in Sector: %"
  308|      0|            PRIuDADDR, taddr);
  ------------------
  |  |  264|      0|#define PRIuDADDR   PRIu64
  ------------------
  309|      0|        goto on_error;
  310|      0|    }
  311|       |
  312|      1|    dlabel_x86 = (sun_dlabel_i386 *) buf;
  313|      1|    if (tsk_vs_guessu16(vs, dlabel_x86->magic, SUN_MAGIC)) {
  ------------------
  |  |   40|      1|    tsk_guess_end_u16(&(vs->endian), (x), (mag))
  |  |  ------------------
  |  |  |  Branch (40:5): [True: 1, False: 0]
  |  |  ------------------
  ------------------
  314|      1|        tsk_error_reset();
  315|      1|        tsk_error_set_errno(TSK_ERR_VS_MAGIC);
  ------------------
  |  |  330|      1|#define TSK_ERR_VS_MAGIC	(TSK_ERR_VS | 3)
  |  |  ------------------
  |  |  |  |  300|      1|#define TSK_ERR_VS	0x04000000
  |  |  ------------------
  ------------------
  316|      1|        tsk_error_set_errstr("SUN (intel) partition table (Sector: %"
  317|      1|            PRIuDADDR ") %x", taddr, tsk_getu16(vs->endian,
  ------------------
  |  |   86|      1|#define tsk_getu16(endian, x)   \
  |  |   87|      1|(uint16_t)(((endian) == TSK_LIT_ENDIAN) ? \
  |  |  ------------------
  |  |  |  Branch (87:12): [True: 0, False: 1]
  |  |  ------------------
  |  |   88|      1|           (((uint8_t *)(x))[0] + (((uint8_t *)(x))[1] << 8)) :    \
  |  |   89|      1|           (((uint8_t *)(x))[1] + (((uint8_t *)(x))[0] << 8)) )
  ------------------
  318|      1|                dlabel_sp->magic));
  319|      1|        goto on_error;
  320|      1|    }
  321|       |
  322|      0|    if (tsk_getu32(vs->endian, dlabel_x86->sanity) != SUN_SANITY) {
  ------------------
  |  |  119|      0|#define tsk_getu32(endian, x)	\
  |  |  120|      0|(uint32_t)( ((endian) == TSK_LIT_ENDIAN)  ?	\
  |  |  ------------------
  |  |  |  Branch (120:13): [True: 0, False: 0]
  |  |  ------------------
  |  |  121|      0|            ((((uint8_t *)(x))[0] <<  0) + \
  |  |  122|      0|             (((uint8_t *)(x))[1] <<  8) + \
  |  |  123|      0|             (((uint8_t *)(x))[2] << 16) + \
  |  |  124|      0|             ((uint32_t)((uint8_t *)(x))[3] << 24) ) \
  |  |  125|      0|                                          :	\
  |  |  126|      0|            ((((uint8_t *)(x))[3] <<  0) + \
  |  |  127|      0|             (((uint8_t *)(x))[2] <<  8) + \
  |  |  128|      0|             (((uint8_t *)(x))[1] << 16) + \
  |  |  129|      0|             ((uint32_t)((uint8_t *)(x))[0] << 24) ) )
  ------------------
                  if (tsk_getu32(vs->endian, dlabel_x86->sanity) != SUN_SANITY) {
  ------------------
  |  |  110|      0|#define SUN_SANITY	0x600DDEEE
  ------------------
  |  Branch (322:9): [True: 0, False: 0]
  ------------------
  323|      0|        tsk_error_reset();
  324|      0|        tsk_error_set_errno(TSK_ERR_VS_MAGIC);
  ------------------
  |  |  330|      0|#define TSK_ERR_VS_MAGIC	(TSK_ERR_VS | 3)
  |  |  ------------------
  |  |  |  |  300|      0|#define TSK_ERR_VS	0x04000000
  |  |  ------------------
  ------------------
  325|      0|        tsk_error_set_errstr("SUN (intel) sanity value (Sector: %"
  326|      0|            PRIuDADDR ") %x", taddr, tsk_getu16(vs->endian,
  ------------------
  |  |   86|      0|#define tsk_getu16(endian, x)   \
  |  |   87|      0|(uint16_t)(((endian) == TSK_LIT_ENDIAN) ? \
  |  |  ------------------
  |  |  |  Branch (87:12): [True: 0, False: 0]
  |  |  ------------------
  |  |   88|      0|           (((uint8_t *)(x))[0] + (((uint8_t *)(x))[1] << 8)) :    \
  |  |   89|      0|           (((uint8_t *)(x))[1] + (((uint8_t *)(x))[0] << 8)) )
  ------------------
  327|      0|                dlabel_sp->magic));
  328|      0|        goto on_error;
  329|      0|    }
  330|       |
  331|      0|    result = sun_load_table_i386(vs, dlabel_x86);
  332|       |    // TODO: I assume based on the existing free that the previous function
  333|       |    // does not take ownership of buf.
  334|      0|    free(buf);
  335|      0|    return result;
  336|       |
  337|      1|on_error:
  338|      1|    free(buf);
  339|      1|    return 1;
  340|      0|}

LLVMFuzzerTestOneInput:
   30|      1|extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   31|      1|  TSK_IMG_INFO *img;
   32|      1|  TSK_VS_INFO *vs;
   33|       |
   34|      1|  img = mem_open(data, size);
   35|      1|  if (img == nullptr)
  ------------------
  |  Branch (35:7): [True: 0, False: 1]
  ------------------
   36|      0|    return 0;
   37|       |
   38|      1|  vs = tsk_vs_open(img, 0, VSTYPE);
   39|      1|  if (vs != nullptr) {
  ------------------
  |  Branch (39:7): [True: 0, False: 1]
  ------------------
   40|      0|    tsk_vs_part_walk(vs, 0, vs->part_count - 1, TSK_VS_PART_FLAG_ALL, part_act,
   41|      0|                     nullptr);
   42|       |
   43|      0|    tsk_vs_close(vs);
   44|      0|  }
   45|       |
   46|      1|  img->close(img);
   47|      1|  return 0;
   48|      1|}

