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

_Z14hexDigitToCharc:
   85|    256|{
   86|    256|  if (ch > 47 && ch < 58)
  ------------------
  |  Branch (86:7): [True: 256, False: 0]
  |  Branch (86:18): [True: 148, False: 108]
  ------------------
   87|    148|    return ch - 48;
   88|       |
   89|    108|  if (ch > 96 && ch < 103)
  ------------------
  |  Branch (89:7): [True: 108, False: 0]
  |  Branch (89:18): [True: 108, False: 0]
  ------------------
   90|    108|    return ch - 87;
   91|       |
   92|      0|  if (ch > 64 && ch < 71)
  ------------------
  |  Branch (92:7): [True: 0, False: 0]
  |  Branch (92:18): [True: 0, False: 0]
  ------------------
   93|      0|    return ch - 55;
   94|       |
   95|      0|  return 0;
   96|      0|}
_Z13hexPairToCharcc:
  100|    128|{
  101|    128|  return hexDigitToChar(a) * 16 + hexDigitToChar(b);
  102|    128|}
_ZN7TSKGuidC2ERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
  106|      8|{
  107|      8|  _bytes.clear();
  108|       |
  109|      8|  char charOne, charTwo;
  110|      8|  bool lookingForFirstChar = true;
  111|       |
  112|       |  // for (const char &ch : fromString) C++ 11 CODE CHANGED FOR TSK
  113|    296|  for (std::string::const_iterator it = fromString.begin(); it != fromString.end(); ++it)
  ------------------
  |  Branch (113:61): [True: 288, False: 8]
  ------------------
  114|    288|  {
  115|    288|    char ch = *it;
  116|    288|    if (ch == '-')
  ------------------
  |  Branch (116:9): [True: 32, False: 256]
  ------------------
  117|     32|      continue;
  118|       |
  119|    256|    if (lookingForFirstChar)
  ------------------
  |  Branch (119:9): [True: 128, False: 128]
  ------------------
  120|    128|    {
  121|    128|      charOne = ch;
  122|    128|      lookingForFirstChar = false;
  123|    128|    }
  124|    128|    else
  125|    128|    {
  126|    128|      charTwo = ch;
  127|    128|      unsigned char byte = hexPairToChar(charOne, charTwo);
  128|    128|      _bytes.push_back(byte);
  129|    128|      lookingForFirstChar = true;
  130|    128|    }
  131|    256|  }
  132|       |
  133|      8|}

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

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

tsk_error_get_info:
  148|     10|{
  149|     10|    TSK_ERROR_INFO *ptr = NULL;
  150|     10|    (void) pthread_once(&pt_tls_key_once, make_pt_tls_key);
  151|     10|    if ((ptr = (TSK_ERROR_INFO *) pthread_getspecific(pt_tls_key)) == 0) {
  ------------------
  |  Branch (151:9): [True: 1, False: 9]
  ------------------
  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|     10|    return ptr;
  163|     10|}
tsk_error_get_errno:
  297|      1|{
  298|      1|    return tsk_error_get_info()->t_errno;
  299|      1|}
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_set_errstr2:
  373|      1|{
  374|      1|    va_list args;
  375|      1|    va_start(args, format);
  376|      1|    vsnprintf(tsk_error_get_info()->errstr2, TSK_ERROR_STRING_MAX_LENGTH,
  ------------------
  |  |   67|      1|#define TSK_ERROR_STRING_MAX_LENGTH 1024
  ------------------
  377|      1|        format, args);
  378|      1|    va_end(args);
  379|      1|}
tsk_error_reset:
  444|      5|{
  445|      5|    TSK_ERROR_INFO *info = tsk_error_get_info();
  446|       |
  447|      5|    if( info != NULL ) {
  ------------------
  |  Branch (447:9): [True: 5, False: 0]
  ------------------
  448|      5|       info->t_errno = 0;
  449|      5|       info->errstr[0] = 0;
  450|      5|       info->errstr2[0] = 0;
  451|      5|       info->errstr_print[0] = 0;
  452|      5|    }
  453|      5|}
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|      4|{
   47|      4|    pthread_mutexattr_t attr;
   48|      4|    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|      4|    int e = pthread_mutex_init(&lock->mutex, &attr);
   72|      4|    pthread_mutexattr_destroy(&attr);
   73|      4|    if (e != 0) {
  ------------------
  |  Branch (73:9): [True: 0, False: 4]
  ------------------
   74|      0|        fprintf(stderr, "tsk_init_lock: thread_mutex_init failed %d\n", e);
   75|      0|        assert(0);
   76|      0|    }
   77|      4|}
tsk_deinit_lock:
   81|      4|{
   82|      4|    pthread_mutex_destroy(&lock->mutex);
   83|      4|}
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_fs_attr_run_alloc:
   47|      1|{
   48|      1|    TSK_FS_ATTR_RUN *fs_attr_run =
   49|      1|        (TSK_FS_ATTR_RUN *) tsk_malloc(sizeof(TSK_FS_ATTR_RUN));
   50|      1|    if (fs_attr_run == NULL)
  ------------------
  |  Branch (50:9): [True: 0, False: 1]
  ------------------
   51|      0|        return NULL;
   52|       |
   53|      1|    return fs_attr_run;
   54|      1|}
tsk_fs_attr_run_free:
   64|      1|{
   65|      2|    while (fs_attr_run) {
  ------------------
  |  Branch (65:12): [True: 1, False: 1]
  ------------------
   66|      1|        TSK_FS_ATTR_RUN *fs_attr_run_prev = fs_attr_run;
   67|      1|        fs_attr_run = fs_attr_run->next;
   68|      1|        fs_attr_run_prev->next = NULL;
   69|      1|        free(fs_attr_run_prev);
   70|      1|    }
   71|      1|}
tsk_fs_attr_alloc:
   85|      2|{
   86|      2|    TSK_FS_ATTR *fs_attr = (TSK_FS_ATTR *) tsk_malloc(sizeof(TSK_FS_ATTR));
   87|      2|    if (fs_attr == NULL) {
  ------------------
  |  Branch (87:9): [True: 0, False: 2]
  ------------------
   88|      0|        return NULL;
   89|      0|    }
   90|       |
   91|      2|    fs_attr->name_size = 128;
   92|      2|    if ((fs_attr->name = (char *) tsk_malloc(fs_attr->name_size)) == NULL) {
  ------------------
  |  Branch (92:9): [True: 0, False: 2]
  ------------------
   93|      0|        free(fs_attr);
   94|      0|        return NULL;
   95|      0|    }
   96|       |
   97|      2|    if (type == TSK_FS_ATTR_NONRES) {
  ------------------
  |  Branch (97:9): [True: 2, False: 0]
  ------------------
   98|      2|        fs_attr->flags = (TSK_FS_ATTR_NONRES | TSK_FS_ATTR_INUSE);
   99|      2|    }
  100|      0|    else if (type == TSK_FS_ATTR_RES) {
  ------------------
  |  Branch (100:14): [True: 0, False: 0]
  ------------------
  101|      0|        fs_attr->rd.buf_size = 1024;
  102|      0|        fs_attr->rd.buf = (uint8_t *) tsk_malloc(fs_attr->rd.buf_size);
  103|      0|        if (fs_attr->rd.buf == NULL) {
  ------------------
  |  Branch (103:13): [True: 0, False: 0]
  ------------------
  104|      0|            free(fs_attr->name);
  105|      0|            return NULL;
  106|      0|        }
  107|      0|        fs_attr->flags = (TSK_FS_ATTR_RES | TSK_FS_ATTR_INUSE);
  108|      0|    }
  109|      0|    else {
  110|      0|        tsk_error_reset();
  111|      0|        tsk_error_set_errno(TSK_ERR_FS_ARG);
  ------------------
  |  |  351|      0|#define TSK_ERR_FS_ARG		(TSK_ERR_FS | 6)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  112|      0|        tsk_error_set_errstr("tsk_fs_attr_alloc: Invalid Type: %d\n",
  113|      0|            type);
  114|      0|        return NULL;
  115|      0|    }
  116|       |
  117|      2|    return fs_attr;
  118|      2|}
tsk_fs_attr_free:
  129|      2|{
  130|      2|    if (a_fs_attr == NULL)
  ------------------
  |  Branch (130:9): [True: 0, False: 2]
  ------------------
  131|      0|        return;
  132|       |
  133|      2|    if (a_fs_attr->nrd.run)
  ------------------
  |  Branch (133:9): [True: 1, False: 1]
  ------------------
  134|      1|        tsk_fs_attr_run_free(a_fs_attr->nrd.run);
  135|      2|    a_fs_attr->nrd.run = NULL;
  136|       |
  137|      2|    free(a_fs_attr->rd.buf);
  138|      2|    a_fs_attr->rd.buf = NULL;
  139|       |
  140|      2|    free(a_fs_attr->name);
  141|      2|    a_fs_attr->name = NULL;
  142|       |
  143|      2|    free(a_fs_attr);
  144|      2|}
tsk_fs_attr_set_run:
  279|      2|{
  280|      2|    if ((a_fs_file == NULL) || (a_fs_file->meta == NULL)) {
  ------------------
  |  Branch (280:9): [True: 0, False: 2]
  |  Branch (280:32): [True: 0, False: 2]
  ------------------
  281|      0|        tsk_error_reset();
  282|      0|        tsk_error_set_errno(TSK_ERR_FS_ARG);
  ------------------
  |  |  351|      0|#define TSK_ERR_FS_ARG		(TSK_ERR_FS | 6)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  283|      0|        tsk_error_set_errstr("Null fs_file in tsk_fs_attr_set_run");
  284|      0|        return 1;
  285|      0|    }
  286|      2|    if (a_fs_attr == NULL) {
  ------------------
  |  Branch (286:9): [True: 0, False: 2]
  ------------------
  287|      0|        tsk_error_reset();
  288|      0|        tsk_error_set_errno(TSK_ERR_FS_ARG);
  ------------------
  |  |  351|      0|#define TSK_ERR_FS_ARG		(TSK_ERR_FS | 6)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  289|      0|        tsk_error_set_errstr("Null fs_attr in tsk_fs_attr_set_run");
  290|      0|        return 1;
  291|      0|    }
  292|       |
  293|      2|    if (alloc_size < size) {
  ------------------
  |  Branch (293:9): [True: 0, False: 2]
  ------------------
  294|      0|        tsk_error_reset();
  295|      0|        tsk_error_set_errno(TSK_ERR_FS_ARG);
  ------------------
  |  |  351|      0|#define TSK_ERR_FS_ARG		(TSK_ERR_FS | 6)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  296|      0|        tsk_error_set_errstr("tsk_fs_attr_set_run: alloc_size (%" PRIdOFF
  297|      0|            ") is less than size (%" PRIdOFF ")", alloc_size, size);
  298|      0|        return 1;
  299|      0|    }
  300|       |
  301|      2|    a_fs_attr->fs_file = a_fs_file;
  302|      2|    a_fs_attr->flags = (TSK_FS_ATTR_INUSE | TSK_FS_ATTR_NONRES | flags);
  303|      2|    a_fs_attr->type = type;
  304|      2|    a_fs_attr->id = id;
  305|      2|    a_fs_attr->size = size;
  306|      2|    a_fs_attr->nrd.allocsize = alloc_size;
  307|      2|    a_fs_attr->nrd.initsize = init_size;
  308|      2|    a_fs_attr->nrd.compsize = compsize;
  309|       |
  310|      2|    if (fs_attr_put_name(a_fs_attr, name)) {
  ------------------
  |  Branch (310:9): [True: 0, False: 2]
  ------------------
  311|      0|        return 1;
  312|      0|    }
  313|       |
  314|       |    /* Add the a_data_run_new to the attribute. */
  315|       |
  316|       |    /* We support the ODD case where the run is NULL.  In this case, 
  317|       |     * we set the attribute size info, but set everything else to NULL.
  318|       |     */
  319|      2|    if (a_data_run_new == NULL) {
  ------------------
  |  Branch (319:9): [True: 1, False: 1]
  ------------------
  320|      1|        a_fs_attr->nrd.run = NULL;
  321|      1|        a_fs_attr->nrd.run_end = NULL;
  322|      1|        return 0;
  323|      1|    }
  324|       |
  325|       |    /*
  326|       |     * If this is not in the beginning, then we need to make a filler 
  327|       |     * to account for the cluster numbers we haven't seen yet
  328|       |     *
  329|       |     * This commonly happens when we process an MFT entry that
  330|       |     * is not a base entry and it is referenced in an $ATTR_LIST
  331|       |     *
  332|       |     * The $DATA attribute in the non-base have a non-zero
  333|       |     * a_data_run_new->offset.  
  334|       |     */
  335|      1|    if (a_data_run_new->offset != 0) {
  ------------------
  |  Branch (335:9): [True: 0, False: 1]
  ------------------
  336|      0|        TSK_FS_ATTR_RUN *fill_run = tsk_fs_attr_run_alloc();
  337|      0|        fill_run->flags = TSK_FS_ATTR_RUN_FLAG_FILLER;
  338|      0|        fill_run->offset = 0;
  339|      0|        fill_run->addr = 0;
  340|      0|        fill_run->len = a_data_run_new->offset;
  341|      0|        fill_run->next = a_data_run_new;
  342|      0|        a_data_run_new = fill_run;
  343|      0|    }
  344|       |
  345|      1|    a_fs_attr->nrd.run = a_data_run_new;
  346|       |
  347|       |    // update the pointer to the end of the list
  348|      1|    a_fs_attr->nrd.run_end = a_data_run_new;
  349|      1|    while (a_fs_attr->nrd.run_end->next) {
  ------------------
  |  Branch (349:12): [True: 0, False: 1]
  ------------------
  350|      0|        a_fs_attr->nrd.run_end = a_fs_attr->nrd.run_end->next;
  351|      0|    }
  352|       |
  353|      1|    return 0;
  354|      2|}
tsk_fs_attr_read:
 1105|      1|{
 1106|      1|    TSK_FS_INFO *fs;
 1107|       |
 1108|      1|    if ((a_fs_attr == NULL) || (a_fs_attr->fs_file == NULL)
  ------------------
  |  Branch (1108:9): [True: 0, False: 1]
  |  Branch (1108:32): [True: 0, False: 1]
  ------------------
 1109|      1|        || (a_fs_attr->fs_file->fs_info == NULL) || (a_buf == NULL)) {
  ------------------
  |  Branch (1109:12): [True: 0, False: 1]
  |  Branch (1109:53): [True: 0, False: 1]
  ------------------
 1110|      0|        tsk_error_set_errno(TSK_ERR_FS_ARG);
  ------------------
  |  |  351|      0|#define TSK_ERR_FS_ARG		(TSK_ERR_FS | 6)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
 1111|      0|        tsk_error_set_errstr
 1112|      0|            ("tsk_fs_attr_read: Attribute has null pointers.");
 1113|      0|        return -1;
 1114|      0|    }
 1115|      1|    fs = a_fs_attr->fs_file->fs_info;
 1116|       |
 1117|       |	// Handle logical directories separately
 1118|      1|	if (fs->ftype == TSK_FS_TYPE_LOGICAL) {
  ------------------
  |  Branch (1118:6): [True: 0, False: 1]
  ------------------
 1119|      0|		return logicalfs_read(fs, a_fs_attr->fs_file, a_offset, a_len, a_buf);
 1120|      0|	}
 1121|       |
 1122|       |    /* for compressed data, call the specialized function */
 1123|      1|    if (a_fs_attr->flags & TSK_FS_ATTR_COMP) {
  ------------------
  |  Branch (1123:9): [True: 0, False: 1]
  ------------------
 1124|      0|        if (a_fs_attr->r == NULL) {
  ------------------
  |  Branch (1124:13): [True: 0, False: 0]
  ------------------
 1125|      0|            tsk_error_set_errno(TSK_ERR_FS_ARG);
  ------------------
  |  |  351|      0|#define TSK_ERR_FS_ARG		(TSK_ERR_FS | 6)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
 1126|      0|            tsk_error_set_errstr
 1127|      0|                ("tsk_fs_attr_read: Attribute has compressed type set, but no compressed read function defined");
 1128|      0|            return -1;
 1129|      0|        }
 1130|      0|        return a_fs_attr->r(a_fs_attr, a_offset, a_buf, a_len);
 1131|      0|    }
 1132|       |
 1133|       |    /* For resident data, copy data from the local buffer */
 1134|      1|    else if (a_fs_attr->flags & TSK_FS_ATTR_RES) {
  ------------------
  |  Branch (1134:14): [True: 0, False: 1]
  ------------------
 1135|      0|        size_t len_toread;
 1136|       |
 1137|      0|        if (a_offset >= a_fs_attr->size) {
  ------------------
  |  Branch (1137:13): [True: 0, False: 0]
  ------------------
 1138|      0|            tsk_error_reset();
 1139|      0|            tsk_error_set_errno(TSK_ERR_FS_READ_OFF);
  ------------------
  |  |  350|      0|#define TSK_ERR_FS_READ_OFF	(TSK_ERR_FS | 5)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
 1140|      0|            tsk_error_set_errstr("tsk_fs_attr_read - %" PRIdOFF, a_offset);
  ------------------
  |  |  269|      0|#define PRIdOFF		PRId64
  ------------------
 1141|      0|            return -1;
 1142|      0|        }
 1143|       |
 1144|      0|        len_toread = a_len;
 1145|      0|        if (a_offset + (TSK_OFF_T)a_len > a_fs_attr->size) {
  ------------------
  |  Branch (1145:13): [True: 0, False: 0]
  ------------------
 1146|      0|            len_toread = (size_t) (a_fs_attr->size - a_offset);
 1147|      0|            memset(&a_buf[len_toread], 0, a_len - len_toread);
 1148|      0|        }
 1149|       |
 1150|      0|        memcpy(a_buf, &a_fs_attr->rd.buf[a_offset], len_toread);
 1151|       |
 1152|      0|        return (ssize_t) len_toread;
 1153|      0|    }
 1154|       |
 1155|       |    /* For non-resident data, load the needed block and copy the data */
 1156|      1|    else if (a_fs_attr->flags & TSK_FS_ATTR_NONRES) {
  ------------------
  |  Branch (1156:14): [True: 1, False: 0]
  ------------------
 1157|      1|        TSK_FS_ATTR_RUN *data_run_cur;
 1158|      1|        TSK_DADDR_T blkoffset_toread;   // block offset of where we want to start reading from
 1159|      1|        size_t byteoffset_toread;       // byte offset in blkoffset_toread of where we want to start reading from
 1160|      1|        ssize_t len_remain;      // length remaining to copy
 1161|      1|        size_t len_toread;      // length total to copy
 1162|       |
 1163|      1|        if (((a_flags & TSK_FS_FILE_READ_FLAG_SLACK)
  ------------------
  |  Branch (1163:14): [True: 0, False: 1]
  ------------------
 1164|      1|                && (a_offset >= a_fs_attr->nrd.allocsize))
  ------------------
  |  Branch (1164:20): [True: 0, False: 0]
  ------------------
 1165|      1|            || (!(a_flags & TSK_FS_FILE_READ_FLAG_SLACK)
  ------------------
  |  Branch (1165:17): [True: 1, False: 0]
  ------------------
 1166|      1|                && (a_offset >= a_fs_attr->size))) {
  ------------------
  |  Branch (1166:20): [True: 1, False: 0]
  ------------------
 1167|      1|            tsk_error_reset();
 1168|      1|            tsk_error_set_errno(TSK_ERR_FS_READ_OFF);
  ------------------
  |  |  350|      1|#define TSK_ERR_FS_READ_OFF	(TSK_ERR_FS | 5)
  |  |  ------------------
  |  |  |  |  301|      1|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
 1169|      1|            tsk_error_set_errstr("tsk_fs_attr_read - %" PRIdOFF, a_offset);
  ------------------
  |  |  269|      1|#define PRIdOFF		PRId64
  ------------------
 1170|      1|            return -1;
 1171|      1|        }
 1172|       |
 1173|      0|        blkoffset_toread = a_offset / fs->block_size;
 1174|      0|        byteoffset_toread = (size_t) (a_offset % fs->block_size);
 1175|       |
 1176|       |        // determine how many bytes we can copy
 1177|      0|        len_toread = a_len;
 1178|      0|        if (a_flags & TSK_FS_FILE_READ_FLAG_SLACK) {
  ------------------
  |  Branch (1178:13): [True: 0, False: 0]
  ------------------
 1179|      0|            if (a_offset + (TSK_OFF_T)a_len > a_fs_attr->nrd.allocsize)
  ------------------
  |  Branch (1179:17): [True: 0, False: 0]
  ------------------
 1180|      0|                len_toread =
 1181|      0|                    (size_t) (a_fs_attr->nrd.allocsize - a_offset);
 1182|      0|        }
 1183|      0|        else {
 1184|      0|            if (a_offset + (TSK_OFF_T)a_len > a_fs_attr->size)
  ------------------
  |  Branch (1184:17): [True: 0, False: 0]
  ------------------
 1185|      0|                len_toread = (size_t) (a_fs_attr->size - a_offset);
 1186|      0|        }
 1187|       |
 1188|       |
 1189|       |        // wipe the buffer we won't read into
 1190|      0|        if (len_toread < a_len)
  ------------------
  |  Branch (1190:13): [True: 0, False: 0]
  ------------------
 1191|      0|            memset(&a_buf[len_toread], 0, a_len - len_toread);
 1192|       |
 1193|      0|        len_remain = len_toread;
 1194|       |
 1195|       |        // cycle through the runs until we find the one where our offset starts
 1196|      0|        for (data_run_cur = a_fs_attr->nrd.run; data_run_cur && len_remain > 0;
  ------------------
  |  Branch (1196:49): [True: 0, False: 0]
  |  Branch (1196:65): [True: 0, False: 0]
  ------------------
 1197|      0|            data_run_cur = data_run_cur->next) {
 1198|       |
 1199|      0|            TSK_DADDR_T blkoffset_inrun;
 1200|      0|            size_t len_inrun;
 1201|       |
 1202|       |            // See if this run contains the starting offset they requested
 1203|      0|            if (data_run_cur->offset + data_run_cur->len <=
  ------------------
  |  Branch (1203:17): [True: 0, False: 0]
  ------------------
 1204|      0|                blkoffset_toread)
 1205|      0|                continue;
 1206|       |
 1207|       |            // We want this run, so find out the offset that we want
 1208|       |            // we'll start at 0 if we already read data in the last run. 
 1209|      0|            if (data_run_cur->offset < blkoffset_toread)
  ------------------
  |  Branch (1209:17): [True: 0, False: 0]
  ------------------
 1210|      0|                blkoffset_inrun = blkoffset_toread - data_run_cur->offset;
 1211|      0|            else
 1212|      0|                blkoffset_inrun = 0;
 1213|       |
 1214|       |            // see if we need to read the rest of this run and into the next or if it is all here
 1215|      0|            len_inrun = len_remain;
 1216|      0|            if ((data_run_cur->len - blkoffset_inrun) * fs->block_size -
  ------------------
  |  Branch (1216:17): [True: 0, False: 0]
  ------------------
 1217|      0|                byteoffset_toread < (size_t)len_remain) {
 1218|      0|                len_inrun =
 1219|      0|                    (size_t) ((data_run_cur->len -
 1220|      0|                        blkoffset_inrun) * fs->block_size -
 1221|      0|                    byteoffset_toread);
 1222|      0|            }
 1223|       |
 1224|       |            /* sparse files/runs just get 0s */
 1225|      0|            if (data_run_cur->flags & TSK_FS_ATTR_RUN_FLAG_SPARSE) {
  ------------------
  |  Branch (1225:17): [True: 0, False: 0]
  ------------------
 1226|      0|                memset(&a_buf[len_toread - len_remain], 0, len_inrun);
 1227|      0|            }
 1228|       |
 1229|       |            /* FILLER entries exist when the source file system can store run
 1230|       |             * info out of order and we did not get all of the run info.  We
 1231|       |             * return 0s if data is read from this type of run. */
 1232|      0|            else if (data_run_cur->flags & TSK_FS_ATTR_RUN_FLAG_FILLER) {
  ------------------
  |  Branch (1232:22): [True: 0, False: 0]
  ------------------
 1233|      0|                if (a_buf == NULL) {
  ------------------
  |  Branch (1233:21): [True: 0, False: 0]
  ------------------
 1234|      0|                    tsk_error_reset();
 1235|      0|                    tsk_error_set_errno(TSK_ERR_FS_READ_OFF);
  ------------------
  |  |  350|      0|#define TSK_ERR_FS_READ_OFF	(TSK_ERR_FS | 5)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
 1236|      0|                    tsk_error_set_errstr("tsk_fs_attr_read - missing a_buf");
 1237|      0|                    return -1;
 1238|      0|                }
 1239|      0|                memset(&a_buf[len_toread - len_remain], 0, len_inrun);
 1240|      0|                if (tsk_verbose)
  ------------------
  |  Branch (1240:21): [True: 0, False: 0]
  ------------------
 1241|      0|                    fprintf(stderr,
 1242|      0|                        "tsk_fs_attr_read_type: File %" PRIuINUM
 1243|      0|                        " has FILLER entry, using 0s\n",
 1244|      0|                        (a_fs_attr->fs_file->meta) ? a_fs_attr->
  ------------------
  |  Branch (1244:25): [True: 0, False: 0]
  ------------------
 1245|      0|                        fs_file->meta->addr : 0);
 1246|      0|            }
 1247|       |
 1248|       |            // we return 0s for reads past the initsize (unless they want slack space)
 1249|      0|            else if (((TSK_OFF_T) ((data_run_cur->offset +
  ------------------
  |  Branch (1249:22): [True: 0, False: 0]
  ------------------
 1250|      0|                            blkoffset_inrun) * fs->block_size +
 1251|      0|                        byteoffset_toread) >= a_fs_attr->nrd.initsize)
 1252|      0|                && ((a_flags & TSK_FS_FILE_READ_FLAG_SLACK) == 0)) {
  ------------------
  |  Branch (1252:20): [True: 0, False: 0]
  ------------------
 1253|      0|                memset(&a_buf[len_toread - len_remain], 0, len_inrun);
 1254|      0|                if (tsk_verbose)
  ------------------
  |  Branch (1254:21): [True: 0, False: 0]
  ------------------
 1255|      0|                    fprintf(stderr,
 1256|      0|                        "tsk_fs_attr_read: Returning 0s for read past end of initsize (%"
 1257|      0|                        PRIuINUM ")\n", ((a_fs_attr->fs_file)
  ------------------
  |  Branch (1257:42): [True: 0, False: 0]
  ------------------
 1258|      0|                            && (a_fs_attr->fs_file->
  ------------------
  |  Branch (1258:32): [True: 0, False: 0]
  ------------------
 1259|      0|                                meta)) ? a_fs_attr->fs_file->meta->
 1260|      0|                        addr : 0);
 1261|      0|            }
 1262|       |
 1263|       |            // we are going to read some data
 1264|      0|            else {
 1265|      0|                TSK_OFF_T fs_offset_b;
 1266|      0|                ssize_t cnt;
 1267|       |
 1268|       |                // calculate the byte offset in the file system that we want to read from
 1269|      0|                fs_offset_b =
 1270|      0|                    (data_run_cur->addr +
 1271|      0|                    blkoffset_inrun) * fs->block_size;
 1272|       |
 1273|       |                // add the byte offset in the block
 1274|      0|                fs_offset_b += byteoffset_toread;
 1275|      0|				cnt =
 1276|      0|					tsk_fs_read_decrypt(fs, fs_offset_b,
 1277|      0|						&a_buf[len_toread - len_remain], len_inrun,
 1278|      0|						data_run_cur->crypto_id + blkoffset_inrun);
 1279|       |
 1280|      0|                if (cnt != (ssize_t)len_inrun) {
  ------------------
  |  Branch (1280:21): [True: 0, False: 0]
  ------------------
 1281|      0|                    if (cnt >= 0) {
  ------------------
  |  Branch (1281:25): [True: 0, False: 0]
  ------------------
 1282|      0|                        tsk_error_reset();
 1283|      0|                        tsk_error_set_errno(TSK_ERR_FS_READ);
  ------------------
  |  |  349|      0|#define TSK_ERR_FS_READ		(TSK_ERR_FS | 4)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
 1284|      0|                    }
 1285|      0|                    tsk_error_set_errstr2
 1286|      0|                        ("tsk_fs_attr_read_type: offset: %" PRIdOFF
 1287|      0|                        "  Len: %" PRIuSIZE "", fs_offset_b, len_inrun);
 1288|      0|                    return cnt;
 1289|      0|                }
 1290|       |
 1291|       |                // see if part of the data is in the non-initialized space
 1292|      0|                if (((TSK_OFF_T) ((data_run_cur->offset +
  ------------------
  |  Branch (1292:21): [True: 0, False: 0]
  ------------------
 1293|      0|                                blkoffset_inrun) * fs->block_size +
 1294|      0|                            byteoffset_toread + len_inrun) >
 1295|      0|                        a_fs_attr->nrd.initsize)
 1296|      0|                    && ((a_flags & TSK_FS_FILE_READ_FLAG_SLACK) == 0)) {
  ------------------
  |  Branch (1296:24): [True: 0, False: 0]
  ------------------
 1297|       |
 1298|      0|                    size_t uninit_off = (size_t) (a_fs_attr->nrd.initsize -
 1299|      0|                        ((data_run_cur->offset +
 1300|      0|                                blkoffset_inrun) * fs->block_size +
 1301|      0|                            byteoffset_toread));
 1302|       |
 1303|      0|                    memset(&a_buf[len_toread - len_remain + uninit_off], 0,
 1304|      0|                        len_inrun - uninit_off);
 1305|      0|                }
 1306|       |
 1307|      0|            }
 1308|       |
 1309|      0|            len_remain -= len_inrun;
 1310|       |
 1311|       |            // reset this in case we need to also read from the next run 
 1312|      0|            byteoffset_toread = 0;
 1313|      0|        }
 1314|      0|        return (ssize_t) (len_toread - len_remain);
 1315|      0|    }
 1316|       |
 1317|      0|    tsk_error_set_errno(TSK_ERR_FS_ARG);
  ------------------
  |  |  351|      0|#define TSK_ERR_FS_ARG		(TSK_ERR_FS | 6)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
 1318|      0|    tsk_error_set_errstr("tsk_fs_attr_read: Unknown attribute type: %x",
 1319|      0|        a_fs_attr->flags);
 1320|      0|    return -1;
 1321|      1|}
fs_attr.c:fs_attr_put_name:
  181|      2|{
  182|      2|    if ((name == NULL) || (strlen(name) == 0)) {
  ------------------
  |  Branch (182:9): [True: 2, False: 0]
  |  Branch (182:27): [True: 0, False: 0]
  ------------------
  183|      2|        if (fs_attr->name_size > 0) {
  ------------------
  |  Branch (183:13): [True: 2, False: 0]
  ------------------
  184|      2|            free(fs_attr->name);
  185|      2|            fs_attr->name_size = 0;
  186|      2|        }
  187|      2|        fs_attr->name = NULL;
  188|      2|        return 0;
  189|      2|    }
  190|       |
  191|      0|    if (fs_attr->name_size < (strlen(name) + 1)) {
  ------------------
  |  Branch (191:9): [True: 0, False: 0]
  ------------------
  192|      0|        fs_attr->name = tsk_realloc(fs_attr->name, strlen(name) + 1);
  193|      0|        if (fs_attr->name == NULL)
  ------------------
  |  Branch (193:13): [True: 0, False: 0]
  ------------------
  194|      0|            return 1;
  195|      0|        fs_attr->name_size = strlen(name) + 1;
  196|      0|    }
  197|      0|    strncpy(fs_attr->name, name, fs_attr->name_size);
  198|      0|    return 0;
  199|      0|}

tsk_fs_attrlist_alloc:
   26|      2|{
   27|      2|    TSK_FS_ATTRLIST *fs_attrlist;
   28|       |
   29|      2|    if ((fs_attrlist =
  ------------------
  |  Branch (29:9): [True: 0, False: 2]
  ------------------
   30|      2|            (TSK_FS_ATTRLIST *) tsk_malloc(sizeof(TSK_FS_ATTRLIST))) ==
   31|      2|        NULL)
   32|      0|        return NULL;
   33|      2|    return fs_attrlist;
   34|      2|}
tsk_fs_attrlist_free:
   41|      2|{
   42|      2|    TSK_FS_ATTR *fs_attr_cur, *fs_attr_tmp;
   43|      2|    if (a_fs_attrlist == NULL)
  ------------------
  |  Branch (43:9): [True: 0, False: 2]
  ------------------
   44|      0|        return;
   45|       |
   46|      2|    fs_attr_cur = a_fs_attrlist->head;
   47|      4|    while (fs_attr_cur) {
  ------------------
  |  Branch (47:12): [True: 2, False: 2]
  ------------------
   48|      2|        fs_attr_tmp = fs_attr_cur->next;
   49|      2|        tsk_fs_attr_free(fs_attr_cur);
   50|      2|        fs_attr_cur = fs_attr_tmp;
   51|      2|    }
   52|      2|    free(a_fs_attrlist);
   53|      2|}
tsk_fs_attrlist_add:
   65|      2|{
   66|      2|    if (a_fs_attrlist == NULL) {
  ------------------
  |  Branch (66:9): [True: 0, False: 2]
  ------------------
   67|      0|        tsk_error_reset();
   68|      0|        tsk_error_set_errno(TSK_ERR_FS_ARG);
  ------------------
  |  |  351|      0|#define TSK_ERR_FS_ARG		(TSK_ERR_FS | 6)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
   69|      0|        tsk_error_set_errstr("Null list in tsk_fs_attrlist_add");
   70|      0|        return 1;
   71|      0|    }
   72|       |
   73|       |    // verify INUSE is set
   74|      2|    a_fs_attr->flags |= TSK_FS_ATTR_INUSE;
   75|       |
   76|      2|    if (a_fs_attrlist->head == NULL) {
  ------------------
  |  Branch (76:9): [True: 2, False: 0]
  ------------------
   77|      2|        a_fs_attrlist->head = a_fs_attr;
   78|      2|    }
   79|      0|    else {
   80|      0|        TSK_FS_ATTR *fs_attr_cur;
   81|      0|        fs_attr_cur = a_fs_attrlist->head;
   82|      0|        while (fs_attr_cur) {
  ------------------
  |  Branch (82:16): [True: 0, False: 0]
  ------------------
   83|       |            // check if it already exists
   84|      0|            if ((fs_attr_cur->type == a_fs_attr->type)
  ------------------
  |  Branch (84:17): [True: 0, False: 0]
  ------------------
   85|      0|                && (fs_attr_cur->id == a_fs_attr->id)) {
  ------------------
  |  Branch (85:20): [True: 0, False: 0]
  ------------------
   86|      0|                tsk_error_reset();
   87|      0|                tsk_error_set_errno(TSK_ERR_FS_ARG);
  ------------------
  |  |  351|      0|#define TSK_ERR_FS_ARG		(TSK_ERR_FS | 6)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
   88|      0|                tsk_error_set_errstr
   89|      0|                    ("datalist_add: Type %d and Id %d already in list",
   90|      0|                    a_fs_attr->type, a_fs_attr->id);
   91|      0|                return 1;
   92|      0|            }
   93|      0|            if (fs_attr_cur->next == NULL) {
  ------------------
  |  Branch (93:17): [True: 0, False: 0]
  ------------------
   94|      0|                fs_attr_cur->next = a_fs_attr;
   95|      0|                break;
   96|      0|            }
   97|      0|            fs_attr_cur = fs_attr_cur->next;
   98|      0|        }
   99|      0|    }
  100|      2|    return 0;
  101|      2|}
tsk_fs_attrlist_getnew:
  120|      2|{
  121|      2|    TSK_FS_ATTR *fs_attr_cur;
  122|      2|    TSK_FS_ATTR *fs_attr_ok = NULL;
  123|       |
  124|      2|    if (a_fs_attrlist == NULL) {
  ------------------
  |  Branch (124:9): [True: 0, False: 2]
  ------------------
  125|      0|        tsk_error_reset();
  126|      0|        tsk_error_set_errno(TSK_ERR_FS_ARG);
  ------------------
  |  |  351|      0|#define TSK_ERR_FS_ARG		(TSK_ERR_FS | 6)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  127|      0|        tsk_error_set_errstr("Null list in tsk_fs_attrlist_getnew()");
  128|      0|        return NULL;
  129|      0|    }
  130|       |
  131|      2|    if ((a_atype != TSK_FS_ATTR_NONRES) && (a_atype != TSK_FS_ATTR_RES)) {
  ------------------
  |  Branch (131:9): [True: 0, False: 2]
  |  Branch (131:44): [True: 0, False: 0]
  ------------------
  132|      0|        tsk_error_reset();
  133|      0|        tsk_error_set_errno(TSK_ERR_FS_ARG);
  ------------------
  |  |  351|      0|#define TSK_ERR_FS_ARG		(TSK_ERR_FS | 6)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  134|      0|        tsk_error_set_errstr("Invalid Type in tsk_fs_attrlist_getnew()");
  135|      0|        return NULL;
  136|      0|    }
  137|       |
  138|      2|    for (fs_attr_cur = a_fs_attrlist->head; fs_attr_cur;
  ------------------
  |  Branch (138:45): [True: 0, False: 2]
  ------------------
  139|      2|        fs_attr_cur = fs_attr_cur->next) {
  140|      0|        if (fs_attr_cur->flags == 0) {
  ------------------
  |  Branch (140:13): [True: 0, False: 0]
  ------------------
  141|      0|            if (a_atype == TSK_FS_ATTR_NONRES) {
  ------------------
  |  Branch (141:17): [True: 0, False: 0]
  ------------------
  142|      0|                if (fs_attr_cur->nrd.run)
  ------------------
  |  Branch (142:21): [True: 0, False: 0]
  ------------------
  143|      0|                    break;
  144|      0|                else if (!fs_attr_ok)
  ------------------
  |  Branch (144:26): [True: 0, False: 0]
  ------------------
  145|      0|                    fs_attr_ok = fs_attr_cur;
  146|      0|            }
  147|       |            /* we want one with an allocated buf */
  148|      0|            else {
  149|      0|                if (fs_attr_cur->rd.buf_size)
  ------------------
  |  Branch (149:21): [True: 0, False: 0]
  ------------------
  150|      0|                    break;
  151|      0|                else if (!fs_attr_ok)
  ------------------
  |  Branch (151:26): [True: 0, False: 0]
  ------------------
  152|      0|                    fs_attr_ok = fs_attr_cur;
  153|      0|            }
  154|      0|        }
  155|      0|    }
  156|       |
  157|       |    /* if we fell out then check fs_attr_tmp */
  158|      2|    if (!fs_attr_cur) {
  ------------------
  |  Branch (158:9): [True: 2, False: 0]
  ------------------
  159|      2|        if (fs_attr_ok)
  ------------------
  |  Branch (159:13): [True: 0, False: 2]
  ------------------
  160|      0|            fs_attr_cur = fs_attr_ok;
  161|      2|        else {
  162|       |            /* make a new one */
  163|      2|            if ((fs_attr_cur = tsk_fs_attr_alloc(a_atype)) == NULL)
  ------------------
  |  Branch (163:17): [True: 0, False: 2]
  ------------------
  164|      0|                return NULL;
  165|       |
  166|       |            // add it to the list
  167|      2|            if (tsk_fs_attrlist_add(a_fs_attrlist, fs_attr_cur)) {
  ------------------
  |  Branch (167:17): [True: 0, False: 2]
  ------------------
  168|      0|                tsk_fs_attr_free(fs_attr_cur);
  169|      0|                return NULL;
  170|      0|            }
  171|      2|        }
  172|      2|    }
  173|       |
  174|      2|    fs_attr_cur->flags = (TSK_FS_ATTR_INUSE | a_atype);
  175|      2|    return fs_attr_cur;
  176|      2|}
tsk_fs_attrlist_get:
  212|      1|{
  213|      1|    TSK_FS_ATTR *fs_attr_cur;
  214|      1|    TSK_FS_ATTR *fs_attr_ok = NULL;
  215|       |
  216|      1|    if (!a_fs_attrlist) {
  ------------------
  |  Branch (216:9): [True: 0, False: 1]
  ------------------
  217|      0|        tsk_error_reset();
  218|      0|        tsk_error_set_errno(TSK_ERR_FS_ARG);
  ------------------
  |  |  351|      0|#define TSK_ERR_FS_ARG		(TSK_ERR_FS | 6)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  219|      0|        tsk_error_set_errstr("tsk_fs_attrlist_get: Null list pointer");
  220|      0|        return NULL;
  221|      0|    }
  222|       |
  223|      2|    for (fs_attr_cur = a_fs_attrlist->head; fs_attr_cur;
  ------------------
  |  Branch (223:45): [True: 1, False: 1]
  ------------------
  224|      1|        fs_attr_cur = fs_attr_cur->next) {
  225|      1|        if ((fs_attr_cur->flags & TSK_FS_ATTR_INUSE)
  ------------------
  |  Branch (225:13): [True: 1, False: 0]
  ------------------
  226|      1|            && (fs_attr_cur->type == a_type)) {
  ------------------
  |  Branch (226:16): [True: 1, False: 0]
  ------------------
  227|       |
  228|       |            /* If we are looking for NTFS $Data,
  229|       |             * then return default when we see it */
  230|      1|            if ((fs_attr_cur->type == TSK_FS_ATTR_TYPE_NTFS_DATA) &&
  ------------------
  |  Branch (230:17): [True: 0, False: 1]
  ------------------
  231|      1|                (fs_attr_cur->name == NULL)) {
  ------------------
  |  Branch (231:17): [True: 0, False: 0]
  ------------------
  232|      0|                return fs_attr_cur;
  233|      0|            }
  234|       |
  235|       |            // make sure we return the lowest if multiple exist
  236|      1|            if ((fs_attr_ok == NULL) || (fs_attr_ok->id > fs_attr_cur->id))
  ------------------
  |  Branch (236:17): [True: 1, False: 0]
  |  Branch (236:41): [True: 0, False: 0]
  ------------------
  237|      1|                fs_attr_ok = fs_attr_cur;
  238|      1|        }
  239|      1|    }
  240|       |
  241|      1|    if (!fs_attr_ok) {
  ------------------
  |  Branch (241:9): [True: 0, False: 1]
  ------------------
  242|      0|        tsk_error_set_errno(TSK_ERR_FS_ATTR_NOTFOUND);
  ------------------
  |  |  362|      0|#define TSK_ERR_FS_ATTR_NOTFOUND (TSK_ERR_FS | 17)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  243|      0|        tsk_error_set_errstr("tsk_fs_attrlist_get: Attribute %d not found",
  244|      0|            a_type);
  245|      0|        return NULL;
  246|      0|    }
  247|      1|    else {
  248|      1|        return fs_attr_ok;
  249|      1|    }
  250|      1|}

tsk_fs_file_alloc:
   28|      2|{
   29|      2|    TSK_FS_FILE *fs_file;
   30|       |
   31|      2|    fs_file = (TSK_FS_FILE *) tsk_malloc(sizeof(TSK_FS_FILE));
   32|      2|    if (fs_file == NULL)
  ------------------
  |  Branch (32:9): [True: 0, False: 2]
  ------------------
   33|      0|        return NULL;
   34|      2|    fs_file->fs_info = a_fs;
   35|      2|    fs_file->tag = TSK_FS_FILE_TAG;
  ------------------
  |  |  687|      2|#define  TSK_FS_FILE_TAG 0x11212212
  ------------------
   36|      2|    return fs_file;
   37|      2|}
tsk_fs_file_close:
   61|      2|{
   62|      2|    if ((a_fs_file == NULL) || (a_fs_file->tag != TSK_FS_FILE_TAG))
  ------------------
  |  |  687|      2|#define  TSK_FS_FILE_TAG 0x11212212
  ------------------
  |  Branch (62:9): [True: 0, False: 2]
  |  Branch (62:32): [True: 0, False: 2]
  ------------------
   63|      0|        return;
   64|       |
   65|      2|    a_fs_file->tag = 0;
   66|       |
   67|      2|    if (a_fs_file->meta) {
  ------------------
  |  Branch (67:9): [True: 2, False: 0]
  ------------------
   68|      2|        tsk_fs_meta_close(a_fs_file->meta);
   69|      2|        a_fs_file->meta = NULL;
   70|      2|    }
   71|      2|    if (a_fs_file->name) {
  ------------------
  |  Branch (71:9): [True: 0, False: 2]
  ------------------
   72|      0|        tsk_fs_name_free(a_fs_file->name);
   73|      0|        a_fs_file->name = NULL;
   74|      0|    }
   75|       |
   76|      2|    free(a_fs_file);
   77|      2|}
tsk_fs_file_open_meta:
  101|      2|{
  102|      2|    TSK_FS_FILE *fs_file;
  103|       |
  104|      2|    if ((a_fs == NULL) || (a_fs->tag != TSK_FS_INFO_TAG)) {
  ------------------
  |  |  933|      2|#define TSK_FS_INFO_TAG  0x10101010
  ------------------
  |  Branch (104:9): [True: 0, False: 2]
  |  Branch (104:27): [True: 0, False: 2]
  ------------------
  105|      0|        tsk_error_set_errno(TSK_ERR_FS_ARG);
  ------------------
  |  |  351|      0|#define TSK_ERR_FS_ARG		(TSK_ERR_FS | 6)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  106|      0|        tsk_error_set_errstr
  107|      0|            ("tsk_fs_file_open_meta: called with NULL or unallocated structures");
  108|      0|        return NULL;
  109|      0|    }
  110|       |
  111|      2|    fs_file = a_fs_file;
  112|      2|    if (fs_file == NULL) {
  ------------------
  |  Branch (112:9): [True: 2, False: 0]
  ------------------
  113|      2|        if ((fs_file = tsk_fs_file_alloc(a_fs)) == NULL)
  ------------------
  |  Branch (113:13): [True: 0, False: 2]
  ------------------
  114|      0|            return NULL;
  115|      2|    }
  116|      0|    else {
  117|       |        /* if the structure passed has a name structure, free it
  118|       |         * because we won't use it. */
  119|      0|        if (fs_file->name) {
  ------------------
  |  Branch (119:13): [True: 0, False: 0]
  ------------------
  120|      0|            tsk_fs_name_free(fs_file->name);
  121|      0|            fs_file->name = NULL;
  122|      0|        }
  123|       |
  124|       |        // reset the rest of it
  125|      0|        tsk_fs_file_reset(fs_file);
  126|      0|    }
  127|       |
  128|      2|    if (a_fs->file_add_meta(a_fs, fs_file, a_addr)) {
  ------------------
  |  Branch (128:9): [True: 1, False: 1]
  ------------------
  129|      1|        if (a_fs_file == NULL)
  ------------------
  |  Branch (129:13): [True: 1, False: 0]
  ------------------
  130|      1|            tsk_fs_file_close(fs_file);
  131|      1|        return NULL;
  132|      1|    }
  133|       |
  134|      1|    return fs_file;
  135|      2|}

tsk_fs_meta_alloc:
   38|      2|{
   39|      2|    TSK_FS_META *fs_meta;
   40|       |
   41|      2|    if ((fs_meta =
  ------------------
  |  Branch (41:9): [True: 0, False: 2]
  ------------------
   42|      2|            (TSK_FS_META *) tsk_malloc(sizeof(TSK_FS_META))) == NULL)
   43|      0|        return NULL;
   44|       |
   45|      2|    fs_meta->attr_state = TSK_FS_META_ATTR_EMPTY;
   46|       |
   47|      2|    if (a_buf_len > 0) {
  ------------------
  |  Branch (47:9): [True: 2, False: 0]
  ------------------
   48|      2|        if ((fs_meta->content_ptr = tsk_malloc(a_buf_len)) == NULL) {
  ------------------
  |  Branch (48:13): [True: 0, False: 2]
  ------------------
   49|      0|            free(fs_meta);
   50|      0|            return NULL;
   51|      0|        }
   52|      2|        fs_meta->content_len = a_buf_len;
   53|      2|        fs_meta->reset_content = NULL;
   54|      2|    }
   55|       |
   56|       |    // assign the id so we know the structure is still alloc
   57|      2|    fs_meta->tag = TSK_FS_META_TAG;
  ------------------
  |  |  445|      2|#define TSK_FS_META_TAG 0x13524635
  ------------------
   58|       |
   59|      2|    return fs_meta;
   60|      2|}
tsk_fs_meta_close:
   99|      2|{
  100|      2|    TSK_FS_META_NAME_LIST *fs_name, *fs_name2;
  101|       |
  102|      2|    if ((!fs_meta) || (fs_meta->tag != TSK_FS_META_TAG))
  ------------------
  |  |  445|      2|#define TSK_FS_META_TAG 0x13524635
  ------------------
  |  Branch (102:9): [True: 0, False: 2]
  |  Branch (102:23): [True: 0, False: 2]
  ------------------
  103|      0|        return;
  104|       |
  105|       |    // clear the tag so we know the structure isn't alloc
  106|      2|    fs_meta->tag = 0;
  107|       |
  108|      2|    if (fs_meta->content_ptr) {
  ------------------
  |  Branch (108:9): [True: 2, False: 0]
  ------------------
  109|      2|        if (fs_meta->reset_content) {
  ------------------
  |  Branch (109:13): [True: 0, False: 2]
  ------------------
  110|      0|            fs_meta->reset_content(fs_meta->content_ptr);
  111|      0|        }
  112|       |
  113|      2|        free((char *) fs_meta->content_ptr);
  114|      2|    }
  115|       |
  116|      2|    fs_meta->content_ptr = NULL;
  117|      2|    fs_meta->content_len = 0;
  118|       |
  119|      2|    if (fs_meta->attr)
  ------------------
  |  Branch (119:9): [True: 2, False: 0]
  ------------------
  120|      2|        tsk_fs_attrlist_free(fs_meta->attr);
  121|      2|    fs_meta->attr = NULL;
  122|       |
  123|      2|    free(fs_meta->link);
  124|      2|    fs_meta->link = NULL;
  125|       |
  126|      2|    fs_name = fs_meta->name2;
  127|      4|    while (fs_name) {
  ------------------
  |  Branch (127:12): [True: 2, False: 2]
  ------------------
  128|      2|        fs_name2 = fs_name->next;
  129|      2|        fs_name->next = NULL;
  130|      2|        free(fs_name);
  131|      2|        fs_name = fs_name2;
  132|      2|    }
  133|       |
  134|      2|    free(fs_meta);
  135|      2|}
tsk_fs_meta_reset:
  143|      2|{
  144|      2|    void *content_ptr_tmp;
  145|      2|    size_t content_len_tmp;
  146|      2|    TSK_FS_ATTRLIST *attr_tmp;
  147|      2|    TSK_FS_META_NAME_LIST *name2_tmp;
  148|      2|    char *link_tmp;
  149|       |
  150|       |    // Clear content
  151|      2|    if (a_fs_meta->reset_content) {
  ------------------
  |  Branch (151:9): [True: 0, False: 2]
  ------------------
  152|      0|        a_fs_meta->reset_content(a_fs_meta->content_ptr);
  153|      0|    }
  154|       |
  155|       |    // backup pointers
  156|      2|    content_ptr_tmp = a_fs_meta->content_ptr;
  157|      2|    content_len_tmp = a_fs_meta->content_len;
  158|      2|    attr_tmp = a_fs_meta->attr;
  159|      2|    name2_tmp = a_fs_meta->name2;
  160|      2|    link_tmp = a_fs_meta->link;
  161|       |
  162|       |    // clear all data
  163|      2|    memset(a_fs_meta, 0, sizeof(TSK_FS_META));
  164|      2|    a_fs_meta->tag = TSK_FS_META_TAG;
  ------------------
  |  |  445|      2|#define TSK_FS_META_TAG 0x13524635
  ------------------
  165|       |
  166|       |    // restore and clear the pointers
  167|      2|    a_fs_meta->content_ptr = content_ptr_tmp;
  168|      2|    a_fs_meta->content_len = content_len_tmp;
  169|       |
  170|      2|    a_fs_meta->attr = attr_tmp;
  171|      2|    a_fs_meta->attr_state = TSK_FS_META_ATTR_EMPTY;
  172|       |
  173|      2|    a_fs_meta->name2 = name2_tmp;
  174|       |
  175|      2|    a_fs_meta->link = link_tmp;
  176|      2|    if (a_fs_meta->link)
  ------------------
  |  Branch (176:9): [True: 0, False: 2]
  ------------------
  177|      0|        a_fs_meta->link[0] = '\0';
  178|       |
  179|       |
  180|      2|    if (a_fs_meta->name2) {
  ------------------
  |  Branch (180:9): [True: 0, False: 2]
  ------------------
  181|      0|        name2_tmp = a_fs_meta->name2;
  182|      0|        while (name2_tmp) {
  ------------------
  |  Branch (182:16): [True: 0, False: 0]
  ------------------
  183|      0|            name2_tmp->name[0] = '\0';
  184|      0|            name2_tmp->par_inode = 0;
  185|      0|            name2_tmp->par_seq = 0;
  186|      0|            name2_tmp = name2_tmp->next;
  187|      0|        }
  188|       |
  189|      0|    }
  190|      2|}

tsk_fs_read:
   91|      1|{
   92|      1|    return tsk_fs_read_decrypt(a_fs, a_off, a_buf, a_len, 0);
   93|      1|}
tsk_fs_read_decrypt:
  107|      1|{
  108|       |    // do a sanity check on the read bounds, but only if the block
  109|       |    // value has been set.
  110|       |    // note that this could prevent us from viewing the FS slack...
  111|      1|    if ((a_fs->last_block_act > 0)
  ------------------
  |  Branch (111:9): [True: 0, False: 1]
  ------------------
  112|      1|        && ((TSK_DADDR_T) a_off >=
  ------------------
  |  Branch (112:12): [True: 0, False: 0]
  ------------------
  113|      0|            ((a_fs->last_block_act + 1) * a_fs->block_size))) {
  114|      0|        tsk_error_reset();
  115|      0|        tsk_error_set_errno(TSK_ERR_FS_READ);
  ------------------
  |  |  349|      0|#define TSK_ERR_FS_READ		(TSK_ERR_FS | 4)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  116|      0|        if ((TSK_DADDR_T) a_off <
  ------------------
  |  Branch (116:13): [True: 0, False: 0]
  ------------------
  117|      0|            ((a_fs->last_block + 1) * a_fs->block_size))
  118|      0|            tsk_error_set_errstr
  119|      0|                ("tsk_fs_read: Offset missing in partial image: %"
  120|      0|                PRIuDADDR ")", a_off);
  121|      0|        else
  122|      0|            tsk_error_set_errstr
  123|      0|                ("tsk_fs_read: Offset is too large for image: %" PRIuDADDR
  124|      0|                ")", a_off);
  125|      0|        return -1;
  126|      0|    }
  127|       |
  128|       |    // We need different logic for encrypted file systems
  129|      1|    if ((a_fs->flags & TSK_FS_INFO_FLAG_ENCRYPTED) && a_fs->block_size) {
  ------------------
  |  Branch (129:9): [True: 0, False: 1]
  |  Branch (129:55): [True: 0, False: 0]
  ------------------
  130|       |        // If we're reading on block boundaries and a multiple of block
  131|       |        // sizes, we can just decrypt directly to the buffer.
  132|      0|        if ((a_off % a_fs->block_size == 0) && (a_len % a_fs->block_size == 0)) {
  ------------------
  |  Branch (132:13): [True: 0, False: 0]
  |  Branch (132:48): [True: 0, False: 0]
  ------------------
  133|      0|           return tsk_fs_read_block_decrypt(a_fs, a_off / a_fs->block_size, a_buf, a_len, crypto_id);
  134|      0|        }
  135|       |
  136|       |        // Since we can only decrypt on block boundaries, we'll need to
  137|       |        // decrypt the blocks and then copy to the output buffer.
  138|       |
  139|       |        // Starting address needs to be aligned by block size;
  140|      0|        TSK_OFF_T bit_magic = a_fs->block_size - 1;
  141|      0|        TSK_OFF_T start = a_off & ~bit_magic;
  142|       |
  143|       |        // Ending address needs to be rounded up to the nearest
  144|       |        // block boundary.
  145|      0|        TSK_OFF_T end = (a_off + a_len + bit_magic) & ~bit_magic;
  146|      0|        TSK_OFF_T len = end - start;
  147|       |
  148|       |        // Decrypt the blocks to a temp buffer
  149|      0|        char * temp_buffer = tsk_malloc(len);
  150|      0|        if (temp_buffer == NULL) {
  ------------------
  |  Branch (150:13): [True: 0, False: 0]
  ------------------
  151|      0|            return -1;
  152|      0|        }
  153|       |
  154|      0|        if (tsk_fs_read_block_decrypt(a_fs, start / a_fs->block_size, temp_buffer,
  ------------------
  |  Branch (154:13): [True: 0, False: 0]
  ------------------
  155|      0|                              len, crypto_id) != len) {
  156|      0|            free(temp_buffer);
  157|      0|            return -1;
  158|      0|        }
  159|       |
  160|       |        // Copy the decrypted data
  161|      0|        memcpy(a_buf, temp_buffer + a_off - start, a_len);
  162|       |
  163|      0|        free(temp_buffer);
  164|       |
  165|      0|        return a_len;
  166|      0|    }
  167|       |
  168|      1|    if (((a_fs->block_pre_size) || (a_fs->block_post_size))
  ------------------
  |  Branch (168:10): [True: 0, False: 1]
  |  Branch (168:36): [True: 0, False: 1]
  ------------------
  169|      1|        && (a_fs->block_size)) {
  ------------------
  |  Branch (169:12): [True: 0, False: 0]
  ------------------
  170|      0|        return fs_prepost_read(a_fs, a_off, a_buf, a_len);
  171|      0|    }
  172|      1|    else {
  173|      1|        return tsk_img_read(a_fs->img_info, a_off + a_fs->offset, a_buf,
  174|      1|            a_len);
  175|      1|    }
  176|      1|}

tsk_fs_open_img:
  108|      1|{
  109|      1|    return tsk_fs_open_img_decrypt(a_img_info, a_offset, a_ftype, "");
  110|      1|}
tsk_fs_open_img_decrypt:
  128|      1|{
  129|      1|    TSK_FS_INFO *fs_info;
  130|       |
  131|      1|    const struct {
  132|      1|        char* name;
  133|      1|        TSK_FS_INFO* (*open)(TSK_IMG_INFO*, TSK_OFF_T,
  134|      1|                                 TSK_FS_TYPE_ENUM, uint8_t);
  135|       |        // This type should be the _DETECT version because it used
  136|       |        // during autodetection
  137|      1|        TSK_FS_TYPE_ENUM type;
  138|      1|    } FS_OPENERS[] = {
  139|      1|        { "NTFS",     ntfs_open,    TSK_FS_TYPE_NTFS_DETECT    },
  140|      1|        { "FAT",      fatfs_open,   TSK_FS_TYPE_FAT_DETECT     },
  141|      1|        { "EXT2/3/4", ext2fs_open,  TSK_FS_TYPE_EXT_DETECT     },
  142|      1|        { "UFS",      ffs_open,     TSK_FS_TYPE_FFS_DETECT     },
  143|      1|        { "YAFFS2",   yaffs2_open,  TSK_FS_TYPE_YAFFS2_DETECT  },
  144|      1|#if TSK_USE_HFS
  145|      1|        { "HFS",      hfs_open,     TSK_FS_TYPE_HFS_DETECT     },
  146|      1|#endif
  147|      1|        { "ISO9660",  iso9660_open, TSK_FS_TYPE_ISO9660_DETECT },
  148|      1|        { "APFS",     apfs_open_auto_detect,    TSK_FS_TYPE_APFS_DETECT }
  149|      1|    };
  150|      1|    if (a_img_info == NULL) {
  ------------------
  |  Branch (150:9): [True: 0, False: 1]
  ------------------
  151|      0|        tsk_error_reset();
  152|      0|        tsk_error_set_errno(TSK_ERR_FS_ARG);
  ------------------
  |  |  351|      0|#define TSK_ERR_FS_ARG		(TSK_ERR_FS | 6)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  153|      0|        tsk_error_set_errstr("tsk_fs_open_img: Null image handle");
  154|      0|        return NULL;
  155|      0|    }
  156|       |
  157|       |	/* If the image is type IMG_DIR_INFO, then the file system is
  158|       |	 * automatically the logical directory file system type. It is an
  159|       |	 * error to try to use any other file system type in that case.
  160|       |	 */
  161|      1|	if (a_img_info->itype == TSK_IMG_TYPE_LOGICAL) {
  ------------------
  |  Branch (161:6): [True: 0, False: 1]
  ------------------
  162|      0|		if (!(a_ftype == TSK_FS_TYPE_DETECT || a_ftype == TSK_FS_TYPE_LOGICAL)) {
  ------------------
  |  Branch (162:9): [True: 0, False: 0]
  |  Branch (162:42): [True: 0, False: 0]
  ------------------
  163|      0|			tsk_error_reset();
  164|      0|			tsk_error_set_errno(TSK_ERR_FS_ARG);
  ------------------
  |  |  351|      0|#define TSK_ERR_FS_ARG		(TSK_ERR_FS | 6)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  165|      0|			tsk_error_set_errstr("tsk_fs_open_img: Incompatable file system type given for logical file image");
  166|      0|			return NULL;
  167|      0|		}
  168|       |
  169|      0|		return logical_fs_open(a_img_info);
  170|      0|	}
  171|       |
  172|       |    /* We will try different file systems ...
  173|       |     * We need to try all of them in case more than one matches
  174|       |     */
  175|      1|    if (a_ftype == TSK_FS_TYPE_DETECT) {
  ------------------
  |  Branch (175:9): [True: 0, False: 1]
  ------------------
  176|      0|        unsigned long i;
  177|      0|        const char *name_first = "";
  178|      0|        TSK_FS_INFO *fs_first = NULL;
  179|       |
  180|      0|        if (tsk_verbose)
  ------------------
  |  Branch (180:13): [True: 0, False: 0]
  ------------------
  181|      0|            tsk_fprintf(stderr,
  182|      0|                "fsopen: Auto detection mode at offset %" PRIdOFF "\n",
  183|      0|                a_offset);
  184|       |
  185|      0|        for (i = 0; i < sizeof(FS_OPENERS)/sizeof(FS_OPENERS[0]); ++i) {
  ------------------
  |  Branch (185:21): [True: 0, False: 0]
  ------------------
  186|      0|            if ((fs_info = FS_OPENERS[i].open(
  ------------------
  |  Branch (186:17): [True: 0, False: 0]
  ------------------
  187|      0|                    a_img_info, a_offset, FS_OPENERS[i].type, 1)) != NULL) {
  188|       |                // fs opens as type i
  189|      0|                if (fs_first == NULL) {
  ------------------
  |  Branch (189:21): [True: 0, False: 0]
  ------------------
  190|       |                    // first success opening fs
  191|      0|                    name_first = FS_OPENERS[i].name;
  192|      0|                    fs_first = fs_info;
  193|      0|                }
  194|      0|                else {
  195|       |                    // second success opening fs, which means we
  196|       |                    // cannot autodetect the fs type and must give up
  197|      0|                    fs_first->close(fs_first);
  198|      0|                    fs_info->close(fs_info);
  199|      0|                    tsk_error_reset();
  200|      0|                    tsk_error_set_errno(TSK_ERR_FS_MULTTYPE);
  ------------------
  |  |  365|      0|#define TSK_ERR_FS_MULTTYPE    (TSK_ERR_FS | 20)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  201|      0|                    tsk_error_set_errstr(
  202|      0|                        "%s or %s", FS_OPENERS[i].name, name_first);
  203|      0|                    return NULL;
  204|      0|                }
  205|      0|            }
  206|      0|            else {
  207|       |                // fs does not open as type i
  208|      0|                tsk_error_reset();
  209|      0|            }
  210|      0|        }
  211|       |
  212|      0|        if (fs_first == NULL) {
  ------------------
  |  Branch (212:13): [True: 0, False: 0]
  ------------------
  213|      0|            tsk_error_reset();
  214|       |
  215|       |            // If we're still at the start of the image and haven't identified any volume systems or file
  216|       |            // systems, check if the image type is a known unsupported type.
  217|      0|            int unsupportedSignatureFound = 0;
  218|      0|            if (a_offset == 0) {
  ------------------
  |  Branch (218:17): [True: 0, False: 0]
  ------------------
  219|      0|                char * imageType = detectUnsupportedImageType(a_img_info);
  220|      0|                if (imageType != NULL) {
  ------------------
  |  Branch (220:21): [True: 0, False: 0]
  ------------------
  221|      0|                    unsupportedSignatureFound = 1;
  222|      0|                    tsk_error_reset();
  223|      0|                    tsk_error_set_errno(TSK_ERR_IMG_UNSUPTYPE);
  ------------------
  |  |  314|      0|#define TSK_ERR_IMG_UNSUPTYPE 	(TSK_ERR_IMG | 3)
  |  |  ------------------
  |  |  |  |  299|      0|#define TSK_ERR_IMG	0x02000000
  |  |  ------------------
  ------------------
  224|      0|                    tsk_error_set_errstr("%s", imageType);
  225|      0|                    free(imageType);
  226|      0|                }
  227|      0|            }
  228|       |
  229|      0|            if (!unsupportedSignatureFound) {
  ------------------
  |  Branch (229:17): [True: 0, False: 0]
  ------------------
  230|       |                // Check if the file system appears to be encrypted
  231|      0|                encryption_detected_result* result = detectVolumeEncryption(a_img_info, a_offset);
  232|      0|                if (result != NULL) {
  ------------------
  |  Branch (232:21): [True: 0, False: 0]
  ------------------
  233|      0|                    if (result->encryptionType == ENCRYPTION_DETECTED_SIGNATURE) {
  ------------------
  |  Branch (233:25): [True: 0, False: 0]
  ------------------
  234|      0|                        tsk_error_set_errno(TSK_ERR_FS_ENCRYPTED);
  ------------------
  |  |  363|      0|#define TSK_ERR_FS_ENCRYPTED    (TSK_ERR_FS | 18)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  235|      0|                        tsk_error_set_errstr("%s", result->desc);
  236|      0|                    }
  237|      0|                    else if (result->encryptionType == ENCRYPTION_DETECTED_ENTROPY) {
  ------------------
  |  Branch (237:30): [True: 0, False: 0]
  ------------------
  238|      0|                        tsk_error_set_errno(TSK_ERR_FS_POSSIBLY_ENCRYPTED);
  ------------------
  |  |  364|      0|#define TSK_ERR_FS_POSSIBLY_ENCRYPTED    (TSK_ERR_FS | 19)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  239|      0|                        tsk_error_set_errstr("%s", result->desc);
  240|      0|                    }
  241|      0|                    else {
  242|      0|                        tsk_error_set_errno(TSK_ERR_FS_UNKTYPE);
  ------------------
  |  |  345|      0|#define TSK_ERR_FS_UNKTYPE	(TSK_ERR_FS | 0)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  243|      0|                    }
  244|      0|                    free(result);
  245|      0|                    result = NULL;
  246|      0|                }
  247|      0|                else {
  248|      0|                    tsk_error_set_errno(TSK_ERR_FS_UNKTYPE);
  ------------------
  |  |  345|      0|#define TSK_ERR_FS_UNKTYPE	(TSK_ERR_FS | 0)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  249|      0|                }
  250|      0|            }
  251|      0|        }
  252|      0|        return fs_first;
  253|      0|    }
  254|      1|    else if (TSK_FS_TYPE_ISNTFS(a_ftype)) {
  ------------------
  |  |  836|      1|    (((ftype) & TSK_FS_TYPE_NTFS_DETECT)?1:0)
  |  |  ------------------
  |  |  |  Branch (836:5): [True: 0, False: 1]
  |  |  |  Branch (836:6): [True: 0, False: 1]
  |  |  ------------------
  ------------------
  255|      0|        return ntfs_open(a_img_info, a_offset, a_ftype, 0);
  256|      0|    }
  257|      1|    else if (TSK_FS_TYPE_ISFAT(a_ftype)) {
  ------------------
  |  |  843|      1|    (((ftype) & TSK_FS_TYPE_FAT_DETECT)?1:0)
  |  |  ------------------
  |  |  |  Branch (843:5): [True: 0, False: 1]
  |  |  |  Branch (843:6): [True: 0, False: 1]
  |  |  ------------------
  ------------------
  258|      0|        return fatfs_open(a_img_info, a_offset, a_ftype, 0);
  259|      0|    }
  260|      1|    else if (TSK_FS_TYPE_ISFFS(a_ftype)) {
  ------------------
  |  |  850|      1|    (((ftype) & TSK_FS_TYPE_FFS_DETECT)?1:0)
  |  |  ------------------
  |  |  |  Branch (850:5): [True: 0, False: 1]
  |  |  |  Branch (850:6): [True: 0, False: 1]
  |  |  ------------------
  ------------------
  261|      0|        return ffs_open(a_img_info, a_offset, a_ftype, 0);
  262|      0|    }
  263|      1|    else if (TSK_FS_TYPE_ISEXT(a_ftype)) {
  ------------------
  |  |  857|      1|    (((ftype) & TSK_FS_TYPE_EXT_DETECT)?1:0)
  |  |  ------------------
  |  |  |  Branch (857:5): [True: 0, False: 1]
  |  |  |  Branch (857:6): [True: 0, False: 1]
  |  |  ------------------
  ------------------
  264|      0|        return ext2fs_open(a_img_info, a_offset, a_ftype, 0);
  265|      0|    }
  266|      1|    else if (TSK_FS_TYPE_ISHFS(a_ftype)) {
  ------------------
  |  |  871|      1|    (((ftype) & TSK_FS_TYPE_HFS_DETECT)?1:0)
  |  |  ------------------
  |  |  |  Branch (871:5): [True: 1, False: 0]
  |  |  |  Branch (871:6): [True: 1, False: 0]
  |  |  ------------------
  ------------------
  267|      1|        return hfs_open(a_img_info, a_offset, a_ftype, 0);
  268|      1|    }
  269|      0|    else if (TSK_FS_TYPE_ISISO9660(a_ftype)) {
  ------------------
  |  |  864|      0|    (((ftype) & TSK_FS_TYPE_ISO9660_DETECT)?1:0)
  |  |  ------------------
  |  |  |  Branch (864:5): [True: 0, False: 0]
  |  |  |  Branch (864:6): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  270|      0|        return iso9660_open(a_img_info, a_offset, a_ftype, 0);
  271|      0|    }
  272|      0|    else if (TSK_FS_TYPE_ISRAW(a_ftype)) {
  ------------------
  |  |  899|      0|    (((ftype) & TSK_FS_TYPE_RAW_DETECT)?1:0)
  |  |  ------------------
  |  |  |  Branch (899:5): [True: 0, False: 0]
  |  |  |  Branch (899:6): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  273|      0|        return rawfs_open(a_img_info, a_offset);
  274|      0|    }
  275|      0|    else if (TSK_FS_TYPE_ISSWAP(a_ftype)) {
  ------------------
  |  |  878|      0|    (((ftype) & TSK_FS_TYPE_SWAP_DETECT)?1:0)
  |  |  ------------------
  |  |  |  Branch (878:5): [True: 0, False: 0]
  |  |  |  Branch (878:6): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  276|      0|        return swapfs_open(a_img_info, a_offset);
  277|      0|    }
  278|      0|    else if (TSK_FS_TYPE_ISYAFFS2(a_ftype)) {
  ------------------
  |  |  885|      0|    (((ftype) & TSK_FS_TYPE_YAFFS2_DETECT)?1:0)
  |  |  ------------------
  |  |  |  Branch (885:5): [True: 0, False: 0]
  |  |  |  Branch (885:6): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  279|      0|        return yaffs2_open(a_img_info, a_offset, a_ftype, 0);
  280|      0|    } 
  281|      0|    else if (TSK_FS_TYPE_ISAPFS(a_ftype)) {
  ------------------
  |  |  906|      0|    (((ftype) & TSK_FS_TYPE_APFS_DETECT)?1:0)
  |  |  ------------------
  |  |  |  Branch (906:5): [True: 0, False: 0]
  |  |  |  Branch (906:6): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  282|      0|        return apfs_open(a_img_info, a_offset, a_ftype, a_pass);
  283|      0|    }
  284|      0|    tsk_error_reset();
  285|      0|    tsk_error_set_errno(TSK_ERR_FS_UNSUPTYPE);
  ------------------
  |  |  346|      0|#define TSK_ERR_FS_UNSUPTYPE	(TSK_ERR_FS | 1)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  286|      0|    tsk_error_set_errstr("%X", (int) a_ftype);
  287|      0|    return NULL;
  288|      1|}
tsk_fs_malloc:
  311|      1|{
  312|      1|    TSK_FS_INFO *fs_info;
  313|      1|    if ((fs_info = (TSK_FS_INFO *) tsk_malloc(a_len)) == NULL)
  ------------------
  |  Branch (313:9): [True: 0, False: 1]
  ------------------
  314|      0|        return NULL;
  315|      1|    tsk_init_lock(&fs_info->list_inum_named_lock);
  316|      1|    tsk_init_lock(&fs_info->orphan_dir_lock);
  317|       |
  318|      1|    fs_info->list_inum_named = NULL;
  319|       |
  320|      1|    return fs_info;
  321|      1|}
tsk_fs_free:
  328|      1|{
  329|      1|    if (a_fs_info->list_inum_named) {
  ------------------
  |  Branch (329:9): [True: 0, False: 1]
  ------------------
  330|      0|        tsk_list_free(a_fs_info->list_inum_named);
  331|      0|        a_fs_info->list_inum_named = NULL;
  332|      0|    }
  333|       |
  334|       |    /* we should probably get the lock, but we're 
  335|       |     * about to kill the entire object so there are
  336|       |     * bigger problems if another thread is still 
  337|       |     * using the fs */
  338|      1|    if (a_fs_info->orphan_dir) {
  ------------------
  |  Branch (338:9): [True: 0, False: 1]
  ------------------
  339|      0|        tsk_fs_dir_close(a_fs_info->orphan_dir);
  340|      0|        a_fs_info->orphan_dir = NULL;
  341|      0|    }
  342|       |
  343|       |
  344|      1|    tsk_deinit_lock(&a_fs_info->list_inum_named_lock);
  345|      1|    tsk_deinit_lock(&a_fs_info->orphan_dir_lock);
  346|       |
  347|      1|    free(a_fs_info);
  348|      1|}

hfs_checked_read_random:
  108|      1|{
  109|      1|    ssize_t r;
  110|       |
  111|      1|    r = tsk_fs_read(fs, offs, buf, len);
  112|      1|    if (r != (ssize_t) len) {
  ------------------
  |  Branch (112:9): [True: 0, False: 1]
  ------------------
  113|      0|        if (r >= 0) {
  ------------------
  |  Branch (113:13): [True: 0, False: 0]
  ------------------
  114|      0|            tsk_error_reset();
  115|      0|            tsk_error_set_errno(TSK_ERR_FS_READ);
  ------------------
  |  |  349|      0|#define TSK_ERR_FS_READ		(TSK_ERR_FS | 4)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  116|      0|        }
  117|      0|        return 1;
  118|      0|    }
  119|      1|    return 0;
  120|      1|}
hfs_open:
 6426|      1|{
 6427|      1|    HFS_INFO *hfs;
 6428|      1|    unsigned int len;
 6429|      1|    TSK_FS_INFO *fs;
 6430|      1|    ssize_t cnt;
 6431|      1|    TSK_FS_FILE *file;          // The root directory, or the metadata directories
 6432|      1|    TSK_INUM_T inum;            // The inum (or CNID) of the metadata directories
 6433|      1|    int8_t result;              // of tsk_fs_path2inum()
 6434|       |
 6435|      1|    tsk_error_reset();
 6436|       |
 6437|      1|    if (TSK_FS_TYPE_ISHFS(ftype) == 0) {
  ------------------
  |  |  871|      1|    (((ftype) & TSK_FS_TYPE_HFS_DETECT)?1:0)
  |  |  ------------------
  |  |  |  Branch (871:6): [True: 1, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (6437:9): [True: 0, False: 1]
  ------------------
 6438|      0|        tsk_error_set_errno(TSK_ERR_FS_ARG);
  ------------------
  |  |  351|      0|#define TSK_ERR_FS_ARG		(TSK_ERR_FS | 6)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
 6439|      0|        tsk_error_set_errstr("Invalid FS Type in hfs_open");
 6440|      0|        return NULL;
 6441|      0|    }
 6442|       |
 6443|      1|    if ((hfs = (HFS_INFO *) tsk_fs_malloc(sizeof(HFS_INFO))) == NULL)
  ------------------
  |  Branch (6443:9): [True: 0, False: 1]
  ------------------
 6444|      0|        return NULL;
 6445|       |
 6446|      1|    fs = &(hfs->fs_info);
 6447|       |
 6448|      1|    fs->ftype = TSK_FS_TYPE_HFS;
 6449|      1|    fs->duname = "Allocation Block";
 6450|      1|    fs->tag = TSK_FS_INFO_TAG;
  ------------------
  |  |  933|      1|#define TSK_FS_INFO_TAG  0x10101010
  ------------------
 6451|      1|    fs->flags = 0;
 6452|       |
 6453|      1|    fs->img_info = img_info;
 6454|      1|    fs->offset = offset;
 6455|       |
 6456|       |    /*
 6457|       |     * Read the superblock.
 6458|       |     */
 6459|      1|    len = sizeof(hfs_plus_vh);
 6460|      1|    if ((hfs->fs = (hfs_plus_vh *) tsk_malloc(len)) == NULL) {
  ------------------
  |  Branch (6460:9): [True: 0, False: 1]
  ------------------
 6461|      0|        fs->tag = 0;
 6462|      0|        tsk_fs_free((TSK_FS_INFO *)hfs);
 6463|      0|        return NULL;
 6464|      0|    }
 6465|       |
 6466|      1|    if (hfs_checked_read_random(fs, (char *) hfs->fs, len,
  ------------------
  |  Branch (6466:9): [True: 0, False: 1]
  ------------------
 6467|      1|            (TSK_OFF_T) HFS_VH_OFF)) {
  ------------------
  |  |  269|      1|#define HFS_VH_OFF	1024    // byte offset in volume to volume header
  ------------------
 6468|      0|        tsk_error_set_errstr2("hfs_open: superblock");
 6469|      0|        fs->tag = 0;
 6470|      0|        free(hfs->fs);
 6471|      0|        tsk_fs_free((TSK_FS_INFO *)hfs);
 6472|      0|        return NULL;
 6473|      0|    }
 6474|       |
 6475|       |    /*
 6476|       |     * Verify we are looking at an HFS+ image
 6477|       |     */
 6478|      1|    if (tsk_fs_guessu16(fs, hfs->fs->signature, HFS_VH_SIG_HFSPLUS) &&
  ------------------
  |  |  296|      2|     tsk_guess_end_u16(&(fs->endian), (x), (mag))
  |  |  ------------------
  |  |  |  Branch (296:6): [True: 0, False: 1]
  |  |  ------------------
  ------------------
 6479|      1|        tsk_fs_guessu16(fs, hfs->fs->signature, HFS_VH_SIG_HFSX) &&
  ------------------
  |  |  296|      1|     tsk_guess_end_u16(&(fs->endian), (x), (mag))
  |  |  ------------------
  |  |  |  Branch (296:6): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 6480|      1|        tsk_fs_guessu16(fs, hfs->fs->signature, HFS_VH_SIG_HFS)) {
  ------------------
  |  |  296|      0|     tsk_guess_end_u16(&(fs->endian), (x), (mag))
  |  |  ------------------
  |  |  |  Branch (296:6): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 6481|       |
 6482|      0|        fs->tag = 0;
 6483|      0|        free(hfs->fs);
 6484|      0|        tsk_fs_free((TSK_FS_INFO *)hfs);
 6485|      0|        tsk_error_set_errno(TSK_ERR_FS_MAGIC);
  ------------------
  |  |  355|      0|#define TSK_ERR_FS_MAGIC	(TSK_ERR_FS | 10)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
 6486|      0|        tsk_error_set_errstr("not an HFS+ file system (magic)");
 6487|      0|        return NULL;
 6488|      0|    }
 6489|       |
 6490|       |    /*
 6491|       |     * Handle an HFS-wrapped HFS+ image, which is a HFS volume that contains
 6492|       |     * the HFS+ volume inside of it.
 6493|       |     */
 6494|      1|    if (tsk_getu16(fs->endian, hfs->fs->signature) == HFS_VH_SIG_HFS) {
  ------------------
  |  |   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)) )
  ------------------
                  if (tsk_getu16(fs->endian, hfs->fs->signature) == HFS_VH_SIG_HFS) {
  ------------------
  |  |  272|      1|#define HFS_VH_SIG_HFS	    0x4244      /* BD in big endian */
  ------------------
  |  Branch (6494:9): [True: 0, False: 1]
  ------------------
 6495|       |
 6496|      0|        hfs_mdb *wrapper_sb = (hfs_mdb *) hfs->fs;
 6497|       |
 6498|       |        // Verify that we are setting a wrapper and not a normal HFS volume
 6499|      0|        if ((tsk_getu16(fs->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)) )
  ------------------
  |  Branch (6499:13): [True: 0, False: 0]
  ------------------
 6500|      0|                    wrapper_sb->drEmbedSigWord) == HFS_VH_SIG_HFSPLUS)
  ------------------
  |  |  273|      0|#define HFS_VH_SIG_HFSPLUS	0x482b  /* H+ in big endian */
  ------------------
 6501|      0|            || (tsk_getu16(fs->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)) )
  ------------------
  |  Branch (6501:16): [True: 0, False: 0]
  ------------------
 6502|      0|                    wrapper_sb->drEmbedSigWord) == HFS_VH_SIG_HFSX)) {
  ------------------
  |  |  274|      0|#define HFS_VH_SIG_HFSX      0x4858     /* HX in big endian */
  ------------------
 6503|       |
 6504|      0|            TSK_FS_INFO *fs_info2;
 6505|       |            // offset in sectors to start of first HFS block
 6506|      0|            uint16_t drAlBlSt =
 6507|      0|                tsk_getu16(fs->endian, wrapper_sb->drAlBlSt);
  ------------------
  |  |   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)) )
  ------------------
 6508|       |
 6509|       |            // size of each HFS block
 6510|      0|            uint32_t drAlBlkSiz =
 6511|      0|                tsk_getu32(fs->endian, wrapper_sb->drAlBlkSiz);
  ------------------
  |  |  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) ) )
  ------------------
 6512|       |
 6513|       |            // start of embedded FS
 6514|      0|            uint16_t startBlock = tsk_getu16(fs->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)) )
  ------------------
 6515|      0|                wrapper_sb->drEmbedExtent_startBlock);
 6516|       |
 6517|       |            // calculate the offset; 512 here is intentional.
 6518|       |            // TN1150 says "The drAlBlSt field contains the offset, in
 6519|       |            // 512-byte blocks, of the wrapper's allocation block 0 relative
 6520|       |            // to the start of the volume"
 6521|      0|            TSK_OFF_T hfsplus_offset =
 6522|      0|                (drAlBlSt * (TSK_OFF_T) 512) +
 6523|      0|                (drAlBlkSiz * (TSK_OFF_T) startBlock);
 6524|       |
 6525|      0|            if (tsk_verbose)
  ------------------
  |  Branch (6525:17): [True: 0, False: 0]
  ------------------
 6526|      0|                tsk_fprintf(stderr,
 6527|      0|                    "hfs_open: HFS+/HFSX within HFS wrapper at byte offset %"
 6528|      0|					PRIdOFF "\n", hfsplus_offset);
 6529|       |
 6530|      0|            fs->tag = 0;
 6531|      0|            free(hfs->fs);
 6532|      0|            tsk_fs_free((TSK_FS_INFO *)hfs);
 6533|       |
 6534|       |            /* just re-open with the new offset, then record the offset */
 6535|      0|            if (hfsplus_offset == 0) {
  ------------------
  |  Branch (6535:17): [True: 0, False: 0]
  ------------------
 6536|      0|                tsk_error_set_errno(TSK_ERR_FS_CORRUPT);
  ------------------
  |  |  361|      0|#define TSK_ERR_FS_CORRUPT	(TSK_ERR_FS | 16)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
 6537|      0|                tsk_error_set_errstr("HFS+ offset is zero");
 6538|      0|                return NULL;
 6539|      0|            }
 6540|      0|            fs_info2 =
 6541|      0|                hfs_open(img_info, offset + hfsplus_offset, ftype, test);
 6542|       |
 6543|      0|            if (fs_info2)
  ------------------
  |  Branch (6543:17): [True: 0, False: 0]
  ------------------
 6544|      0|                ((HFS_INFO *) fs_info2)->hfs_wrapper_offset =
 6545|      0|                    hfsplus_offset;
 6546|       |
 6547|      0|            return fs_info2;
 6548|      0|        }
 6549|      0|        else {
 6550|      0|            fs->tag = 0;
 6551|      0|            free(hfs->fs);
 6552|      0|            tsk_fs_free((TSK_FS_INFO *)hfs);
 6553|      0|            tsk_error_set_errno(TSK_ERR_FS_MAGIC);
  ------------------
  |  |  355|      0|#define TSK_ERR_FS_MAGIC	(TSK_ERR_FS | 10)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
 6554|      0|            tsk_error_set_errstr
 6555|      0|                ("HFS file systems (other than wrappers HFS+/HFSX file systems) are not supported");
 6556|      0|            return NULL;
 6557|      0|        }
 6558|      0|    }
 6559|       |
 6560|      1|    fs->block_count = tsk_getu32(fs->endian, hfs->fs->blk_cnt);
  ------------------
  |  |  119|      1|#define tsk_getu32(endian, x)	\
  |  |  120|      1|(uint32_t)( ((endian) == TSK_LIT_ENDIAN)  ?	\
  |  |  ------------------
  |  |  |  Branch (120:13): [True: 0, False: 1]
  |  |  ------------------
  |  |  121|      1|            ((((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|      1|                                          :	\
  |  |  126|      1|            ((((uint8_t *)(x))[3] <<  0) + \
  |  |  127|      1|             (((uint8_t *)(x))[2] <<  8) + \
  |  |  128|      1|             (((uint8_t *)(x))[1] << 16) + \
  |  |  129|      1|             ((uint32_t)((uint8_t *)(x))[0] << 24) ) )
  ------------------
 6561|      1|    fs->first_block = 0;
 6562|      1|    fs->last_block = fs->last_block_act = fs->block_count - 1;
 6563|       |
 6564|       |    /* this isn't really accurate; fs->block_size reports only the size
 6565|       |       of the allocation block; the size of the device block has to be
 6566|       |       found from the device (allocation block size should always be
 6567|       |       larger than device block size and an even multiple of the device
 6568|       |       block size) */
 6569|      1|    fs->dev_bsize = fs->block_size =
 6570|      1|        tsk_getu32(fs->endian, hfs->fs->blk_sz);
  ------------------
  |  |  119|      1|#define tsk_getu32(endian, x)	\
  |  |  120|      1|(uint32_t)( ((endian) == TSK_LIT_ENDIAN)  ?	\
  |  |  ------------------
  |  |  |  Branch (120:13): [True: 0, False: 1]
  |  |  ------------------
  |  |  121|      1|            ((((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|      1|                                          :	\
  |  |  126|      1|            ((((uint8_t *)(x))[3] <<  0) + \
  |  |  127|      1|             (((uint8_t *)(x))[2] <<  8) + \
  |  |  128|      1|             (((uint8_t *)(x))[1] << 16) + \
  |  |  129|      1|             ((uint32_t)((uint8_t *)(x))[0] << 24) ) )
  ------------------
 6571|       |
 6572|       |    // determine the last block we have in this image
 6573|      1|    if (fs->block_size <= 1) {
  ------------------
  |  Branch (6573:9): [True: 0, False: 1]
  ------------------
 6574|      0|        fs->tag = 0;
 6575|      0|        free(hfs->fs);
 6576|      0|        tsk_fs_free((TSK_FS_INFO *)hfs);
 6577|      0|        tsk_error_set_errno(TSK_ERR_FS_CORRUPT);
  ------------------
  |  |  361|      0|#define TSK_ERR_FS_CORRUPT	(TSK_ERR_FS | 16)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
 6578|      0|        tsk_error_set_errstr("HFS+ allocation block size too small");
 6579|      0|        return NULL;
 6580|      0|    }
 6581|      1|    if ((TSK_DADDR_T) ((img_info->size - offset) / fs->block_size) <
  ------------------
  |  Branch (6581:9): [True: 0, False: 1]
  ------------------
 6582|      1|        fs->block_count)
 6583|      0|        fs->last_block_act =
 6584|      0|            (img_info->size - offset) / fs->block_size - 1;
 6585|       |
 6586|       |    // Initialize the lock
 6587|      1|    tsk_init_lock(&(hfs->metadata_dir_cache_lock));
 6588|       |
 6589|       |    /*
 6590|       |     * Set function pointers
 6591|       |     */
 6592|      1|    fs->inode_walk = hfs_inode_walk;
 6593|      1|    fs->block_walk = hfs_block_walk;
 6594|      1|    fs->block_getflags = hfs_block_getflags;
 6595|      1|    fs->load_attrs = hfs_load_attrs;
 6596|      1|    fs->get_default_attr_type = hfs_get_default_attr_type;
 6597|       |
 6598|      1|    fs->file_add_meta = hfs_inode_lookup;
 6599|      1|    fs->dir_open_meta = hfs_dir_open_meta;
 6600|      1|    fs->fsstat = hfs_fsstat;
 6601|      1|    fs->fscheck = hfs_fscheck;
 6602|      1|    fs->istat = hfs_istat;
 6603|      1|    fs->close = hfs_close;
 6604|       |
 6605|       |    // lazy loading of block map
 6606|      1|    hfs->blockmap_file = NULL;
 6607|      1|    hfs->blockmap_attr = NULL;
 6608|      1|    hfs->blockmap_cache_start = -1;
 6609|      1|    hfs->blockmap_cache_len = 0;
 6610|       |
 6611|      1|    fs->first_inum = HFS_ROOT_INUM;
  ------------------
  |  |  142|      1|#define HFS_ROOT_INUM HFS_ROOT_FOLDER_ID
  |  |  ------------------
  |  |  |  |  123|      1|#define HFS_ROOT_FOLDER_ID         2
  |  |  ------------------
  ------------------
 6612|      1|    fs->root_inum = HFS_ROOT_INUM;
  ------------------
  |  |  142|      1|#define HFS_ROOT_INUM HFS_ROOT_FOLDER_ID
  |  |  ------------------
  |  |  |  |  123|      1|#define HFS_ROOT_FOLDER_ID         2
  |  |  ------------------
  ------------------
 6613|      1|    fs->last_inum = HFS_FIRST_USER_CNID - 1;    // we will later increase this
  ------------------
  |  |  141|      1|#define HFS_FIRST_USER_CNID	   16
  ------------------
 6614|      1|    fs->inum_count = fs->last_inum - fs->first_inum + 1;
 6615|       |
 6616|       |    /* We will load the extents file data when we need it */
 6617|      1|    hfs->extents_file = NULL;
 6618|      1|    hfs->extents_attr = NULL;
 6619|       |
 6620|      1|    if (tsk_getu32(fs->endian,
  ------------------
  |  |  119|      1|#define tsk_getu32(endian, x)	\
  |  |  120|      1|(uint32_t)( ((endian) == TSK_LIT_ENDIAN)  ?	\
  |  |  ------------------
  |  |  |  Branch (120:13): [True: 0, False: 1]
  |  |  ------------------
  |  |  121|      1|            ((((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|      1|                                          :	\
  |  |  126|      1|            ((((uint8_t *)(x))[3] <<  0) + \
  |  |  127|      1|             (((uint8_t *)(x))[2] <<  8) + \
  |  |  128|      1|             (((uint8_t *)(x))[1] << 16) + \
  |  |  129|      1|             ((uint32_t)((uint8_t *)(x))[0] << 24) ) )
  ------------------
  |  Branch (6620:9): [True: 1, False: 0]
  ------------------
 6621|      1|                hfs->fs->start_file.extents[0].blk_cnt) == 0) {
 6622|      1|            if (tsk_verbose)
  ------------------
  |  Branch (6622:17): [True: 0, False: 1]
  ------------------
 6623|      0|                tsk_fprintf(stderr,
 6624|      0|                    "hfs_open: Optional Startup File is not present.\n");
 6625|      1|            hfs->has_startup_file = FALSE;
  ------------------
  |  |  453|      1|#define FALSE 0
  ------------------
 6626|      1|        }
 6627|      0|    else {
 6628|      0|        if (tsk_verbose)
  ------------------
  |  Branch (6628:13): [True: 0, False: 0]
  ------------------
 6629|      0|            tsk_fprintf(stderr, "hfs_open: Startup File is present.\n");
 6630|      0|        hfs->has_startup_file = TRUE;
  ------------------
  |  |  454|      0|#define TRUE  ( !FALSE )
  |  |  ------------------
  |  |  |  |  453|      0|#define FALSE 0
  |  |  ------------------
  ------------------
 6631|      0|    }
 6632|       |
 6633|      1|    if (tsk_getu32(fs->endian, hfs->fs->ext_file.extents[0].blk_cnt) == 0) {
  ------------------
  |  |  119|      1|#define tsk_getu32(endian, x)	\
  |  |  120|      1|(uint32_t)( ((endian) == TSK_LIT_ENDIAN)  ?	\
  |  |  ------------------
  |  |  |  Branch (120:13): [True: 0, False: 1]
  |  |  ------------------
  |  |  121|      1|            ((((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|      1|                                          :	\
  |  |  126|      1|            ((((uint8_t *)(x))[3] <<  0) + \
  |  |  127|      1|             (((uint8_t *)(x))[2] <<  8) + \
  |  |  128|      1|             (((uint8_t *)(x))[1] << 16) + \
  |  |  129|      1|             ((uint32_t)((uint8_t *)(x))[0] << 24) ) )
  ------------------
  |  Branch (6633:9): [True: 0, False: 1]
  ------------------
 6634|      0|        if (tsk_verbose)
  ------------------
  |  Branch (6634:13): [True: 0, False: 0]
  ------------------
 6635|      0|            tsk_fprintf(stderr,
 6636|      0|                "hfs_open: Optional Extents File (and Badblocks File) is not present.\n");
 6637|      0|        hfs->has_extents_file = FALSE;
  ------------------
  |  |  453|      0|#define FALSE 0
  ------------------
 6638|      0|    }
 6639|      1|    else {
 6640|      1|        if (tsk_verbose)
  ------------------
  |  Branch (6640:13): [True: 0, False: 1]
  ------------------
 6641|      0|            tsk_fprintf(stderr,
 6642|      0|                "hfs_open: Extents File (and BadBlocks File) is present.\n");
 6643|      1|        hfs->has_extents_file = TRUE;
  ------------------
  |  |  454|      1|#define TRUE  ( !FALSE )
  |  |  ------------------
  |  |  |  |  453|      1|#define FALSE 0
  |  |  ------------------
  ------------------
 6644|      1|    }
 6645|       |
 6646|      1|    if (tsk_getu32(fs->endian, hfs->fs->attr_file.extents[0].blk_cnt) == 0) {
  ------------------
  |  |  119|      1|#define tsk_getu32(endian, x)	\
  |  |  120|      1|(uint32_t)( ((endian) == TSK_LIT_ENDIAN)  ?	\
  |  |  ------------------
  |  |  |  Branch (120:13): [True: 0, False: 1]
  |  |  ------------------
  |  |  121|      1|            ((((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|      1|                                          :	\
  |  |  126|      1|            ((((uint8_t *)(x))[3] <<  0) + \
  |  |  127|      1|             (((uint8_t *)(x))[2] <<  8) + \
  |  |  128|      1|             (((uint8_t *)(x))[1] << 16) + \
  |  |  129|      1|             ((uint32_t)((uint8_t *)(x))[0] << 24) ) )
  ------------------
  |  Branch (6646:9): [True: 1, False: 0]
  ------------------
 6647|      1|        if (tsk_verbose)
  ------------------
  |  Branch (6647:13): [True: 0, False: 1]
  ------------------
 6648|      0|            tsk_fprintf(stderr,
 6649|      0|                "hfs_open: Optional Attributes File is not present.\n");
 6650|      1|        hfs->has_attributes_file = FALSE;
  ------------------
  |  |  453|      1|#define FALSE 0
  ------------------
 6651|      1|    }
 6652|      0|    else {
 6653|      0|        if (tsk_verbose)
  ------------------
  |  Branch (6653:13): [True: 0, False: 0]
  ------------------
 6654|      0|            tsk_fprintf(stderr, "hfs_open: Attributes File is present.\n");
 6655|      0|        hfs->has_attributes_file = TRUE;
  ------------------
  |  |  454|      0|#define TRUE  ( !FALSE )
  |  |  ------------------
  |  |  |  |  453|      0|#define FALSE 0
  |  |  ------------------
  ------------------
 6656|      0|    }
 6657|       |
 6658|       |    /* Load the catalog file though */
 6659|      1|    if ((hfs->catalog_file =
  ------------------
  |  Branch (6659:9): [True: 1, False: 0]
  ------------------
 6660|      1|            tsk_fs_file_open_meta(fs, NULL,
 6661|      1|                HFS_CATALOG_FILE_ID)) == NULL) {
  ------------------
  |  |  126|      1|#define HFS_CATALOG_FILE_ID        4    // catalog file
  ------------------
 6662|      1|        hfs_close(fs);
 6663|      1|        return NULL;
 6664|      1|    }
 6665|       |
 6666|       |    /* cache the data attribute */
 6667|      0|    hfs->catalog_attr =
 6668|      0|        tsk_fs_attrlist_get(hfs->catalog_file->meta->attr,
 6669|      0|        TSK_FS_ATTR_TYPE_DEFAULT);
 6670|      0|    if (!hfs->catalog_attr) {
  ------------------
  |  Branch (6670:9): [True: 0, False: 0]
  ------------------
 6671|      0|        hfs_close(fs);
 6672|      0|        tsk_error_errstr2_concat
 6673|      0|            (" - Data Attribute not found in Catalog File");
 6674|      0|        return NULL;
 6675|      0|    }
 6676|       |
 6677|       |    // cache the catalog file header
 6678|      0|    cnt = tsk_fs_attr_read(hfs->catalog_attr, 14,
 6679|      0|        (char *) &(hfs->catalog_header),
 6680|      0|        sizeof(hfs_btree_header_record), 0);
 6681|      0|    if (cnt != sizeof(hfs_btree_header_record)) {
  ------------------
  |  Branch (6681:9): [True: 0, False: 0]
  ------------------
 6682|      0|        if (cnt >= 0) {
  ------------------
  |  Branch (6682:13): [True: 0, False: 0]
  ------------------
 6683|      0|            tsk_error_reset();
 6684|      0|            tsk_error_set_errno(TSK_ERR_FS_READ);
  ------------------
  |  |  349|      0|#define TSK_ERR_FS_READ		(TSK_ERR_FS | 4)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
 6685|      0|        }
 6686|      0|        hfs_close(fs);
 6687|      0|        tsk_error_set_errstr2("hfs_open: Error reading catalog header");
 6688|      0|        return NULL;
 6689|      0|    }
 6690|       |
 6691|      0|    if (tsk_getu16(fs->endian, hfs->fs->version) == HFS_VH_VER_HFSPLUS)
  ------------------
  |  |   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)) )
  ------------------
                  if (tsk_getu16(fs->endian, hfs->fs->version) == HFS_VH_VER_HFSPLUS)
  ------------------
  |  |  277|      0|#define HFS_VH_VER_HFSPLUS 0x0004       /* all HFS+ volumes are version 4 */
  ------------------
  |  Branch (6691:9): [True: 0, False: 0]
  ------------------
 6692|      0|        hfs->is_case_sensitive = 0;
 6693|      0|    else if (tsk_getu16(fs->endian, hfs->fs->version) == HFS_VH_VER_HFSX) {
  ------------------
  |  |   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(fs->endian, hfs->fs->version) == HFS_VH_VER_HFSX) {
  ------------------
  |  |  278|      0|#define HFS_VH_VER_HFSX    0x0005       /* HFSX volumes start with version 5 */
  ------------------
  |  Branch (6693:14): [True: 0, False: 0]
  ------------------
 6694|      0|        if (hfs->catalog_header.compType == HFS_BT_HEAD_COMP_SENS)
  ------------------
  |  |  425|      0|#define HFS_BT_HEAD_COMP_SENS    0xBC   // case sensitive
  ------------------
  |  Branch (6694:13): [True: 0, False: 0]
  ------------------
 6695|      0|            hfs->is_case_sensitive = 1;
 6696|      0|        else if (hfs->catalog_header.compType == HFS_BT_HEAD_COMP_INSENS)
  ------------------
  |  |  426|      0|#define HFS_BT_HEAD_COMP_INSENS    0xC7 // case insensitive
  ------------------
  |  Branch (6696:18): [True: 0, False: 0]
  ------------------
 6697|      0|            hfs->is_case_sensitive = 0;
 6698|      0|        else {
 6699|      0|            if (tsk_verbose)
  ------------------
  |  Branch (6699:17): [True: 0, False: 0]
  ------------------
 6700|      0|                tsk_fprintf(stderr,
 6701|      0|                    "hfs_open: invalid value (0x%02" PRIx8
 6702|      0|                    ") for key compare type; using case-insensitive\n",
 6703|      0|                    hfs->catalog_header.compType);
 6704|      0|            hfs->is_case_sensitive = 0;
 6705|      0|        }
 6706|      0|    }
 6707|      0|    else {
 6708|      0|        if (tsk_verbose)
  ------------------
  |  Branch (6708:13): [True: 0, False: 0]
  ------------------
 6709|      0|            tsk_fprintf(stderr,
 6710|      0|                "hfs_open: unknown HFS+/HFSX version (%" PRIu16 "\n",
 6711|      0|                tsk_getu16(fs->endian, hfs->fs->version));
  ------------------
  |  |   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)) )
  ------------------
 6712|      0|        hfs->is_case_sensitive = 0;
 6713|      0|    }
 6714|       |
 6715|       |    // update the numbers.
 6716|      0|    fs->last_inum = hfs_find_highest_inum(hfs);
 6717|      0|    fs->inum_count = fs->last_inum + 1;
 6718|       |
 6719|      0|    snprintf((char *) fs->fs_id, 17, "%08" PRIx32 "%08" PRIx32,
 6720|      0|        tsk_getu32(fs->endian, hfs->fs->finder_info[HFS_VH_FI_ID1]),
  ------------------
  |  |  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) ) )
  ------------------
 6721|      0|        tsk_getu32(fs->endian, hfs->fs->finder_info[HFS_VH_FI_ID2]));
  ------------------
  |  |  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) ) )
  ------------------
 6722|      0|    fs->fs_id_used = 16;
 6723|       |
 6724|       |    /* journal */
 6725|      0|    fs->jblk_walk = hfs_jblk_walk;
 6726|      0|    fs->jentry_walk = hfs_jentry_walk;
 6727|      0|    fs->jopen = hfs_jopen;
 6728|      0|    fs->name_cmp = hfs_name_cmp;
 6729|      0|    fs->journ_inum = 0;
 6730|       |
 6731|       |    /* Creation Times */
 6732|       |
 6733|       |    // First, the root
 6734|      0|    file = tsk_fs_file_open_meta(fs, NULL, 2);
 6735|      0|    if (file != NULL) {
  ------------------
  |  Branch (6735:9): [True: 0, False: 0]
  ------------------
 6736|      0|        hfs->root_crtime = file->meta->crtime;
 6737|      0|        hfs->has_root_crtime = TRUE;
  ------------------
  |  |  454|      0|#define TRUE  ( !FALSE )
  |  |  ------------------
  |  |  |  |  453|      0|#define FALSE 0
  |  |  ------------------
  ------------------
 6738|      0|        tsk_fs_file_close(file);
 6739|      0|    }
 6740|      0|    else {
 6741|      0|        hfs->has_root_crtime = FALSE;
  ------------------
  |  |  453|      0|#define FALSE 0
  ------------------
 6742|      0|    }
 6743|      0|    file = NULL;
 6744|       |
 6745|       |    // disable hard link traversal while finding the hard
 6746|       |    // link directories themselves (to prevent problems if
 6747|       |    // there are hard links in the root directory)
 6748|      0|    hfs->meta_inum = 0;
 6749|      0|    hfs->meta_dir_inum = 0;
 6750|       |
 6751|       |    // Now the (file) metadata directory
 6752|       |
 6753|       |    // The metadata directory is a sub-directory of the root.  Its name begins with four nulls, followed
 6754|       |    // by "HFS+ Private Data".  The file system parsing code replaces nulls in filenames with UTF8_NULL_REPLACE.
 6755|       |    // In the released version of TSK, this replacement is the character '^'.
 6756|       |    // NOTE: There is a standard Unicode replacement which is 0xfffd in UTF16 and 0xEF 0xBF 0xBD in UTF8.
 6757|       |    // Systems that require the standard definition can redefine UTF8_NULL_REPLACE and UTF16_NULL_REPLACE
 6758|       |    // in tsk_hfs.h
 6759|      0|    hfs->has_meta_crtime = FALSE;
  ------------------
  |  |  453|      0|#define FALSE 0
  ------------------
 6760|      0|    result =
 6761|      0|        tsk_fs_path2inum(fs,
 6762|      0|        "/" UTF8_NULL_REPLACE UTF8_NULL_REPLACE UTF8_NULL_REPLACE
 6763|      0|        UTF8_NULL_REPLACE "HFS+ Private Data", &inum, NULL);
 6764|      0|    if (result == 0) {
  ------------------
  |  Branch (6764:9): [True: 0, False: 0]
  ------------------
 6765|      0|        TSK_FS_FILE *file_tmp = tsk_fs_file_open_meta(fs, NULL, inum);
 6766|      0|        if (file_tmp != NULL) {
  ------------------
  |  Branch (6766:13): [True: 0, False: 0]
  ------------------
 6767|      0|            hfs->meta_crtime = file_tmp->meta->crtime;
 6768|      0|            hfs->has_meta_crtime = TRUE;
  ------------------
  |  |  454|      0|#define TRUE  ( !FALSE )
  |  |  ------------------
  |  |  |  |  453|      0|#define FALSE 0
  |  |  ------------------
  ------------------
 6769|      0|            hfs->meta_inum = inum;
 6770|      0|            tsk_fs_file_close(file_tmp);
 6771|      0|        }
 6772|      0|    }
 6773|       |
 6774|       |    // Now, the directory metadata directory
 6775|       |
 6776|       |    // The "directory" metadata directory, where hardlinked directories actually live, is a subdirectory
 6777|       |    // of the root.  The beginning of the name of this directory is ".HFS+ Private Directory Data" which
 6778|       |    // is followed by a carriage return (ASCII 13).
 6779|      0|    hfs->has_meta_dir_crtime = FALSE;
  ------------------
  |  |  453|      0|#define FALSE 0
  ------------------
 6780|      0|    result =
 6781|      0|        tsk_fs_path2inum(fs, "/.HFS+ Private Directory Data\r", &inum,
 6782|      0|        NULL);
 6783|      0|    if (result == 0) {
  ------------------
  |  Branch (6783:9): [True: 0, False: 0]
  ------------------
 6784|      0|        TSK_FS_FILE *file_tmp = tsk_fs_file_open_meta(fs, NULL, inum);
 6785|      0|        if (file_tmp != NULL) {
  ------------------
  |  Branch (6785:13): [True: 0, False: 0]
  ------------------
 6786|      0|            hfs->metadir_crtime = file_tmp->meta->crtime;
 6787|      0|            hfs->has_meta_dir_crtime = TRUE;
  ------------------
  |  |  454|      0|#define TRUE  ( !FALSE )
  |  |  ------------------
  |  |  |  |  453|      0|#define FALSE 0
  |  |  ------------------
  ------------------
 6788|      0|            hfs->meta_dir_inum = inum;
 6789|      0|            tsk_fs_file_close(file_tmp);
 6790|      0|        }
 6791|      0|    }
 6792|       |
 6793|      0|    if (hfs->has_root_crtime && hfs->has_meta_crtime
  ------------------
  |  Branch (6793:9): [True: 0, False: 0]
  |  Branch (6793:33): [True: 0, False: 0]
  ------------------
 6794|      0|        && hfs->has_meta_dir_crtime) {
  ------------------
  |  Branch (6794:12): [True: 0, False: 0]
  ------------------
 6795|      0|        if (tsk_verbose)
  ------------------
  |  Branch (6795:13): [True: 0, False: 0]
  ------------------
 6796|      0|            tsk_fprintf(stderr,
 6797|      0|                "hfs_open: Creation times for key folders have been read and cached.\n");
 6798|      0|    }
 6799|      0|    if (!hfs->has_root_crtime) {
  ------------------
  |  Branch (6799:9): [True: 0, False: 0]
  ------------------
 6800|      0|        if (tsk_verbose)
  ------------------
  |  Branch (6800:13): [True: 0, False: 0]
  ------------------
 6801|      0|            tsk_fprintf(stderr,
 6802|      0|                "hfs_open: Warning: Could not open the root directory.  "
 6803|      0|                "Hard link detection and some other functions will be impaired\n");
 6804|      0|    }
 6805|      0|    else if (tsk_verbose) {
  ------------------
  |  Branch (6805:14): [True: 0, False: 0]
  ------------------
 6806|      0|        tsk_fprintf(stderr,
 6807|      0|            "hfs_open: The root directory is accessible.\n");
 6808|      0|    }
 6809|       |
 6810|      0|    if (tsk_verbose) {
  ------------------
  |  Branch (6810:9): [True: 0, False: 0]
  ------------------
 6811|      0|        if (hfs->has_meta_crtime)
  ------------------
  |  Branch (6811:13): [True: 0, False: 0]
  ------------------
 6812|      0|            tsk_fprintf(stderr,
 6813|      0|                "hfs_open: \"/^^^^HFS+ Private Data\" metadata folder is accessible.\n");
 6814|      0|        else
 6815|      0|            tsk_fprintf(stderr,
 6816|      0|                "hfs_open: Optional \"^^^^HFS+ Private Data\" metadata folder is not accessible, or does not exist.\n");
 6817|      0|        if (hfs->has_meta_dir_crtime)
  ------------------
  |  Branch (6817:13): [True: 0, False: 0]
  ------------------
 6818|      0|            tsk_fprintf(stderr,
 6819|      0|                "hfs_open: \"/HFS+ Private Directory Data^\" metadata folder is accessible.\n");
 6820|      0|        else
 6821|      0|            tsk_fprintf(stderr,
 6822|      0|                "hfs_open: Optional \"/HFS+ Private Directory Data^\" metadata folder is not accessible, or does not exist.\n");
 6823|      0|    }
 6824|       |
 6825|       |    // These caches will be set, if they are needed.
 6826|      0|    hfs->meta_dir = NULL;
 6827|      0|    hfs->dir_meta_dir = NULL;
 6828|       |
 6829|      0|    return fs;
 6830|      0|}
error_returned:
 6890|      1|{
 6891|      1|    va_list args;
 6892|      1|    va_start(args, errstr);
 6893|       |
 6894|      1|    {
 6895|      1|        TSK_ERROR_INFO *errInfo = tsk_error_get_info();
 6896|      1|        char *loc_errstr2 = errInfo->errstr2;
 6897|       |
 6898|      1|        if (errInfo->t_errno == 0)
  ------------------
  |  Branch (6898:13): [True: 0, False: 1]
  ------------------
 6899|      0|            errInfo->t_errno = TSK_ERR_AUX_GENERIC;
  ------------------
  |  |  308|      0|#define TSK_ERR_AUX_GENERIC (TSK_ERR_AUX | 2)
  |  |  ------------------
  |  |  |  |  298|      0|#define TSK_ERR_AUX	0x01000000
  |  |  ------------------
  ------------------
 6900|      1|        if (errstr != NULL) {
  ------------------
  |  Branch (6900:13): [True: 1, False: 0]
  ------------------
 6901|      1|            size_t sl = strlen(loc_errstr2);
 6902|      1|            vsnprintf(loc_errstr2 + sl, TSK_ERROR_STRING_MAX_LENGTH - sl,
  ------------------
  |  |   67|      1|#define TSK_ERROR_STRING_MAX_LENGTH 1024
  ------------------
 6903|      1|                errstr, args);
 6904|      1|        }
 6905|      1|    }
 6906|      1|    va_end(args);
 6907|      1|}
hfs.c:hfs_inode_lookup:
 2468|      2|{
 2469|      2|    HFS_INFO *hfs = (HFS_INFO *) fs;
 2470|      2|    HFS_ENTRY entry;
 2471|       |
 2472|      2|    if (a_fs_file == NULL) {
  ------------------
  |  Branch (2472:9): [True: 0, False: 2]
  ------------------
 2473|      0|        tsk_error_set_errno(TSK_ERR_FS_ARG);
  ------------------
  |  |  351|      0|#define TSK_ERR_FS_ARG		(TSK_ERR_FS | 6)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
 2474|      0|        tsk_error_set_errstr("hfs_inode_lookup: fs_file is NULL");
 2475|      0|        return 1;
 2476|      0|    }
 2477|       |
 2478|      2|    if (a_fs_file->meta == NULL) {
  ------------------
  |  Branch (2478:9): [True: 2, False: 0]
  ------------------
 2479|      2|        a_fs_file->meta = tsk_fs_meta_alloc(HFS_FILE_CONTENT_LEN);
  ------------------
  |  |   99|      2|#define HFS_FILE_CONTENT_LEN 160        /* size of two hfs_fork data structures */
  ------------------
 2480|      2|    }
 2481|       |
 2482|      2|    if (a_fs_file->meta == NULL) {
  ------------------
  |  Branch (2482:9): [True: 0, False: 2]
  ------------------
 2483|      0|        return 1;
 2484|      0|    }
 2485|      2|    else {
 2486|      2|        tsk_fs_meta_reset(a_fs_file->meta);
 2487|      2|    }
 2488|       |
 2489|      2|    if (tsk_verbose)
  ------------------
  |  Branch (2489:9): [True: 0, False: 2]
  ------------------
 2490|      0|        tsk_fprintf(stderr, "hfs_inode_lookup: looking up %" PRIuINUM "\n",
 2491|      0|            inum);
 2492|       |
 2493|       |    // @@@ Will need to add orphan stuff here too
 2494|       |
 2495|       |    /* First see if this is a special entry
 2496|       |     * the special ones have their metadata stored in the volume header */
 2497|      2|    if (inum == HFS_EXTENTS_FILE_ID) {
  ------------------
  |  |  124|      2|#define HFS_EXTENTS_FILE_ID        3    // extents overflow file
  ------------------
  |  Branch (2497:9): [True: 1, False: 1]
  ------------------
 2498|      1|        if (!hfs->has_extents_file) {
  ------------------
  |  Branch (2498:13): [True: 0, False: 1]
  ------------------
 2499|      0|            error_detected(TSK_ERR_FS_INODE_NUM,
  ------------------
  |  |  353|      0|#define TSK_ERR_FS_INODE_NUM	(TSK_ERR_FS | 8)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
 2500|      0|                "Extents File not present");
 2501|      0|            return 1;
 2502|      0|        }
 2503|       |
 2504|      1|        return hfs_make_extents(hfs, a_fs_file);
 2505|      1|    }
 2506|      1|    else if (inum == HFS_CATALOG_FILE_ID) {
  ------------------
  |  |  126|      1|#define HFS_CATALOG_FILE_ID        4    // catalog file
  ------------------
  |  Branch (2506:14): [True: 1, False: 0]
  ------------------
 2507|      1|        return hfs_make_catalog(hfs, a_fs_file);
 2508|      1|    }
 2509|      0|    else if (inum == HFS_BAD_BLOCK_FILE_ID) {
  ------------------
  |  |  128|      0|#define HFS_BAD_BLOCK_FILE_ID      5
  ------------------
  |  Branch (2509:14): [True: 0, False: 0]
  ------------------
 2510|       |        // Note: the Extents file and the BadBlocks file are really the same.
 2511|      0|        if (!hfs->has_extents_file) {
  ------------------
  |  Branch (2511:13): [True: 0, False: 0]
  ------------------
 2512|      0|            error_detected(TSK_ERR_FS_INODE_NUM,
  ------------------
  |  |  353|      0|#define TSK_ERR_FS_INODE_NUM	(TSK_ERR_FS | 8)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
 2513|      0|                "BadBlocks File not present");
 2514|      0|            return 1;
 2515|      0|        }
 2516|      0|        return hfs_make_badblockfile(hfs, a_fs_file);
 2517|      0|    }
 2518|      0|    else if (inum == HFS_ALLOCATION_FILE_ID) {
  ------------------
  |  |  130|      0|#define HFS_ALLOCATION_FILE_ID     6    // allocation file (HFS+)
  ------------------
  |  Branch (2518:14): [True: 0, False: 0]
  ------------------
 2519|      0|        return hfs_make_blockmap(hfs, a_fs_file);
 2520|      0|    }
 2521|      0|    else if (inum == HFS_STARTUP_FILE_ID) {
  ------------------
  |  |  132|      0|#define HFS_STARTUP_FILE_ID        7    // startup file (HFS+)
  ------------------
  |  Branch (2521:14): [True: 0, False: 0]
  ------------------
 2522|      0|        if (!hfs->has_startup_file) {
  ------------------
  |  Branch (2522:13): [True: 0, False: 0]
  ------------------
 2523|      0|            error_detected(TSK_ERR_FS_INODE_NUM,
  ------------------
  |  |  353|      0|#define TSK_ERR_FS_INODE_NUM	(TSK_ERR_FS | 8)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
 2524|      0|                "Startup File not present");
 2525|      0|            return 1;
 2526|      0|        }
 2527|      0|        return hfs_make_startfile(hfs, a_fs_file);
 2528|      0|    }
 2529|      0|    else if (inum == HFS_ATTRIBUTES_FILE_ID) {
  ------------------
  |  |  134|      0|#define HFS_ATTRIBUTES_FILE_ID     8    // Attributes file (HFS+)
  ------------------
  |  Branch (2529:14): [True: 0, False: 0]
  ------------------
 2530|      0|        if (!hfs->has_attributes_file) {
  ------------------
  |  Branch (2530:13): [True: 0, False: 0]
  ------------------
 2531|      0|            error_detected(TSK_ERR_FS_INODE_NUM,
  ------------------
  |  |  353|      0|#define TSK_ERR_FS_INODE_NUM	(TSK_ERR_FS | 8)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
 2532|      0|                "Attributes File not present");
 2533|      0|            return 1;
 2534|      0|        }
 2535|      0|        return hfs_make_attrfile(hfs, a_fs_file);
 2536|      0|    }
 2537|       |
 2538|       |    /* Lookup inode and store it in the HFS structure */
 2539|      0|    if (hfs_cat_file_lookup(hfs, inum, &entry, TRUE)) {
  ------------------
  |  |  454|      0|#define TRUE  ( !FALSE )
  |  |  ------------------
  |  |  |  |  453|      0|#define FALSE 0
  |  |  ------------------
  ------------------
  |  Branch (2539:9): [True: 0, False: 0]
  ------------------
 2540|      0|        return 1;
 2541|      0|    }
 2542|       |
 2543|       |    /* Copy the structure in hfs to generic fs_inode */
 2544|      0|    if (hfs_dinode_copy(hfs, &entry, a_fs_file)) {
  ------------------
  |  Branch (2544:9): [True: 0, False: 0]
  ------------------
 2545|      0|        return 1;
 2546|      0|    }
 2547|       |
 2548|       |    /* If this is potentially a compressed file, its
 2549|       |     * actual size is unknown until we examine the
 2550|       |     * extended attributes */
 2551|      0|    if ((a_fs_file->meta->size == 0) &&
  ------------------
  |  Branch (2551:9): [True: 0, False: 0]
  ------------------
 2552|      0|        (a_fs_file->meta->type == TSK_FS_META_TYPE_REG) &&
  ------------------
  |  Branch (2552:9): [True: 0, False: 0]
  ------------------
 2553|      0|        (a_fs_file->meta->attr_state != TSK_FS_META_ATTR_ERROR) &&
  ------------------
  |  Branch (2553:9): [True: 0, False: 0]
  ------------------
 2554|      0|        ((a_fs_file->meta->attr_state != TSK_FS_META_ATTR_STUDIED) ||
  ------------------
  |  Branch (2554:10): [True: 0, False: 0]
  ------------------
 2555|      0|            (a_fs_file->meta->attr == NULL))) {
  ------------------
  |  Branch (2555:13): [True: 0, False: 0]
  ------------------
 2556|      0|        hfs_load_attrs(a_fs_file);
 2557|      0|    }
 2558|       |
 2559|      0|    return 0;
 2560|      0|}
hfs.c:hfs_make_extents:
 1900|      1|{
 1901|      1|    TSK_FS_INFO *fs = (TSK_FS_INFO *) hfs;
 1902|      1|    TSK_FS_ATTR *fs_attr;
 1903|      1|    TSK_FS_ATTR_RUN *attr_run;
 1904|       |
 1905|      1|    if (tsk_verbose)
  ------------------
  |  Branch (1905:9): [True: 0, False: 1]
  ------------------
 1906|      0|        tsk_fprintf(stderr,
 1907|      0|            "hfs_make_extents: Making virtual extents file\n");
 1908|       |
 1909|      1|    if (hfs_make_specialbase(fs_file)) {
  ------------------
  |  Branch (1909:9): [True: 0, False: 1]
  ------------------
 1910|      0|        error_returned(" - hfs_make_extents");
 1911|      0|        return 1;
 1912|      0|    }
 1913|       |
 1914|      1|    fs_file->meta->addr = HFS_EXTENTS_FILE_ID;
  ------------------
  |  |  124|      1|#define HFS_EXTENTS_FILE_ID        3    // extents overflow file
  ------------------
 1915|      1|    strncpy(fs_file->meta->name2->name, HFS_EXTENTSNAME,
  ------------------
  |  |  165|      1|#define HFS_EXTENTSNAME "$ExtentsFile"
  ------------------
 1916|      1|        TSK_FS_META_NAME_LIST_NSIZE);
  ------------------
  |  |  348|      1|#define TSK_FS_META_NAME_LIST_NSIZE    512
  ------------------
 1917|       |
 1918|      1|    fs_file->meta->size =
 1919|      1|        tsk_getu64(fs->endian, hfs->fs->ext_file.logic_sz);
  ------------------
  |  |  171|      1|#define tsk_getu64(endian, x)   \
  |  |  172|      1|(uint64_t)( ((endian) == TSK_LIT_ENDIAN)  ?	\
  |  |  ------------------
  |  |  |  Branch (172:13): [True: 0, False: 1]
  |  |  ------------------
  |  |  173|      1|            ((uint64_t) \
  |  |  174|      0|             ((uint64_t)((uint8_t *)(x))[0] << 0)  + \
  |  |  175|      0|             ((uint64_t)((uint8_t *)(x))[1] << 8) + \
  |  |  176|      0|             ((uint64_t)((uint8_t *)(x))[2] << 16) + \
  |  |  177|      0|             ((uint64_t)((uint8_t *)(x))[3] << 24) + \
  |  |  178|      0|             ((uint64_t)((uint8_t *)(x))[4] << 32) + \
  |  |  179|      0|             ((uint64_t)((uint8_t *)(x))[5] << 40) + \
  |  |  180|      0|             ((uint64_t)((uint8_t *)(x))[6] << 48) + \
  |  |  181|      0|             ((uint64_t)((uint8_t *)(x))[7] << 56)) \
  |  |  182|      1|                                          : \
  |  |  183|      1|            ((uint64_t) \
  |  |  184|      1|             ((uint64_t)((uint8_t *)(x))[7] <<  0) + \
  |  |  185|      1|             ((uint64_t)((uint8_t *)(x))[6] <<  8) + \
  |  |  186|      1|             ((uint64_t)((uint8_t *)(x))[5] << 16) + \
  |  |  187|      1|             ((uint64_t)((uint8_t *)(x))[4] << 24) + \
  |  |  188|      1|             ((uint64_t)((uint8_t *)(x))[3] << 32) + \
  |  |  189|      1|             ((uint64_t)((uint8_t *)(x))[2] << 40) + \
  |  |  190|      1|             ((uint64_t)((uint8_t *)(x))[1] << 48) + \
  |  |  191|      1|             ((uint64_t)((uint8_t *)(x))[0] << 56)) )
  ------------------
 1920|       |
 1921|       |
 1922|      1|    if (((attr_run =
  ------------------
  |  Branch (1922:9): [True: 0, False: 1]
  ------------------
 1923|      1|                hfs_extents_to_attr(fs, hfs->fs->ext_file.extents,
 1924|      1|                    0)) == NULL) && (tsk_error_get_errno() != 0)) {
  ------------------
  |  Branch (1924:37): [True: 0, False: 0]
  ------------------
 1925|      0|        error_returned(" - hfs_make_extents");
 1926|      0|        return 1;
 1927|      0|    }
 1928|       |
 1929|      1|    if ((fs_attr =
  ------------------
  |  Branch (1929:9): [True: 0, False: 1]
  ------------------
 1930|      1|            tsk_fs_attrlist_getnew(fs_file->meta->attr,
 1931|      1|                TSK_FS_ATTR_NONRES)) == NULL) {
 1932|      0|        error_returned(" - hfs_make_extents");
 1933|      0|        tsk_fs_attr_run_free(attr_run);
 1934|      0|        return 1;
 1935|      0|    }
 1936|       |
 1937|       |    // initialize the data run
 1938|      1|    if (tsk_fs_attr_set_run(fs_file, fs_attr, attr_run, NULL,
  ------------------
  |  Branch (1938:9): [True: 0, False: 1]
  ------------------
 1939|      1|            TSK_FS_ATTR_TYPE_DEFAULT, HFS_FS_ATTR_ID_DATA,
  ------------------
  |  |  118|      1|#define HFS_FS_ATTR_ID_DATA 0
  ------------------
 1940|      1|            tsk_getu64(fs->endian, hfs->fs->ext_file.logic_sz),
  ------------------
  |  |  171|      1|#define tsk_getu64(endian, x)   \
  |  |  172|      1|(uint64_t)( ((endian) == TSK_LIT_ENDIAN)  ?	\
  |  |  ------------------
  |  |  |  Branch (172:13): [True: 0, False: 1]
  |  |  ------------------
  |  |  173|      1|            ((uint64_t) \
  |  |  174|      0|             ((uint64_t)((uint8_t *)(x))[0] << 0)  + \
  |  |  175|      0|             ((uint64_t)((uint8_t *)(x))[1] << 8) + \
  |  |  176|      0|             ((uint64_t)((uint8_t *)(x))[2] << 16) + \
  |  |  177|      0|             ((uint64_t)((uint8_t *)(x))[3] << 24) + \
  |  |  178|      0|             ((uint64_t)((uint8_t *)(x))[4] << 32) + \
  |  |  179|      0|             ((uint64_t)((uint8_t *)(x))[5] << 40) + \
  |  |  180|      0|             ((uint64_t)((uint8_t *)(x))[6] << 48) + \
  |  |  181|      0|             ((uint64_t)((uint8_t *)(x))[7] << 56)) \
  |  |  182|      1|                                          : \
  |  |  183|      1|            ((uint64_t) \
  |  |  184|      1|             ((uint64_t)((uint8_t *)(x))[7] <<  0) + \
  |  |  185|      1|             ((uint64_t)((uint8_t *)(x))[6] <<  8) + \
  |  |  186|      1|             ((uint64_t)((uint8_t *)(x))[5] << 16) + \
  |  |  187|      1|             ((uint64_t)((uint8_t *)(x))[4] << 24) + \
  |  |  188|      1|             ((uint64_t)((uint8_t *)(x))[3] << 32) + \
  |  |  189|      1|             ((uint64_t)((uint8_t *)(x))[2] << 40) + \
  |  |  190|      1|             ((uint64_t)((uint8_t *)(x))[1] << 48) + \
  |  |  191|      1|             ((uint64_t)((uint8_t *)(x))[0] << 56)) )
  ------------------
 1941|      1|            tsk_getu64(fs->endian, hfs->fs->ext_file.logic_sz),
  ------------------
  |  |  171|      1|#define tsk_getu64(endian, x)   \
  |  |  172|      1|(uint64_t)( ((endian) == TSK_LIT_ENDIAN)  ?	\
  |  |  ------------------
  |  |  |  Branch (172:13): [True: 0, False: 1]
  |  |  ------------------
  |  |  173|      1|            ((uint64_t) \
  |  |  174|      0|             ((uint64_t)((uint8_t *)(x))[0] << 0)  + \
  |  |  175|      0|             ((uint64_t)((uint8_t *)(x))[1] << 8) + \
  |  |  176|      0|             ((uint64_t)((uint8_t *)(x))[2] << 16) + \
  |  |  177|      0|             ((uint64_t)((uint8_t *)(x))[3] << 24) + \
  |  |  178|      0|             ((uint64_t)((uint8_t *)(x))[4] << 32) + \
  |  |  179|      0|             ((uint64_t)((uint8_t *)(x))[5] << 40) + \
  |  |  180|      0|             ((uint64_t)((uint8_t *)(x))[6] << 48) + \
  |  |  181|      0|             ((uint64_t)((uint8_t *)(x))[7] << 56)) \
  |  |  182|      1|                                          : \
  |  |  183|      1|            ((uint64_t) \
  |  |  184|      1|             ((uint64_t)((uint8_t *)(x))[7] <<  0) + \
  |  |  185|      1|             ((uint64_t)((uint8_t *)(x))[6] <<  8) + \
  |  |  186|      1|             ((uint64_t)((uint8_t *)(x))[5] << 16) + \
  |  |  187|      1|             ((uint64_t)((uint8_t *)(x))[4] << 24) + \
  |  |  188|      1|             ((uint64_t)((uint8_t *)(x))[3] << 32) + \
  |  |  189|      1|             ((uint64_t)((uint8_t *)(x))[2] << 40) + \
  |  |  190|      1|             ((uint64_t)((uint8_t *)(x))[1] << 48) + \
  |  |  191|      1|             ((uint64_t)((uint8_t *)(x))[0] << 56)) )
  ------------------
 1942|      1|            tsk_getu64(fs->endian, hfs->fs->ext_file.logic_sz), 0, 0)) {
  ------------------
  |  |  171|      1|#define tsk_getu64(endian, x)   \
  |  |  172|      1|(uint64_t)( ((endian) == TSK_LIT_ENDIAN)  ?	\
  |  |  ------------------
  |  |  |  Branch (172:13): [True: 0, False: 1]
  |  |  ------------------
  |  |  173|      1|            ((uint64_t) \
  |  |  174|      0|             ((uint64_t)((uint8_t *)(x))[0] << 0)  + \
  |  |  175|      0|             ((uint64_t)((uint8_t *)(x))[1] << 8) + \
  |  |  176|      0|             ((uint64_t)((uint8_t *)(x))[2] << 16) + \
  |  |  177|      0|             ((uint64_t)((uint8_t *)(x))[3] << 24) + \
  |  |  178|      0|             ((uint64_t)((uint8_t *)(x))[4] << 32) + \
  |  |  179|      0|             ((uint64_t)((uint8_t *)(x))[5] << 40) + \
  |  |  180|      0|             ((uint64_t)((uint8_t *)(x))[6] << 48) + \
  |  |  181|      0|             ((uint64_t)((uint8_t *)(x))[7] << 56)) \
  |  |  182|      1|                                          : \
  |  |  183|      1|            ((uint64_t) \
  |  |  184|      1|             ((uint64_t)((uint8_t *)(x))[7] <<  0) + \
  |  |  185|      1|             ((uint64_t)((uint8_t *)(x))[6] <<  8) + \
  |  |  186|      1|             ((uint64_t)((uint8_t *)(x))[5] << 16) + \
  |  |  187|      1|             ((uint64_t)((uint8_t *)(x))[4] << 24) + \
  |  |  188|      1|             ((uint64_t)((uint8_t *)(x))[3] << 32) + \
  |  |  189|      1|             ((uint64_t)((uint8_t *)(x))[2] << 40) + \
  |  |  190|      1|             ((uint64_t)((uint8_t *)(x))[1] << 48) + \
  |  |  191|      1|             ((uint64_t)((uint8_t *)(x))[0] << 56)) )
  ------------------
 1943|      0|        error_returned(" - hfs_make_extents");
 1944|      0|        tsk_fs_attr_run_free(attr_run);
 1945|      0|        return 1;
 1946|      0|    }
 1947|       |
 1948|       |    //hfs_load_extended_attrs(fs_file);
 1949|       |
 1950|       |    // Extents doesn't have an entry in itself
 1951|       |
 1952|      1|    fs_file->meta->attr_state = TSK_FS_META_ATTR_STUDIED;
 1953|      1|    return 0;
 1954|      1|}
hfs.c:hfs_make_specialbase:
 1777|      2|{
 1778|      2|    fs_file->meta->type = TSK_FS_META_TYPE_REG;
 1779|      2|    fs_file->meta->mode = 0;
 1780|      2|    fs_file->meta->nlink = 1;
 1781|      2|    fs_file->meta->flags =
 1782|      2|        (TSK_FS_META_FLAG_USED | TSK_FS_META_FLAG_ALLOC);
 1783|      2|    fs_file->meta->uid = fs_file->meta->gid = 0;
 1784|      2|    fs_file->meta->mtime = fs_file->meta->atime = fs_file->meta->ctime =
 1785|      2|        fs_file->meta->crtime = 0;
 1786|      2|    fs_file->meta->mtime_nano = fs_file->meta->atime_nano =
 1787|      2|        fs_file->meta->ctime_nano = fs_file->meta->crtime_nano = 0;
 1788|       |
 1789|      2|    if (fs_file->meta->name2 == NULL) {
  ------------------
  |  Branch (1789:9): [True: 2, False: 0]
  ------------------
 1790|      2|        if ((fs_file->meta->name2 = (TSK_FS_META_NAME_LIST *)
  ------------------
  |  Branch (1790:13): [True: 0, False: 2]
  ------------------
 1791|      2|                tsk_malloc(sizeof(TSK_FS_META_NAME_LIST))) == NULL) {
 1792|      0|            error_returned
 1793|      0|                (" - hfs_make_specialbase, couldn't malloc space for a name list");
 1794|      0|            return 1;
 1795|      0|        }
 1796|      2|        fs_file->meta->name2->next = NULL;
 1797|      2|    }
 1798|       |
 1799|      2|    if (fs_file->meta->attr != NULL) {
  ------------------
  |  Branch (1799:9): [True: 0, False: 2]
  ------------------
 1800|      0|        tsk_fs_attrlist_markunused(fs_file->meta->attr);
 1801|      0|    }
 1802|      2|    else {
 1803|      2|        fs_file->meta->attr = tsk_fs_attrlist_alloc();
 1804|      2|    }
 1805|      2|    return 0;
 1806|      2|}
hfs.c:hfs_extents_to_attr:
  244|      2|{
  245|      2|    TSK_FS_ATTR_RUN *head_run = NULL;
  246|      2|    TSK_FS_ATTR_RUN *prev_run = NULL;
  247|      2|    int i;
  248|      2|    TSK_OFF_T cur_off = a_start_off;
  249|       |
  250|       |    // since tsk_errno is checked as a return value, make sure it is clean.
  251|      2|    tsk_error_reset();
  252|       |
  253|      2|    if (tsk_verbose)
  ------------------
  |  Branch (253:9): [True: 0, False: 2]
  ------------------
  254|      0|        tsk_fprintf(stderr,
  255|      0|            "hfs_extents_to_attr: Converting extents from offset %" PRIdOFF
  256|      0|            " to runlist\n", a_start_off);
  257|       |
  258|      3|    for (i = 0; i < 8; ++i) {
  ------------------
  |  Branch (258:17): [True: 3, False: 0]
  ------------------
  259|      3|        TSK_FS_ATTR_RUN *cur_run;
  260|       |
  261|      3|        uint32_t addr = tsk_getu32(a_fs->endian, a_extents[i].start_blk);
  ------------------
  |  |  119|      3|#define tsk_getu32(endian, x)	\
  |  |  120|      3|(uint32_t)( ((endian) == TSK_LIT_ENDIAN)  ?	\
  |  |  ------------------
  |  |  |  Branch (120:13): [True: 0, False: 3]
  |  |  ------------------
  |  |  121|      3|            ((((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|      3|                                          :	\
  |  |  126|      3|            ((((uint8_t *)(x))[3] <<  0) + \
  |  |  127|      3|             (((uint8_t *)(x))[2] <<  8) + \
  |  |  128|      3|             (((uint8_t *)(x))[1] << 16) + \
  |  |  129|      3|             ((uint32_t)((uint8_t *)(x))[0] << 24) ) )
  ------------------
  262|      3|        uint32_t len = tsk_getu32(a_fs->endian, a_extents[i].blk_cnt);
  ------------------
  |  |  119|      3|#define tsk_getu32(endian, x)	\
  |  |  120|      3|(uint32_t)( ((endian) == TSK_LIT_ENDIAN)  ?	\
  |  |  ------------------
  |  |  |  Branch (120:13): [True: 0, False: 3]
  |  |  ------------------
  |  |  121|      3|            ((((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|      3|                                          :	\
  |  |  126|      3|            ((((uint8_t *)(x))[3] <<  0) + \
  |  |  127|      3|             (((uint8_t *)(x))[2] <<  8) + \
  |  |  128|      3|             (((uint8_t *)(x))[1] << 16) + \
  |  |  129|      3|             ((uint32_t)((uint8_t *)(x))[0] << 24) ) )
  ------------------
  263|       |
  264|      3|        if (tsk_verbose)
  ------------------
  |  Branch (264:13): [True: 0, False: 3]
  ------------------
  265|      0|            tsk_fprintf(stderr,
  266|      0|                "hfs_extents_to_attr: run %i at addr %" PRIu32
  267|      0|                " with len %" PRIu32 "\n", i, addr, len);
  268|       |
  269|      3|        if ((addr == 0) && (len == 0)) {
  ------------------
  |  Branch (269:13): [True: 2, False: 1]
  |  Branch (269:28): [True: 2, False: 0]
  ------------------
  270|      2|            break;
  271|      2|        }
  272|       |
  273|       |        // make a non-resident run
  274|      1|        if ((cur_run = tsk_fs_attr_run_alloc()) == NULL) {
  ------------------
  |  Branch (274:13): [True: 0, False: 1]
  ------------------
  275|      0|            error_returned(" - hfs_extents_to_attr");
  276|      0|            return NULL;
  277|      0|        }
  278|       |
  279|      1|        cur_run->addr = addr;
  280|      1|        cur_run->len = len;
  281|      1|        cur_run->offset = cur_off;
  282|       |
  283|      1|        if (head_run == NULL)
  ------------------
  |  Branch (283:13): [True: 1, False: 0]
  ------------------
  284|      1|            head_run = cur_run;
  285|      1|        if (prev_run != NULL)
  ------------------
  |  Branch (285:13): [True: 0, False: 1]
  ------------------
  286|      0|            prev_run->next = cur_run;
  287|      1|        cur_off += cur_run->len;
  288|      1|        prev_run = cur_run;
  289|      1|    }
  290|       |
  291|      2|    return head_run;
  292|      2|}
hfs.c:hfs_make_catalog:
 1818|      1|{
 1819|      1|    TSK_FS_INFO *fs = (TSK_FS_INFO *) hfs;
 1820|      1|    TSK_FS_ATTR *fs_attr;
 1821|      1|    TSK_FS_ATTR_RUN *attr_run;
 1822|      1|    unsigned char dummy1, dummy2;
 1823|      1|    uint64_t dummy3;
 1824|      1|    uint8_t result;
 1825|       |
 1826|      1|    if (tsk_verbose)
  ------------------
  |  Branch (1826:9): [True: 0, False: 1]
  ------------------
 1827|      0|        tsk_fprintf(stderr,
 1828|      0|            "hfs_make_catalog: Making virtual catalog file\n");
 1829|       |
 1830|      1|    if (hfs_make_specialbase(fs_file)) {
  ------------------
  |  Branch (1830:9): [True: 0, False: 1]
  ------------------
 1831|      0|        error_returned(" - hfs_make_catalog");
 1832|      0|        return 1;
 1833|      0|    }
 1834|       |
 1835|      1|    fs_file->meta->addr = HFS_CATALOG_FILE_ID;
  ------------------
  |  |  126|      1|#define HFS_CATALOG_FILE_ID        4    // catalog file
  ------------------
 1836|      1|    strncpy(fs_file->meta->name2->name, HFS_CATALOGNAME,
  ------------------
  |  |  164|      1|#define HFS_CATALOGNAME "$CatalogFile"
  ------------------
 1837|      1|        TSK_FS_META_NAME_LIST_NSIZE);
  ------------------
  |  |  348|      1|#define TSK_FS_META_NAME_LIST_NSIZE    512
  ------------------
 1838|       |
 1839|      1|    fs_file->meta->size =
 1840|      1|        tsk_getu64(fs->endian, hfs->fs->cat_file.logic_sz);
  ------------------
  |  |  171|      1|#define tsk_getu64(endian, x)   \
  |  |  172|      1|(uint64_t)( ((endian) == TSK_LIT_ENDIAN)  ?	\
  |  |  ------------------
  |  |  |  Branch (172:13): [True: 0, False: 1]
  |  |  ------------------
  |  |  173|      1|            ((uint64_t) \
  |  |  174|      0|             ((uint64_t)((uint8_t *)(x))[0] << 0)  + \
  |  |  175|      0|             ((uint64_t)((uint8_t *)(x))[1] << 8) + \
  |  |  176|      0|             ((uint64_t)((uint8_t *)(x))[2] << 16) + \
  |  |  177|      0|             ((uint64_t)((uint8_t *)(x))[3] << 24) + \
  |  |  178|      0|             ((uint64_t)((uint8_t *)(x))[4] << 32) + \
  |  |  179|      0|             ((uint64_t)((uint8_t *)(x))[5] << 40) + \
  |  |  180|      0|             ((uint64_t)((uint8_t *)(x))[6] << 48) + \
  |  |  181|      0|             ((uint64_t)((uint8_t *)(x))[7] << 56)) \
  |  |  182|      1|                                          : \
  |  |  183|      1|            ((uint64_t) \
  |  |  184|      1|             ((uint64_t)((uint8_t *)(x))[7] <<  0) + \
  |  |  185|      1|             ((uint64_t)((uint8_t *)(x))[6] <<  8) + \
  |  |  186|      1|             ((uint64_t)((uint8_t *)(x))[5] << 16) + \
  |  |  187|      1|             ((uint64_t)((uint8_t *)(x))[4] << 24) + \
  |  |  188|      1|             ((uint64_t)((uint8_t *)(x))[3] << 32) + \
  |  |  189|      1|             ((uint64_t)((uint8_t *)(x))[2] << 40) + \
  |  |  190|      1|             ((uint64_t)((uint8_t *)(x))[1] << 48) + \
  |  |  191|      1|             ((uint64_t)((uint8_t *)(x))[0] << 56)) )
  ------------------
 1841|       |
 1842|       |
 1843|       |    // convert the  runs in the volume header to attribute runs
 1844|      1|    if (((attr_run =
  ------------------
  |  Branch (1844:9): [True: 1, False: 0]
  ------------------
 1845|      1|                hfs_extents_to_attr(fs, hfs->fs->cat_file.extents,
 1846|      1|                    0)) == NULL) && (tsk_error_get_errno() != 0)) {
  ------------------
  |  Branch (1846:37): [True: 0, False: 1]
  ------------------
 1847|      0|        error_returned(" - hfs_make_catalog");
 1848|      0|        return 1;
 1849|      0|    }
 1850|       |
 1851|      1|    if ((fs_attr =
  ------------------
  |  Branch (1851:9): [True: 0, False: 1]
  ------------------
 1852|      1|            tsk_fs_attrlist_getnew(fs_file->meta->attr,
 1853|      1|                TSK_FS_ATTR_NONRES)) == NULL) {
 1854|      0|        error_returned(" - hfs_make_catalog");
 1855|      0|        tsk_fs_attr_run_free(attr_run);
 1856|      0|        return 1;
 1857|      0|    }
 1858|       |
 1859|       |    // initialize the data run
 1860|      1|    if (tsk_fs_attr_set_run(fs_file, fs_attr, attr_run, NULL,
  ------------------
  |  Branch (1860:9): [True: 0, False: 1]
  ------------------
 1861|      1|            TSK_FS_ATTR_TYPE_DEFAULT, HFS_FS_ATTR_ID_DATA,
  ------------------
  |  |  118|      1|#define HFS_FS_ATTR_ID_DATA 0
  ------------------
 1862|      1|            tsk_getu64(fs->endian, hfs->fs->cat_file.logic_sz),
  ------------------
  |  |  171|      1|#define tsk_getu64(endian, x)   \
  |  |  172|      1|(uint64_t)( ((endian) == TSK_LIT_ENDIAN)  ?	\
  |  |  ------------------
  |  |  |  Branch (172:13): [True: 0, False: 1]
  |  |  ------------------
  |  |  173|      1|            ((uint64_t) \
  |  |  174|      0|             ((uint64_t)((uint8_t *)(x))[0] << 0)  + \
  |  |  175|      0|             ((uint64_t)((uint8_t *)(x))[1] << 8) + \
  |  |  176|      0|             ((uint64_t)((uint8_t *)(x))[2] << 16) + \
  |  |  177|      0|             ((uint64_t)((uint8_t *)(x))[3] << 24) + \
  |  |  178|      0|             ((uint64_t)((uint8_t *)(x))[4] << 32) + \
  |  |  179|      0|             ((uint64_t)((uint8_t *)(x))[5] << 40) + \
  |  |  180|      0|             ((uint64_t)((uint8_t *)(x))[6] << 48) + \
  |  |  181|      0|             ((uint64_t)((uint8_t *)(x))[7] << 56)) \
  |  |  182|      1|                                          : \
  |  |  183|      1|            ((uint64_t) \
  |  |  184|      1|             ((uint64_t)((uint8_t *)(x))[7] <<  0) + \
  |  |  185|      1|             ((uint64_t)((uint8_t *)(x))[6] <<  8) + \
  |  |  186|      1|             ((uint64_t)((uint8_t *)(x))[5] << 16) + \
  |  |  187|      1|             ((uint64_t)((uint8_t *)(x))[4] << 24) + \
  |  |  188|      1|             ((uint64_t)((uint8_t *)(x))[3] << 32) + \
  |  |  189|      1|             ((uint64_t)((uint8_t *)(x))[2] << 40) + \
  |  |  190|      1|             ((uint64_t)((uint8_t *)(x))[1] << 48) + \
  |  |  191|      1|             ((uint64_t)((uint8_t *)(x))[0] << 56)) )
  ------------------
 1863|      1|            tsk_getu64(fs->endian, hfs->fs->cat_file.logic_sz),
  ------------------
  |  |  171|      1|#define tsk_getu64(endian, x)   \
  |  |  172|      1|(uint64_t)( ((endian) == TSK_LIT_ENDIAN)  ?	\
  |  |  ------------------
  |  |  |  Branch (172:13): [True: 0, False: 1]
  |  |  ------------------
  |  |  173|      1|            ((uint64_t) \
  |  |  174|      0|             ((uint64_t)((uint8_t *)(x))[0] << 0)  + \
  |  |  175|      0|             ((uint64_t)((uint8_t *)(x))[1] << 8) + \
  |  |  176|      0|             ((uint64_t)((uint8_t *)(x))[2] << 16) + \
  |  |  177|      0|             ((uint64_t)((uint8_t *)(x))[3] << 24) + \
  |  |  178|      0|             ((uint64_t)((uint8_t *)(x))[4] << 32) + \
  |  |  179|      0|             ((uint64_t)((uint8_t *)(x))[5] << 40) + \
  |  |  180|      0|             ((uint64_t)((uint8_t *)(x))[6] << 48) + \
  |  |  181|      0|             ((uint64_t)((uint8_t *)(x))[7] << 56)) \
  |  |  182|      1|                                          : \
  |  |  183|      1|            ((uint64_t) \
  |  |  184|      1|             ((uint64_t)((uint8_t *)(x))[7] <<  0) + \
  |  |  185|      1|             ((uint64_t)((uint8_t *)(x))[6] <<  8) + \
  |  |  186|      1|             ((uint64_t)((uint8_t *)(x))[5] << 16) + \
  |  |  187|      1|             ((uint64_t)((uint8_t *)(x))[4] << 24) + \
  |  |  188|      1|             ((uint64_t)((uint8_t *)(x))[3] << 32) + \
  |  |  189|      1|             ((uint64_t)((uint8_t *)(x))[2] << 40) + \
  |  |  190|      1|             ((uint64_t)((uint8_t *)(x))[1] << 48) + \
  |  |  191|      1|             ((uint64_t)((uint8_t *)(x))[0] << 56)) )
  ------------------
 1864|      1|            tsk_getu64(fs->endian, hfs->fs->cat_file.logic_sz), 0, 0)) {
  ------------------
  |  |  171|      1|#define tsk_getu64(endian, x)   \
  |  |  172|      1|(uint64_t)( ((endian) == TSK_LIT_ENDIAN)  ?	\
  |  |  ------------------
  |  |  |  Branch (172:13): [True: 0, False: 1]
  |  |  ------------------
  |  |  173|      1|            ((uint64_t) \
  |  |  174|      0|             ((uint64_t)((uint8_t *)(x))[0] << 0)  + \
  |  |  175|      0|             ((uint64_t)((uint8_t *)(x))[1] << 8) + \
  |  |  176|      0|             ((uint64_t)((uint8_t *)(x))[2] << 16) + \
  |  |  177|      0|             ((uint64_t)((uint8_t *)(x))[3] << 24) + \
  |  |  178|      0|             ((uint64_t)((uint8_t *)(x))[4] << 32) + \
  |  |  179|      0|             ((uint64_t)((uint8_t *)(x))[5] << 40) + \
  |  |  180|      0|             ((uint64_t)((uint8_t *)(x))[6] << 48) + \
  |  |  181|      0|             ((uint64_t)((uint8_t *)(x))[7] << 56)) \
  |  |  182|      1|                                          : \
  |  |  183|      1|            ((uint64_t) \
  |  |  184|      1|             ((uint64_t)((uint8_t *)(x))[7] <<  0) + \
  |  |  185|      1|             ((uint64_t)((uint8_t *)(x))[6] <<  8) + \
  |  |  186|      1|             ((uint64_t)((uint8_t *)(x))[5] << 16) + \
  |  |  187|      1|             ((uint64_t)((uint8_t *)(x))[4] << 24) + \
  |  |  188|      1|             ((uint64_t)((uint8_t *)(x))[3] << 32) + \
  |  |  189|      1|             ((uint64_t)((uint8_t *)(x))[2] << 40) + \
  |  |  190|      1|             ((uint64_t)((uint8_t *)(x))[1] << 48) + \
  |  |  191|      1|             ((uint64_t)((uint8_t *)(x))[0] << 56)) )
  ------------------
 1865|      0|        error_returned(" - hfs_make_catalog");
 1866|      0|        tsk_fs_attr_run_free(attr_run);
 1867|      0|        return 1;
 1868|      0|    }
 1869|       |
 1870|       |    // see if catalog file has additional runs
 1871|      1|    if (hfs_ext_find_extent_record_attr(hfs, HFS_CATALOG_FILE_ID, fs_attr,
  ------------------
  |  |  126|      1|#define HFS_CATALOG_FILE_ID        4    // catalog file
  ------------------
  |  Branch (1871:9): [True: 1, False: 0]
  ------------------
 1872|      1|            TRUE)) {
  ------------------
  |  |  454|      1|#define TRUE  ( !FALSE )
  |  |  ------------------
  |  |  |  |  453|      1|#define FALSE 0
  |  |  ------------------
  ------------------
 1873|      1|        error_returned(" - hfs_make_catalog");
 1874|      1|        fs_file->meta->attr_state = TSK_FS_META_ATTR_ERROR;
 1875|      1|        return 1;
 1876|      1|    }
 1877|       |
 1878|      0|    result = hfs_load_extended_attrs(fs_file, &dummy1, &dummy2, &dummy3);
 1879|      0|    if (result != 0) {
  ------------------
  |  Branch (1879:9): [True: 0, False: 0]
  ------------------
 1880|      0|        if (tsk_verbose)
  ------------------
  |  Branch (1880:13): [True: 0, False: 0]
  ------------------
 1881|      0|            tsk_fprintf(stderr,
 1882|      0|                "WARNING: Extended attributes failed to load for the Catalog file.\n");
 1883|      0|        tsk_error_reset();
 1884|      0|    }
 1885|       |
 1886|      0|    fs_file->meta->attr_state = TSK_FS_META_ATTR_STUDIED;
 1887|      0|    return 0;
 1888|      1|}
hfs.c:hfs_ext_find_extent_record_attr:
  308|      1|{
  309|      1|    TSK_FS_INFO *fs = (TSK_FS_INFO *) & (hfs->fs_info);
  310|      1|    uint16_t nodesize;          /* size of nodes (all, regardless of the name) */
  311|      1|    uint32_t cur_node;          /* node id of the current node */
  312|      1|    char *node = NULL;
  313|      1|    uint8_t is_done;
  314|      1|    uint8_t desiredType;
  315|       |
  316|      1|    tsk_error_reset();
  317|       |
  318|      1|    if (tsk_verbose)
  ------------------
  |  Branch (318:9): [True: 0, False: 1]
  ------------------
  319|      0|        tsk_fprintf(stderr,
  320|      0|            "hfs_ext_find_extent_record_attr: Looking for extents for file %"
  321|      0|            PRIu32 " %s\n", cnid,
  322|      0|            dataForkQ ? "data fork" : "resource fork");
  ------------------
  |  Branch (322:13): [True: 0, False: 0]
  ------------------
  323|       |
  324|      1|    if (!hfs->has_extents_file) {
  ------------------
  |  Branch (324:9): [True: 0, False: 1]
  ------------------
  325|       |        // No extents file (which is optional), and so, no further extents are possible.
  326|      0|        return 0;
  327|      0|    }
  328|       |
  329|       |    // Are we looking for extents of the data fork or the resource fork?
  330|      1|    desiredType =
  331|      1|        dataForkQ ? HFS_EXT_KEY_TYPE_DATA : HFS_EXT_KEY_TYPE_RSRC;
  ------------------
  |  |  460|      1|#define HFS_EXT_KEY_TYPE_DATA   0x00    // extents key is for data fork
  ------------------
                      dataForkQ ? HFS_EXT_KEY_TYPE_DATA : HFS_EXT_KEY_TYPE_RSRC;
  ------------------
  |  |  461|      1|#define HFS_EXT_KEY_TYPE_RSRC   0xFF    // extents key is for resource fork
  ------------------
  |  Branch (331:9): [True: 1, False: 0]
  ------------------
  332|       |
  333|       |    // Load the extents attribute, if it has not been done so yet.
  334|      1|    if (hfs->extents_file == NULL) {
  ------------------
  |  Branch (334:9): [True: 1, False: 0]
  ------------------
  335|      1|        ssize_t cnt;
  336|       |
  337|      1|        if ((hfs->extents_file =
  ------------------
  |  Branch (337:13): [True: 0, False: 1]
  ------------------
  338|      1|                tsk_fs_file_open_meta(fs, NULL,
  339|      1|                    HFS_EXTENTS_FILE_ID)) == NULL) {
  ------------------
  |  |  124|      1|#define HFS_EXTENTS_FILE_ID        3    // extents overflow file
  ------------------
  340|      0|            return 1;
  341|      0|        }
  342|       |
  343|       |        /* cache the data attribute */
  344|      1|        hfs->extents_attr =
  345|      1|            tsk_fs_attrlist_get(hfs->extents_file->meta->attr,
  346|      1|            TSK_FS_ATTR_TYPE_DEFAULT);
  347|      1|        if (!hfs->extents_attr) {
  ------------------
  |  Branch (347:13): [True: 0, False: 1]
  ------------------
  348|      0|            tsk_error_errstr2_concat
  349|      0|                (" - Default Attribute not found in Extents File");
  350|      0|            return 1;
  351|      0|        }
  352|       |
  353|       |        // cache the extents file header
  354|      1|        cnt = tsk_fs_attr_read(hfs->extents_attr, 14,
  355|      1|            (char *) &(hfs->extents_header),
  356|      1|            sizeof(hfs_btree_header_record), 0);
  357|      1|        if (cnt != sizeof(hfs_btree_header_record)) {
  ------------------
  |  Branch (357:13): [True: 1, False: 0]
  ------------------
  358|      1|            if (cnt >= 0) {
  ------------------
  |  Branch (358:17): [True: 0, False: 1]
  ------------------
  359|      0|                tsk_error_reset();
  360|      0|                tsk_error_set_errno(TSK_ERR_FS_READ);
  ------------------
  |  |  349|      0|#define TSK_ERR_FS_READ		(TSK_ERR_FS | 4)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  361|      0|            }
  362|      1|            tsk_error_set_errstr2
  363|      1|                ("hfs_ext_find_extent_record_attr: Error reading header");
  364|      1|            return 1;
  365|      1|        }
  366|      1|    }
  367|       |
  368|       |    // allocate a node buffer
  369|      0|    nodesize = tsk_getu16(fs->endian, hfs->extents_header.nodesize);
  ------------------
  |  |   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)) )
  ------------------
  370|      0|    if ((node = (char *) tsk_malloc(nodesize)) == NULL) {
  ------------------
  |  Branch (370:9): [True: 0, False: 0]
  ------------------
  371|      0|        return 1;
  372|      0|    }
  373|       |
  374|       |    /* start at root node */
  375|      0|    cur_node = tsk_getu32(fs->endian, hfs->extents_header.rootNode);
  ------------------
  |  |  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) ) )
  ------------------
  376|       |
  377|       |    /* if the root node is zero, then the extents btree is empty */
  378|       |    /* if no files have overflow extents, the Extents B-tree still
  379|       |       exists on disk, but is an empty B-tree containing only
  380|       |       the header node */
  381|      0|    if (cur_node == 0) {
  ------------------
  |  Branch (381:9): [True: 0, False: 0]
  ------------------
  382|      0|        if (tsk_verbose)
  ------------------
  |  Branch (382:13): [True: 0, False: 0]
  ------------------
  383|      0|            tsk_fprintf(stderr, "hfs_ext_find_extent_record: "
  384|      0|                "empty extents btree\n");
  385|      0|        free(node);
  386|      0|        return 0;
  387|      0|    }
  388|       |
  389|      0|    if (tsk_verbose)
  ------------------
  |  Branch (389:9): [True: 0, False: 0]
  ------------------
  390|      0|        tsk_fprintf(stderr, "hfs_ext_find_extent_record: starting at "
  391|      0|            "root node %" PRIu32 "; nodesize = %"
  392|      0|            PRIu16 "\n", cur_node, nodesize);
  393|       |
  394|       |    /* Recurse down to the needed leaf nodes and then go forward */
  395|      0|    is_done = 0;
  396|      0|    while (is_done == 0) {
  ------------------
  |  Branch (396:12): [True: 0, False: 0]
  ------------------
  397|      0|        TSK_OFF_T cur_off;      /* start address of cur_node */
  398|      0|        uint16_t num_rec;       /* number of records in this node */
  399|      0|        ssize_t cnt;
  400|      0|        hfs_btree_node *node_desc;
  401|       |
  402|       |        // sanity check
  403|      0|        if (cur_node > tsk_getu32(fs->endian,
  ------------------
  |  |  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) ) )
  ------------------
  |  Branch (403:13): [True: 0, False: 0]
  ------------------
  404|      0|                hfs->extents_header.totalNodes)) {
  405|      0|            tsk_error_set_errno(TSK_ERR_FS_GENFS);
  ------------------
  |  |  360|      0|#define TSK_ERR_FS_GENFS	(TSK_ERR_FS | 15)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  406|      0|            tsk_error_set_errstr
  407|      0|                ("hfs_ext_find_extent_record_attr: Node %d too large for file",
  408|      0|                cur_node);
  409|      0|            free(node);
  410|      0|            return 1;
  411|      0|        }
  412|       |
  413|       |        // read the current node
  414|      0|        cur_off = (TSK_OFF_T)cur_node * nodesize;
  415|      0|        if (tsk_verbose)
  ------------------
  |  Branch (415:13): [True: 0, False: 0]
  ------------------
  416|      0|            tsk_fprintf(stderr,
  417|      0|                "hfs_ext_find_extent_record: reading node %" PRIu32
  418|      0|                " at offset %" PRIdOFF "\n", cur_node, cur_off);
  419|       |
  420|      0|        cnt = tsk_fs_attr_read(hfs->extents_attr, cur_off,
  421|      0|            node, nodesize, 0);
  422|      0|        if (cnt != nodesize) {
  ------------------
  |  Branch (422:13): [True: 0, False: 0]
  ------------------
  423|      0|            if (cnt >= 0) {
  ------------------
  |  Branch (423:17): [True: 0, False: 0]
  ------------------
  424|      0|                tsk_error_reset();
  425|      0|                tsk_error_set_errno(TSK_ERR_FS_READ);
  ------------------
  |  |  349|      0|#define TSK_ERR_FS_READ		(TSK_ERR_FS | 4)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  426|      0|            }
  427|      0|            tsk_error_set_errstr2
  428|      0|                ("hfs_ext_find_extent_record_attr: Error reading node %d at offset %"
  429|      0|                PRIdOFF, cur_node, cur_off);
  ------------------
  |  |  269|      0|#define PRIdOFF		PRId64
  ------------------
  430|      0|            free(node);
  431|      0|            return 1;
  432|      0|        }
  433|       |
  434|       |        // process the header / descriptor
  435|      0|        if (nodesize < sizeof(hfs_btree_node)) {
  ------------------
  |  Branch (435:13): [True: 0, False: 0]
  ------------------
  436|      0|            tsk_error_set_errno(TSK_ERR_FS_GENFS);
  ------------------
  |  |  360|      0|#define TSK_ERR_FS_GENFS	(TSK_ERR_FS | 15)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  437|      0|            tsk_error_set_errstr
  438|      0|                ("hfs_ext_find_extent_record_attr: Node size %d is too small to be valid", nodesize);
  439|      0|            free(node);
  440|      0|            return 1;
  441|      0|        }
  442|      0|        node_desc = (hfs_btree_node *) node;
  443|      0|        num_rec = tsk_getu16(fs->endian, node_desc->num_rec);
  ------------------
  |  |   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)) )
  ------------------
  444|       |
  445|      0|        if (num_rec == 0) {
  ------------------
  |  Branch (445:13): [True: 0, False: 0]
  ------------------
  446|      0|            tsk_error_set_errno(TSK_ERR_FS_GENFS);
  ------------------
  |  |  360|      0|#define TSK_ERR_FS_GENFS	(TSK_ERR_FS | 15)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  447|      0|            tsk_error_set_errstr
  448|      0|                ("hfs_ext_find_extent_record: zero records in node %"
  449|      0|                PRIu32, cur_node);
  450|      0|            free(node);
  451|      0|            return 1;
  452|      0|        }
  453|       |
  454|       |
  455|       |        /* With an index node, find the record with the largest key that is smaller
  456|       |         * to or equal to cnid */
  457|      0|        if (node_desc->type == HFS_BT_NODE_TYPE_IDX) {
  ------------------
  |  |  402|      0|#define HFS_BT_NODE_TYPE_IDX	 0
  ------------------
  |  Branch (457:13): [True: 0, False: 0]
  ------------------
  458|      0|            uint32_t next_node = 0;
  459|      0|            int rec;
  460|       |
  461|      0|            if (tsk_verbose)
  ------------------
  |  Branch (461:17): [True: 0, False: 0]
  ------------------
  462|      0|                tsk_fprintf(stderr,
  463|      0|                    "hfs_ext_find_extent_record: Index node %" PRIu32
  464|      0|                    " @ %" PRIu64 " has %" PRIu16 " records\n", cur_node,
  465|      0|                    cur_off, num_rec);
  466|       |
  467|      0|            for (rec = 0; rec < num_rec; ++rec) {
  ------------------
  |  Branch (467:27): [True: 0, False: 0]
  ------------------
  468|      0|                int cmp;
  469|      0|                size_t rec_off;
  470|      0|                hfs_btree_key_ext *key;
  471|       |
  472|       |                // Make sure node is large enough, note that (rec + 1) * 2 is an offset
  473|       |                // relative to the end of node
  474|      0|                if ((rec + 1) * 2 > (int) nodesize) {
  ------------------
  |  Branch (474:21): [True: 0, False: 0]
  ------------------
  475|      0|                    tsk_error_set_errno(TSK_ERR_FS_GENFS);
  ------------------
  |  |  360|      0|#define TSK_ERR_FS_GENFS	(TSK_ERR_FS | 15)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  476|      0|                    tsk_error_set_errstr
  477|      0|                        ("hfs_ext_find_extent_record: offset of record %d in leaf node %d too small (%"
  478|      0|                        PRIu16 ")", rec, cur_node, nodesize);
  479|      0|                    free(node);
  480|      0|                    return 1;
  481|      0|                }
  482|       |                // get the record offset in the node
  483|      0|                rec_off =
  484|      0|                    tsk_getu16(fs->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)) )
  ------------------
  485|      0|                    &node[nodesize - (rec + 1) * 2]);
  486|      0|                if (rec_off > nodesize - sizeof(hfs_btree_key_ext)) {
  ------------------
  |  Branch (486:21): [True: 0, False: 0]
  ------------------
  487|      0|                    tsk_error_set_errno(TSK_ERR_FS_GENFS);
  ------------------
  |  |  360|      0|#define TSK_ERR_FS_GENFS	(TSK_ERR_FS | 15)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  488|      0|                    tsk_error_set_errstr
  489|      0|                        ("hfs_ext_find_extent_record_attr: offset of record %d in index node %d too large (%d vs %"
  490|      0|                        PRIu16 ")", rec, cur_node, (int) rec_off,
  491|      0|                        nodesize);
  492|      0|                    free(node);
  493|      0|                    return 1;
  494|      0|                }
  495|      0|                key = (hfs_btree_key_ext *) & node[rec_off];
  496|       |
  497|      0|                cmp = hfs_ext_compare_keys(hfs, cnid, key);
  498|       |
  499|      0|                if (tsk_verbose)
  ------------------
  |  Branch (499:21): [True: 0, False: 0]
  ------------------
  500|      0|                    tsk_fprintf(stderr,
  501|      0|                        "hfs_ext_find_extent_record: record %" PRIu16
  502|      0|                        " ; keylen %" PRIu16 " (FileId: %" PRIu32
  503|      0|                        ", ForkType: %" PRIu8 ", StartBlk: %" PRIu32
  504|      0|                        "); compare: %d\n", rec, tsk_getu16(fs->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)) )
  ------------------
  505|      0|                            key->key_len), tsk_getu32(fs->endian,
  ------------------
  |  |  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) ) )
  ------------------
  506|      0|                            key->file_id), key->fork_type,
  507|      0|                        tsk_getu32(fs->endian, key->start_block), cmp);
  ------------------
  |  |  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) ) )
  ------------------
  508|       |
  509|       |                /* save the info from this record unless it is bigger than cnid */
  510|      0|                if ((cmp <= 0) || (next_node == 0)) {
  ------------------
  |  Branch (510:21): [True: 0, False: 0]
  |  Branch (510:35): [True: 0, False: 0]
  ------------------
  511|      0|                    hfs_btree_index_record *idx_rec;
  512|      0|                    int keylen =
  513|      0|                        2 + hfs_get_idxkeylen(hfs, tsk_getu16(fs->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)) )
  ------------------
  514|      0|                            key->key_len), &(hfs->extents_header));
  515|      0|                    if ((nodesize < 4) || (keylen > nodesize - 4) || (rec_off >= nodesize - 4 - keylen)) {
  ------------------
  |  Branch (515:25): [True: 0, False: 0]
  |  Branch (515:43): [True: 0, False: 0]
  |  Branch (515:70): [True: 0, False: 0]
  ------------------
  516|      0|                        tsk_error_set_errno(TSK_ERR_FS_GENFS);
  ------------------
  |  |  360|      0|#define TSK_ERR_FS_GENFS	(TSK_ERR_FS | 15)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  517|      0|                        tsk_error_set_errstr
  518|      0|                            ("hfs_ext_find_extent_record_attr: offset and keylenth of record %d in index node %d too large (%d vs %"
  519|      0|                            PRIu16 ")", rec, cur_node,
  520|      0|                            (int) rec_off + keylen, nodesize);
  521|      0|                        free(node);
  522|      0|                        return 1;
  523|      0|                    }
  524|      0|                    idx_rec =
  525|      0|                        (hfs_btree_index_record *) & node[rec_off +
  526|      0|                        keylen];
  527|      0|                    next_node = tsk_getu32(fs->endian, idx_rec->childNode);
  ------------------
  |  |  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) ) )
  ------------------
  528|      0|                }
  529|       |
  530|       |                // we are bigger than cnid, so move on to the next node
  531|      0|                if (cmp > 0) {
  ------------------
  |  Branch (531:21): [True: 0, False: 0]
  ------------------
  532|      0|                    break;
  533|      0|                }
  534|      0|            }
  535|       |
  536|       |            // check if we found a relevant node, if not stop.
  537|      0|            if (next_node == 0) {
  ------------------
  |  Branch (537:17): [True: 0, False: 0]
  ------------------
  538|      0|                if (tsk_verbose)
  ------------------
  |  Branch (538:21): [True: 0, False: 0]
  ------------------
  539|      0|                    tsk_fprintf(stderr,
  540|      0|                        "hfs_ext_find_extent_record_attr: did not find any keys for %d in index node %d",
  541|      0|                        cnid, cur_node);
  542|      0|                is_done = 1;
  543|      0|                break;
  544|      0|            }
  545|      0|            cur_node = next_node;
  546|      0|        }
  547|       |
  548|       |        /* with a leaf, we process until we are past cnid.  We move right too if we can */
  549|      0|        else if (node_desc->type == HFS_BT_NODE_TYPE_LEAF) {
  ------------------
  |  |  401|      0|#define HFS_BT_NODE_TYPE_LEAF	-1
  ------------------
  |  Branch (549:18): [True: 0, False: 0]
  ------------------
  550|      0|            int rec;
  551|       |
  552|      0|            if (tsk_verbose)
  ------------------
  |  Branch (552:17): [True: 0, False: 0]
  ------------------
  553|      0|                tsk_fprintf(stderr,
  554|      0|                    "hfs_ext_find_extent_record: Leaf node %" PRIu32 " @ %"
  555|      0|                    PRIu64 " has %" PRIu16 " records\n", cur_node, cur_off,
  556|      0|                    num_rec);
  557|       |
  558|      0|            for (rec = 0; rec < num_rec; ++rec) {
  ------------------
  |  Branch (558:27): [True: 0, False: 0]
  ------------------
  559|      0|                size_t rec_off;
  560|      0|                hfs_btree_key_ext *key;
  561|      0|                uint32_t rec_cnid;
  562|      0|                hfs_extents *extents;
  563|      0|                TSK_OFF_T ext_off = 0;
  564|      0|                int keylen;
  565|      0|                TSK_FS_ATTR_RUN *attr_run;
  566|       |
  567|       |                // Make sure node is large enough, note that (rec + 1) * 2 is an offset
  568|       |                // relative to the end of node
  569|      0|                if ((rec + 1) * 2 > (int) nodesize) {
  ------------------
  |  Branch (569:21): [True: 0, False: 0]
  ------------------
  570|      0|                    tsk_error_set_errno(TSK_ERR_FS_GENFS);
  ------------------
  |  |  360|      0|#define TSK_ERR_FS_GENFS	(TSK_ERR_FS | 15)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  571|      0|                    tsk_error_set_errstr
  572|      0|                        ("hfs_ext_find_extent_record_attr: offset of record %d in leaf node %d too small (%"
  573|      0|                        PRIu16 ")", rec, cur_node, nodesize);
  574|      0|                    free(node);
  575|      0|                    return 1;
  576|      0|                }
  577|       |                // get the record offset in the node
  578|      0|                rec_off =
  579|      0|                    tsk_getu16(fs->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)) )
  ------------------
  580|      0|                    &node[nodesize - (rec + 1) * 2]);
  581|       |
  582|      0|                if (rec_off >= nodesize - sizeof(hfs_btree_key_ext)) {
  ------------------
  |  Branch (582:21): [True: 0, False: 0]
  ------------------
  583|      0|                    tsk_error_set_errno(TSK_ERR_FS_GENFS);
  ------------------
  |  |  360|      0|#define TSK_ERR_FS_GENFS	(TSK_ERR_FS | 15)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  584|      0|                    tsk_error_set_errstr
  585|      0|                        ("hfs_ext_find_extent_record_attr: offset of record %d in leaf node %d too large (%d vs %"
  586|      0|                        PRIu16 ")", rec, cur_node, (int) rec_off,
  587|      0|                        nodesize);
  588|      0|                    free(node);
  589|      0|                    return 1;
  590|      0|                }
  591|       |
  592|       |                // Check that the whole hfs_btree_key_ext structure is set
  593|      0|                if (sizeof(hfs_btree_key_ext) > nodesize - rec_off) {
  ------------------
  |  Branch (593:21): [True: 0, False: 0]
  ------------------
  594|      0|                    tsk_error_set_errno(TSK_ERR_FS_GENFS);
  ------------------
  |  |  360|      0|#define TSK_ERR_FS_GENFS	(TSK_ERR_FS | 15)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  595|      0|                    tsk_error_set_errstr
  596|      0|                    ("hfs_ext_find_extent_record_attr: record %d in leaf node %d truncated (have %d vs %"
  597|      0|                        PRIu16 " bytes)", rec, cur_node, nodesize - (int)rec_off,
  598|      0|                        sizeof(hfs_btree_key_ext));
  599|      0|                    free(node);
  600|      0|                    return 1;
  601|      0|                }
  602|       |
  603|      0|                key = (hfs_btree_key_ext *) & node[rec_off];
  604|       |
  605|      0|                if (tsk_verbose)
  ------------------
  |  Branch (605:21): [True: 0, False: 0]
  ------------------
  606|      0|                    tsk_fprintf(stderr,
  607|      0|                        "hfs_ext_find_extent_record: record %" PRIu16
  608|      0|                        "; keylen %" PRIu16 " (%" PRIu32
  609|      0|                        ", %" PRIu8 ", %" PRIu32 ")\n", rec,
  610|      0|                        tsk_getu16(fs->endian, key->key_len),
  ------------------
  |  |   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)) )
  ------------------
  611|      0|                        tsk_getu32(fs->endian, key->file_id),
  ------------------
  |  |  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) ) )
  ------------------
  612|      0|                        key->fork_type, tsk_getu32(fs->endian,
  ------------------
  |  |  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) ) )
  ------------------
  613|      0|                            key->start_block));
  614|       |
  615|      0|                rec_cnid = tsk_getu32(fs->endian, key->file_id);
  ------------------
  |  |  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) ) )
  ------------------
  616|       |
  617|       |                // see if this record is for our file
  618|       |                // OLD logic, just handles the DATA fork
  619|       |//                if (rec_cnid < cnid) {
  620|       |//                    continue;
  621|       |//                }
  622|       |//                else if ((rec_cnid > cnid)
  623|       |//                    || (key->fork_type != HFS_EXT_KEY_TYPE_DATA)) {
  624|       |//                    is_done = 1;
  625|       |//                    break;
  626|       |//                }
  627|       |
  628|       |                // NEW logic, handles both DATA and RSRC forks.
  629|      0|                if (rec_cnid < cnid) {
  ------------------
  |  Branch (629:21): [True: 0, False: 0]
  ------------------
  630|      0|                    continue;
  631|      0|                }
  632|      0|                if (rec_cnid > cnid) {
  ------------------
  |  Branch (632:21): [True: 0, False: 0]
  ------------------
  633|      0|                    is_done = 1;
  634|      0|                    break;
  635|      0|                }
  636|       |
  637|       |
  638|      0|                if (key->fork_type != desiredType) {
  ------------------
  |  Branch (638:21): [True: 0, False: 0]
  ------------------
  639|      0|                    if (dataForkQ) {
  ------------------
  |  Branch (639:25): [True: 0, False: 0]
  ------------------
  640|      0|                        is_done = 1;
  641|      0|                        break;
  642|      0|                    }
  643|      0|                    else
  644|      0|                        continue;
  645|      0|                }
  646|       |
  647|       |                // OK, this is one of the extents records that we are seeking, so save it.
  648|       |                // Make sure there is room for the hfs_extents struct
  649|      0|                keylen = 2 + tsk_getu16(fs->endian, key->key_len);
  ------------------
  |  |   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)) )
  ------------------
  650|      0|                if (rec_off + keylen + sizeof(hfs_extents) > nodesize) {
  ------------------
  |  Branch (650:21): [True: 0, False: 0]
  ------------------
  651|      0|                    tsk_error_set_errno(TSK_ERR_FS_GENFS);
  ------------------
  |  |  360|      0|#define TSK_ERR_FS_GENFS	(TSK_ERR_FS | 15)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  652|      0|                    tsk_error_set_errstr
  653|      0|                        ("hfs_ext_find_extent_record_attr: offset and keylenth of record %d in leaf node %d too large (%d vs %"
  654|      0|                        PRIu16 ")", rec, cur_node, (int) rec_off + keylen,
  655|      0|                        nodesize);
  656|      0|                    free(node);
  657|      0|                    return 1;
  658|      0|                }
  659|       |
  660|       |                // get the starting offset of this extent
  661|      0|                ext_off = tsk_getu32(fs->endian, key->start_block);
  ------------------
  |  |  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) ) )
  ------------------
  662|       |
  663|       |                // convert the extents to the TSK format
  664|      0|                extents = (hfs_extents *) & node[rec_off + keylen];
  665|       |
  666|      0|                attr_run =
  667|      0|                    hfs_extents_to_attr(fs, extents->extents, ext_off);
  668|      0|                if ((attr_run == NULL) && (tsk_error_get_errno() != 0)) {
  ------------------
  |  Branch (668:21): [True: 0, False: 0]
  |  Branch (668:43): [True: 0, False: 0]
  ------------------
  669|      0|                    tsk_error_errstr2_concat
  670|      0|                        (" - hfs_ext_find_extent_record_attr");
  671|      0|                    free(node);
  672|      0|                    return 1;
  673|      0|                }
  674|       |
  675|      0|                if (tsk_fs_attr_add_run(fs, a_attr, attr_run)) {
  ------------------
  |  Branch (675:21): [True: 0, False: 0]
  ------------------
  676|      0|                    tsk_error_errstr2_concat
  677|      0|                        (" - hfs_ext_find_extent_record_attr");
  678|      0|                    free(node);
  679|      0|                    return 1;
  680|      0|                }
  681|      0|            }
  682|      0|            cur_node = tsk_getu32(fs->endian, node_desc->flink);
  ------------------
  |  |  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) ) )
  ------------------
  683|      0|            if (cur_node == 0) {
  ------------------
  |  Branch (683:17): [True: 0, False: 0]
  ------------------
  684|      0|                is_done = 1;
  685|      0|                break;
  686|      0|            }
  687|      0|        }
  688|      0|        else {
  689|      0|            tsk_error_set_errno(TSK_ERR_FS_GENFS);
  ------------------
  |  |  360|      0|#define TSK_ERR_FS_GENFS	(TSK_ERR_FS | 15)
  |  |  ------------------
  |  |  |  |  301|      0|#define TSK_ERR_FS	0x08000000
  |  |  ------------------
  ------------------
  690|      0|            tsk_error_set_errstr("hfs_ext_find_extent_record: btree node %"
  691|      0|                PRIu32 " (%" PRIdOFF ") is neither index nor leaf (%" PRIu8
  692|      0|                ")", cur_node, cur_off, node_desc->type);
  693|      0|            free(node);
  694|      0|            return 1;
  695|      0|        }
  696|      0|    }
  697|      0|    free(node);
  698|      0|    return 0;
  699|      0|}
hfs.c:hfs_close:
 6379|      1|{
 6380|      1|    HFS_INFO *hfs = (HFS_INFO *) fs;
 6381|       |    // We'll grab this lock a bit early.
 6382|      1|    tsk_take_lock(&(hfs->metadata_dir_cache_lock));
 6383|      1|    fs->tag = 0;
 6384|       |
 6385|      1|    free(hfs->fs);
 6386|       |
 6387|      1|    if (hfs->catalog_file) {
  ------------------
  |  Branch (6387:9): [True: 0, False: 1]
  ------------------
 6388|      0|        tsk_fs_file_close(hfs->catalog_file);
 6389|      0|        hfs->catalog_attr = NULL;
 6390|      0|    }
 6391|       |
 6392|      1|    if (hfs->blockmap_file) {
  ------------------
  |  Branch (6392:9): [True: 0, False: 1]
  ------------------
 6393|      0|        tsk_fs_file_close(hfs->blockmap_file);
 6394|      0|        hfs->blockmap_attr = NULL;
 6395|      0|    }
 6396|       |
 6397|      1|    if (hfs->meta_dir) {
  ------------------
  |  Branch (6397:9): [True: 0, False: 1]
  ------------------
 6398|      0|        tsk_fs_dir_close(hfs->meta_dir);
 6399|      0|        hfs->meta_dir = NULL;
 6400|      0|    }
 6401|       |
 6402|      1|    if (hfs->dir_meta_dir) {
  ------------------
  |  Branch (6402:9): [True: 0, False: 1]
  ------------------
 6403|      0|        tsk_fs_dir_close(hfs->dir_meta_dir);
 6404|      0|        hfs->dir_meta_dir = NULL;
 6405|      0|    }
 6406|       |
 6407|      1|    if (hfs->extents_file) {
  ------------------
  |  Branch (6407:9): [True: 1, False: 0]
  ------------------
 6408|      1|        tsk_fs_file_close(hfs->extents_file);
 6409|      1|        hfs->extents_file = NULL;
 6410|      1|    }
 6411|       |
 6412|      1|    tsk_release_lock(&(hfs->metadata_dir_cache_lock));
 6413|      1|    tsk_deinit_lock(&(hfs->metadata_dir_cache_lock));
 6414|       |
 6415|      1|    tsk_fs_free((TSK_FS_INFO *)hfs);
 6416|      1|}

tsk_img_read:
   60|      1|{
   61|      1|#define CACHE_AGE   1000
   62|      1|    ssize_t read_count = 0;
   63|      1|    int cache_index = 0;
   64|      1|    int cache_next = 0;         // index to lowest age cache (to use next)
   65|      1|    size_t len2 = 0;
   66|       |
   67|      1|    if (a_img_info == NULL) {
  ------------------
  |  Branch (67:9): [True: 0, False: 1]
  ------------------
   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|      1|    if (a_buf == NULL) {
  ------------------
  |  Branch (75:9): [True: 0, False: 1]
  ------------------
   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|      1|    if (a_off < 0) {
  ------------------
  |  Branch (83:9): [True: 0, False: 1]
  ------------------
   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|      1|    if ((TSK_OFF_T) a_len < 0) {
  ------------------
  |  Branch (95:9): [True: 0, False: 1]
  ------------------
   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|      1|    tsk_take_lock(&(a_img_info->cache_lock));
  107|       |
  108|       |    // if they ask for more than the cache length, skip the cache
  109|      1|    if ((a_len + (a_off % 512)) > TSK_IMG_INFO_CACHE_LEN) {
  ------------------
  |  |   85|      1|#define TSK_IMG_INFO_CACHE_LEN  65536
  ------------------
  |  Branch (109:9): [True: 0, False: 1]
  ------------------
  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|      1|    if (a_off >= a_img_info->size) {
  ------------------
  |  Branch (117:9): [True: 0, False: 1]
  ------------------
  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|      1|    len2 = a_len;
  128|       |
  129|       |    // Protect against INT64_MAX + INT64_MAX > value
  130|      1|    if (((TSK_OFF_T) len2 > a_img_info->size)
  ------------------
  |  Branch (130:9): [True: 0, False: 1]
  ------------------
  131|      1|        || (a_off >= (a_img_info->size - (TSK_OFF_T)len2))) {
  ------------------
  |  Branch (131:12): [True: 0, False: 1]
  ------------------
  132|      0|        len2 = (size_t) (a_img_info->size - a_off);
  133|      0|    }
  134|       |
  135|       |    // check if it is in the cache
  136|      1|    for (cache_index = 0;
  137|     33|        cache_index < TSK_IMG_INFO_CACHE_NUM; cache_index++) {
  ------------------
  |  |   84|     33|#define TSK_IMG_INFO_CACHE_NUM  32
  ------------------
  |  Branch (137:9): [True: 32, False: 1]
  ------------------
  138|       |
  139|       |        // Look into the in-use cache entries
  140|     32|        if (a_img_info->cache_len[cache_index] > 0) {
  ------------------
  |  Branch (140:13): [True: 0, False: 32]
  ------------------
  141|       |
  142|       |            // the read_count check makes sure we don't go back in after data was read
  143|      0|            if ((read_count == 0)
  ------------------
  |  Branch (143:17): [True: 0, False: 0]
  ------------------
  144|      0|                && (a_img_info->cache_off[cache_index] <= a_off)
  ------------------
  |  Branch (144:20): [True: 0, False: 0]
  ------------------
  145|      0|                && (a_img_info->cache_off[cache_index] +
  ------------------
  |  Branch (145:20): [True: 0, False: 0]
  ------------------
  146|      0|                    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|      0|                memcpy(a_buf,
  156|      0|                    &a_img_info->cache[cache_index][a_off -
  157|      0|                        a_img_info->cache_off[cache_index]], len2);
  158|      0|                read_count = (ssize_t) len2;
  159|       |
  160|       |                // reset its "age" since it was useful
  161|      0|                a_img_info->cache_age[cache_index] = CACHE_AGE;
  ------------------
  |  |   61|      0|#define CACHE_AGE   1000
  ------------------
  162|       |
  163|       |                // we don't break out of the loop so that we update all ages
  164|      0|            }
  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|      0|        }
  178|     32|        else {
  179|     32|            cache_next = cache_index;
  180|     32|        }
  181|     32|    }
  182|       |
  183|       |    // if we didn't find it, then load it into the cache_next entry
  184|      1|    if (read_count == 0) {
  ------------------
  |  Branch (184:9): [True: 1, False: 0]
  ------------------
  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|      1|    tsk_release_lock(&(a_img_info->cache_lock));
  249|      1|    return read_count;
  250|      1|}

LLVMFuzzerTestOneInput:
   25|      1|extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   26|      1|  TSK_IMG_INFO *img;
   27|      1|  TSK_FS_INFO *fs;
   28|       |
   29|      1|  img = mem_open(data, size);
   30|      1|  if (img == nullptr)
  ------------------
  |  Branch (30:7): [True: 0, False: 1]
  ------------------
   31|      0|    return 0;
   32|       |
   33|      1|  fs = tsk_fs_open_img(img, 0, FSTYPE);
   34|      1|  if (fs != nullptr) {
  ------------------
  |  Branch (34:7): [True: 0, False: 1]
  ------------------
   35|      0|    tsk_fs_fls(fs, TSK_FS_FLS_FULL, fs->root_inum, TSK_FS_DIR_WALK_FLAG_RECURSE,
   36|      0|               nullptr, 0);
   37|       |
   38|      0|    fs->close(fs);
   39|      0|  }
   40|       |
   41|      1|  img->close(img);
   42|      1|  return 0;
   43|      1|}

