_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|      3|{
   30|      3|    void *ptr;
   31|       |
   32|      3|    if ((ptr = calloc(len, 1)) == 0) {
  ------------------
  |  Branch (32:9): [True: 0, False: 3]
  ------------------
   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|      3|    return ptr;
   39|      3|}

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|      7|{
  149|      7|    TSK_ERROR_INFO *ptr = NULL;
  150|      7|    (void) pthread_once(&pt_tls_key_once, make_pt_tls_key);
  151|      7|    if ((ptr = (TSK_ERROR_INFO *) pthread_getspecific(pt_tls_key)) == 0) {
  ------------------
  |  Branch (151:9): [True: 1, False: 6]
  ------------------
  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|      7|    return ptr;
  163|      7|}
tsk_error_set_errno:
  308|      2|{
  309|      2|    tsk_error_get_info()->t_errno = t_errno;
  310|      2|}
tsk_error_set_errstr:
  332|      2|{
  333|      2|    va_list args;
  334|      2|    va_start(args, format);
  335|      2|    vsnprintf(tsk_error_get_info()->errstr, TSK_ERROR_STRING_MAX_LENGTH,
  ------------------
  |  |   67|      2|#define TSK_ERROR_STRING_MAX_LENGTH 1024
  ------------------
  336|      2|        format, args);
  337|      2|    va_end(args);
  338|      2|}
tsk_error_reset:
  444|      3|{
  445|      3|    TSK_ERROR_INFO *info = tsk_error_get_info();
  446|       |
  447|      3|    if( info != NULL ) {
  ------------------
  |  Branch (447:9): [True: 3, False: 0]
  ------------------
  448|      3|       info->t_errno = 0;
  449|      3|       info->errstr[0] = 0;
  450|      3|       info->errstr2[0] = 0;
  451|      3|       info->errstr_print[0] = 0;
  452|      3|    }
  453|      3|}
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_mac_open:
  193|      1|{
  194|      1|    TSK_VS_INFO *vs;
  195|       |
  196|       |    // clean up any errors that are lying around
  197|      1|    tsk_error_reset();
  198|       |
  199|      1|    if (img_info->sector_size == 0) {
  ------------------
  |  Branch (199:9): [True: 0, False: 1]
  ------------------
  200|      0|        tsk_error_reset();
  201|      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
  |  |  ------------------
  ------------------
  202|      0|        tsk_error_set_errstr("tsk_vs_mac_open: sector size is 0");
  203|      0|        return NULL;
  204|      0|    }
  205|       |
  206|      1|    vs = (TSK_VS_INFO *) tsk_malloc(sizeof(*vs));
  207|      1|    if (vs == NULL)
  ------------------
  |  Branch (207:9): [True: 0, False: 1]
  ------------------
  208|      0|        return NULL;
  209|       |
  210|      1|    vs->img_info = img_info;
  211|      1|    vs->vstype = TSK_VS_TYPE_MAC;
  212|      1|    vs->tag = TSK_VS_INFO_TAG;
  ------------------
  |  |   82|      1|#define TSK_VS_INFO_TAG  0x52301642
  ------------------
  213|       |
  214|       |    /* If an offset was given, then use that too */
  215|      1|    vs->offset = offset;
  216|       |
  217|       |    //vs->sect_offset = offset + MAC_PART_OFFSET;
  218|       |
  219|       |    /* initialize settings */
  220|      1|    vs->part_list = NULL;
  221|      1|    vs->part_count = 0;
  222|      1|    vs->endian = 0;
  223|      1|    vs->block_size = img_info->sector_size;
  224|       |
  225|       |    /* Assign functions */
  226|      1|    vs->close = mac_close;
  227|       |
  228|       |    /* Load the partitions into the sorted list */
  229|      1|    if (mac_load_table(vs)) {
  ------------------
  |  Branch (229:9): [True: 1, False: 0]
  ------------------
  230|       |
  231|       |        // try some other sector sizes
  232|      1|        uint8_t returnNull = 1;
  233|      1|        if (vs->block_size == 512) {
  ------------------
  |  Branch (233:13): [True: 1, False: 0]
  ------------------
  234|      1|            if (tsk_verbose)
  ------------------
  |  Branch (234:17): [True: 0, False: 1]
  ------------------
  235|      0|                tsk_fprintf(stderr,
  236|      0|                    "mac_open: Trying 4096-byte sector size instead of 512-byte\n");
  237|      1|            vs->block_size = 4096;
  238|      1|            returnNull = mac_load_table(vs);
  239|      1|        }
  240|      0|        else if (vs->block_size == 4096) {
  ------------------
  |  Branch (240:18): [True: 0, False: 0]
  ------------------
  241|      0|            if (tsk_verbose)
  ------------------
  |  Branch (241:17): [True: 0, False: 0]
  ------------------
  242|      0|                tsk_fprintf(stderr,
  243|      0|                    "mac_open: Trying 512-byte sector size instead of 4096-byte\n");
  244|      0|            vs->block_size = 512;
  245|      0|            returnNull = mac_load_table(vs);
  246|      0|        }
  247|       |
  248|      1|        if (returnNull) {
  ------------------
  |  Branch (248:13): [True: 1, False: 0]
  ------------------
  249|      1|            mac_close(vs);
  250|      1|            return NULL;
  251|      1|        }
  252|      1|    }
  253|       |
  254|       |    /* fill in the sorted list with the 'unknown' values */
  255|      0|    if (tsk_vs_part_unused(vs)) {
  ------------------
  |  Branch (255:9): [True: 0, False: 0]
  ------------------
  256|      0|        mac_close(vs);
  257|      0|        return NULL;
  258|      0|    }
  259|       |
  260|      0|    return vs;
  261|      0|}
mac.c:mac_close:
  181|      1|{
  182|      1|    vs->tag = 0;
  183|      1|    tsk_vs_part_free(vs);
  184|      1|    free(vs);
  185|      1|}
mac.c:mac_load_table:
   27|      2|{
   28|      2|    char *part_buf;
   29|      2|    mac_part *part;
   30|      2|    char *table_str;
   31|      2|    uint32_t idx, max_part;
   32|      2|    TSK_DADDR_T taddr = vs->offset / vs->block_size + MAC_PART_SOFFSET;
  ------------------
  |  |   44|      2|#define MAC_PART_SOFFSET	1
  ------------------
   33|      2|    TSK_DADDR_T max_addr = (vs->img_info->size - vs->offset) / vs->block_size;  // max sector
   34|       |
   35|      2|    if (tsk_verbose)
  ------------------
  |  Branch (35:9): [True: 0, False: 2]
  ------------------
   36|      0|        tsk_fprintf(stderr, "mac_load_table: Sector: %" PRIuDADDR "\n",
   37|      0|            taddr);
   38|       |
   39|       |    /* The table can be variable length, so we loop on it 
   40|       |     * The idx variable shows which round it is
   41|       |     * Each structure is a block size
   42|       |     */
   43|      2|    if ((part_buf = tsk_malloc(vs->block_size)) == NULL)
  ------------------
  |  Branch (43:9): [True: 0, False: 2]
  ------------------
   44|      0|        return 1;
   45|      2|    part = (mac_part *) part_buf;
   46|       |
   47|      2|    max_part = 1;               /* set it to 1 and it will be set in the first loop */
   48|      2|    for (idx = 0; idx < max_part; idx++) {
  ------------------
  |  Branch (48:19): [True: 2, False: 0]
  ------------------
   49|      2|        uint32_t part_start;
   50|      2|        uint32_t part_size;
   51|      2|        uint32_t part_status;
   52|      2|        char *str;
   53|      2|        ssize_t cnt;
   54|      2|        int flag = 0;
   55|       |
   56|       |
   57|       |        /* Read the entry */
   58|      2|        cnt = tsk_vs_read_block
   59|      2|            (vs, MAC_PART_SOFFSET + idx, part_buf, vs->block_size);
  ------------------
  |  |   44|      2|#define MAC_PART_SOFFSET	1
  ------------------
   60|       |
   61|       |        /* If -1, then tsk_errno is already set */
   62|      2|        if (cnt != vs->block_size) {
  ------------------
  |  Branch (62:13): [True: 0, False: 2]
  ------------------
   63|      0|            if (cnt >= 0) {
  ------------------
  |  Branch (63:17): [True: 0, False: 0]
  ------------------
   64|      0|                tsk_error_reset();
   65|      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
  |  |  ------------------
  ------------------
   66|      0|            }
   67|      0|            tsk_error_set_errstr2("MAC Partition entry %" PRIuDADDR,
  ------------------
  |  |  264|      0|#define PRIuDADDR   PRIu64
  ------------------
   68|      0|                taddr + idx);
   69|      0|            free(part_buf);
   70|      0|            return 1;
   71|      0|        }
   72|       |
   73|       |
   74|       |        /* Sanity Check */
   75|      2|        if (idx == 0) {
  ------------------
  |  Branch (75:13): [True: 2, False: 0]
  ------------------
   76|       |            /* Set the endian ordering the first time around */
   77|      2|            if (tsk_vs_guessu16(vs, part->magic, MAC_MAGIC)) {
  ------------------
  |  |   40|      2|    tsk_guess_end_u16(&(vs->endian), (x), (mag))
  |  |  ------------------
  |  |  |  Branch (40:5): [True: 2, False: 0]
  |  |  ------------------
  ------------------
   78|      2|                tsk_error_reset();
   79|      2|                tsk_error_set_errno(TSK_ERR_VS_MAGIC);
  ------------------
  |  |  330|      2|#define TSK_ERR_VS_MAGIC	(TSK_ERR_VS | 3)
  |  |  ------------------
  |  |  |  |  300|      2|#define TSK_ERR_VS	0x04000000
  |  |  ------------------
  ------------------
   80|      2|                tsk_error_set_errstr("Mac partition table entry (Sector: %"
   81|      2|                    PRIuDADDR ") %" PRIx16,
   82|      2|                    (taddr + idx), tsk_getu16(vs->endian, part->magic));
  ------------------
  |  |   86|      2|#define tsk_getu16(endian, x)   \
  |  |   87|      2|(uint16_t)(((endian) == TSK_LIT_ENDIAN) ? \
  |  |  ------------------
  |  |  |  Branch (87:12): [True: 0, False: 2]
  |  |  ------------------
  |  |   88|      2|           (((uint8_t *)(x))[0] + (((uint8_t *)(x))[1] << 8)) :    \
  |  |   89|      2|           (((uint8_t *)(x))[1] + (((uint8_t *)(x))[0] << 8)) )
  ------------------
   83|      2|                if (tsk_verbose)
  ------------------
  |  Branch (83:21): [True: 0, False: 2]
  ------------------
   84|      0|                    tsk_fprintf(stderr,
   85|      0|                        "mac_load: Missing initial magic value\n");
   86|      2|                free(part_buf);
   87|      2|                return 1;
   88|      2|            }
   89|       |
   90|       |            /* Get the number of partitions */
   91|      0|            max_part = tsk_getu32(vs->endian, part->pmap_size);
  ------------------
  |  |  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) ) )
  ------------------
   92|      0|        }
   93|      0|        else if (tsk_getu16(vs->endian, part->magic) != MAC_MAGIC) {
  ------------------
  |  |   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)) )
  ------------------
                      else if (tsk_getu16(vs->endian, part->magic) != MAC_MAGIC) {
  ------------------
  |  |   43|      0|#define MAC_MAGIC	0x504d
  ------------------
  |  Branch (93:18): [True: 0, False: 0]
  ------------------
   94|      0|            tsk_error_reset();
   95|      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
  |  |  ------------------
  ------------------
   96|      0|            tsk_error_set_errstr("Mac partition table entry (Sector: %"
   97|      0|                PRIuDADDR ") %" PRIx16, (taddr + idx),
   98|      0|                tsk_getu16(vs->endian, part->magic));
  ------------------
  |  |   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)) )
  ------------------
   99|      0|            if (tsk_verbose)
  ------------------
  |  Branch (99:17): [True: 0, False: 0]
  ------------------
  100|      0|                tsk_fprintf(stderr,
  101|      0|                    "mac_load: Missing magic value in entry %" PRIu32 "\n",
  102|      0|                    idx);
  103|      0|            free(part_buf);
  104|      0|            return 1;
  105|      0|        }
  106|       |
  107|       |
  108|      0|        part_start = tsk_getu32(vs->endian, part->start_sec);
  ------------------
  |  |  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) ) )
  ------------------
  109|      0|        part_size = tsk_getu32(vs->endian, part->size_sec);
  ------------------
  |  |  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) ) )
  ------------------
  110|      0|        part_status = tsk_getu32(vs->endian, part->status);
  ------------------
  |  |  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) ) )
  ------------------
  111|       |
  112|      0|        if (tsk_verbose)
  ------------------
  |  Branch (112:13): [True: 0, False: 0]
  ------------------
  113|      0|            tsk_fprintf(stderr,
  114|      0|                "mac_load: %" PRIu32 "  Starting Sector: %" PRIu32
  115|      0|                "  Size: %" PRIu32 " Type: %s Status: %"PRIu32"\n", idx, part_start,
  116|      0|                part_size, part->type, part_status);
  117|       |
  118|      0|        if (part_size == 0)
  ------------------
  |  Branch (118:13): [True: 0, False: 0]
  ------------------
  119|      0|            continue;
  120|       |
  121|      0|        if (part_status == 0)
  ------------------
  |  Branch (121:13): [True: 0, False: 0]
  ------------------
  122|      0|            flag = TSK_VS_PART_FLAG_UNALLOC;
  123|      0|        else
  124|      0|            flag = TSK_VS_PART_FLAG_ALLOC;
  125|       |
  126|       |        // make sure the first couple are within the bounds of the image.
  127|      0|        if ((idx < 2) && (part_start > max_addr)) {
  ------------------
  |  Branch (127:13): [True: 0, False: 0]
  |  Branch (127:26): [True: 0, False: 0]
  ------------------
  128|      0|            tsk_error_reset();
  129|      0|            tsk_error_set_errno(TSK_ERR_VS_BLK_NUM);
  ------------------
  |  |  333|      0|#define TSK_ERR_VS_BLK_NUM	(TSK_ERR_VS | 6)
  |  |  ------------------
  |  |  |  |  300|      0|#define TSK_ERR_VS	0x04000000
  |  |  ------------------
  ------------------
  130|      0|            tsk_error_set_errstr
  131|      0|                ("mac_load_table: Starting sector too large for image");
  132|      0|            if (tsk_verbose)
  ------------------
  |  Branch (132:17): [True: 0, False: 0]
  ------------------
  133|      0|                tsk_fprintf(stderr,
  134|      0|                    "mac_load: Starting sector too large for image (%"
  135|      0|                    PRIu32 " vs %" PRIu32 ")\n", part_start, max_addr);
  136|      0|            free(part_buf);
  137|      0|            return 1;
  138|      0|        }
  139|       |
  140|       |
  141|      0|        if ((str = tsk_malloc(sizeof(part->name))) == NULL) {
  ------------------
  |  Branch (141:13): [True: 0, False: 0]
  ------------------
  142|      0|            free(part_buf);
  143|      0|            return 1;
  144|      0|        }
  145|       |
  146|      0|        strncpy(str, (char *) part->type, sizeof(part->name));
  147|      0|        str[sizeof(part->name) - 1] = 0;
  148|       |
  149|      0|        if (NULL == tsk_vs_part_add(vs, (TSK_DADDR_T) part_start,
  ------------------
  |  Branch (149:13): [True: 0, False: 0]
  ------------------
  150|      0|                (TSK_DADDR_T) part_size, (TSK_VS_PART_FLAG_ENUM)flag, str, -1,
  151|      0|                idx)) {
  152|      0|            free(part_buf);
  153|      0|            return 1;
  154|      0|        }
  155|      0|    }
  156|      0|    free(part_buf);
  157|      0|    part_buf = NULL;
  158|       |
  159|       |    // Bail if we didn't find any valid entries
  160|      0|    if (vs->part_count == 0) {
  ------------------
  |  Branch (160:9): [True: 0, False: 0]
  ------------------
  161|      0|        return 1;
  162|      0|    }
  163|       |
  164|       |    /* Add an entry for the table length */
  165|      0|    if ((table_str = tsk_malloc(16)) == NULL) {
  ------------------
  |  Branch (165:9): [True: 0, False: 0]
  ------------------
  166|      0|        return 1;
  167|      0|    }
  168|       |
  169|      0|    snprintf(table_str, 16, "Table");
  170|      0|    if (NULL == tsk_vs_part_add(vs, taddr, max_part, TSK_VS_PART_FLAG_META,
  ------------------
  |  Branch (170:9): [True: 0, False: 0]
  ------------------
  171|      0|            table_str, -1, -1)) {
  172|      0|        return 1;
  173|      0|    }
  174|       |
  175|      0|    return 0;
  176|      0|}

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|      1|        case TSK_VS_TYPE_MAC:
  ------------------
  |  Branch (219:9): [True: 1, False: 0]
  ------------------
  220|      1|            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|      0|        case TSK_VS_TYPE_SUN:
  ------------------
  |  Branch (223:9): [True: 0, False: 1]
  ------------------
  224|      0|            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|}

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|}

