From 98f150fb274b7504f63ebeff123ca38eb69f9334 Mon Sep 17 00:00:00 2001
From: Brian Carrier <carrier@sleuthkit.org>
Date: Sun, 26 Apr 2009 04:29:35 +0000
Subject: [PATCH] Fixed bug in new HFS B-tree traverse code that caused some
 file names to be not displayed

---
 tsk3/fs/hfs.c      | 46 ++++++++++++++++++++++++++++++++++------------
 tsk3/fs/hfs_dent.c | 28 +++++++++++++++++++---------
 tsk3/fs/tsk_hfs.h  |  8 +++++---
 tsk3/img/img_io.c  |  4 ++++
 4 files changed, 62 insertions(+), 24 deletions(-)

diff --git a/tsk3/fs/hfs.c b/tsk3/fs/hfs.c
index 957123e29..e27085e1a 100644
--- a/tsk3/fs/hfs.c
+++ b/tsk3/fs/hfs.c
@@ -745,7 +745,9 @@ hfs_cat_traverse(HFS_INFO * hfs, const void *targ_data,
                     free(node);
                     return 1;
                 }
-                else if ((retval == HFS_BTREE_CB_GO) || (next_node == 0)) {
+                // record the closest entry
+                else if ((retval == HFS_BTREE_CB_IDX_LT)
+                    || (next_node == 0)) {
                     hfs_btree_index_record *idx_rec;
                     int keylen =
                         2 + hfs_get_idxkeylen(hfs, tsk_getu16(fs->endian,
@@ -764,8 +766,8 @@ hfs_cat_traverse(HFS_INFO * hfs, const void *targ_data,
                         keylen];
                     next_node = tsk_getu32(fs->endian, idx_rec->childNode);
                 }
-                if (retval == HFS_BTREE_CB_STOP) {
-                    // we are now too big, so move down to the next node
+                if (retval == HFS_BTREE_CB_IDX_EQGT) {
+                    // move down to the next node
                     break;
                 }
             }
@@ -817,7 +819,7 @@ hfs_cat_traverse(HFS_INFO * hfs, const void *targ_data,
                 retval =
                     a_cb(hfs, HFS_BT_NODE_TYPE_LEAF, targ_data, key,
                     cur_off + rec_off, ptr);
-                if (retval == HFS_BTREE_CB_STOP) {
+                if (retval == HFS_BTREE_CB_LEAF_STOP) {
                     is_done = 1;
                     break;
                 }
@@ -836,6 +838,9 @@ hfs_cat_traverse(HFS_INFO * hfs, const void *targ_data,
                 if (cur_node == 0) {
                     is_done = 1;
                 }
+                if (tsk_verbose)
+                    fprintf(stderr,
+                        "hfs_cat_traverse: moving forward to next leaf");
             }
         }
         else {
@@ -859,20 +864,27 @@ hfs_cat_get_record_offset_cb(HFS_INFO * hfs, int8_t level_type,
     TSK_OFF_T key_off, void *ptr)
 {
     const hfs_btree_key_cat *targ_key = (hfs_btree_key_cat *) targ_data;
+    if (tsk_verbose)
+        fprintf(stderr,
+            "hfs_cat_get_record_offset_cb: %s node want: %" PRIu32
+            " vs have: %" PRIu32 "\n",
+            (level_type == HFS_BT_NODE_TYPE_IDX) ? "Index" : "Leaf",
+            tsk_getu32(hfs->fs_info.endian, targ_key->parent_cnid),
+            tsk_getu32(hfs->fs_info.endian, cur_key->parent_cnid));
+
     if (level_type == HFS_BT_NODE_TYPE_IDX) {
-        if (hfs_cat_compare_keys(hfs, cur_key, targ_key) <= 0)
-            return HFS_BTREE_CB_GO;
+        int diff = hfs_cat_compare_keys(hfs, cur_key, targ_key);
+        if (diff < 0)
+            return HFS_BTREE_CB_IDX_LT;
         else
-            return HFS_BTREE_CB_STOP;
+            return HFS_BTREE_CB_IDX_EQGT;
     }
     else {
-        int diff;
-
-        diff = hfs_cat_compare_keys(hfs, cur_key, targ_key);
+        int diff = hfs_cat_compare_keys(hfs, cur_key, targ_key);
 
         // see if this record is for our file or if we passed the interesting entries
         if (diff < 0) {
-            return HFS_BTREE_CB_GO;
+            return HFS_BTREE_CB_LEAF_GO;
         }
         else if (diff == 0) {
             TSK_OFF_T *off = (TSK_OFF_T *) ptr;
@@ -880,7 +892,7 @@ hfs_cat_get_record_offset_cb(HFS_INFO * hfs, int8_t level_type,
                 key_off + 2 + tsk_getu16(hfs->fs_info.endian,
                 cur_key->key_len);
         }
-        return HFS_BTREE_CB_STOP;
+        return HFS_BTREE_CB_LEAF_STOP;
     }
 }
 
@@ -1086,6 +1098,11 @@ hfs_cat_file_lookup(HFS_INFO * hfs, TSK_INUM_T inum, HFS_ENTRY * entry)
     memset((char *) &key, 0, sizeof(hfs_btree_key_cat));
     cnid_to_array((uint32_t) inum, key.parent_cnid);
 
+    if (tsk_verbose)
+        tsk_fprintf(stderr,
+            "hfs_cat_file_lookup: Looking up thread record (%" PRIuINUM
+            ")\n", inum);
+
     /* look up the thread record */
     off = hfs_cat_get_record_offset(hfs, &key);
     if (off == 0) {
@@ -1119,6 +1136,11 @@ hfs_cat_file_lookup(HFS_INFO * hfs, TSK_INUM_T inum, HFS_ENTRY * entry)
         sizeof(key.parent_cnid));
     memcpy((char *) &key.name, (char *) &thread.name, sizeof(key.name));
 
+    if (tsk_verbose)
+        tsk_fprintf(stderr,
+            "hfs_cat_file_lookup: Looking up file record (parent: %"
+            PRIuINUM ")\n", tsk_getu32(fs->endian, key.parent_cnid));
+
     /* look up the record */
     off = hfs_cat_get_record_offset(hfs, &key);
     if (off == 0) {
diff --git a/tsk3/fs/hfs_dent.c b/tsk3/fs/hfs_dent.c
index 3c47724ea..cf3a594a9 100644
--- a/tsk3/fs/hfs_dent.c
+++ b/tsk3/fs/hfs_dent.c
@@ -178,21 +178,31 @@ hfs_dir_open_meta_cb(HFS_INFO * hfs, int8_t level_type,
     HFS_DIR_OPEN_META_INFO *info = (HFS_DIR_OPEN_META_INFO *) ptr;
     TSK_FS_INFO *fs = &hfs->fs_info;
 
-    // for both node types, continue for smaller values and stop for bigger
-    if (tsk_getu32(hfs->fs_info.endian, cur_key->parent_cnid) < *cnid_p)
-        return HFS_BTREE_CB_GO;
-    else if (tsk_getu32(hfs->fs_info.endian,
-            cur_key->parent_cnid) > *cnid_p)
-        return HFS_BTREE_CB_STOP;
+    if (tsk_verbose)
+        fprintf(stderr,
+            "hfs_dir_open_meta_cb: want %" PRIu32 " vs got %" PRIu32
+            " (%s node)\n", *cnid_p, tsk_getu32(hfs->fs_info.endian,
+                cur_key->parent_cnid),
+            (level_type == HFS_BT_NODE_TYPE_IDX) ? "Index" : "Leaf");
 
     if (level_type == HFS_BT_NODE_TYPE_IDX) {
-        // for equals, return "go"
-        return HFS_BTREE_CB_GO;
+        if (tsk_getu32(hfs->fs_info.endian,
+                cur_key->parent_cnid) < *cnid_p)
+            return HFS_BTREE_CB_IDX_LT;
+        else
+            return HFS_BTREE_CB_IDX_EQGT;
     }
     else {
         uint8_t *rec_buf = (uint8_t *) cur_key;
         uint16_t rec_type;
 
+        if (tsk_getu32(hfs->fs_info.endian,
+                cur_key->parent_cnid) < *cnid_p)
+            return HFS_BTREE_CB_LEAF_GO;
+        else if (tsk_getu32(hfs->fs_info.endian,
+                cur_key->parent_cnid) > *cnid_p)
+            return HFS_BTREE_CB_LEAF_STOP;
+
         size_t rec_off2 =
             2 + tsk_getu16(hfs->fs_info.endian, cur_key->key_len);
         // @@@ NEED TO REPLACE THIS SOMEHOW, but need to figure out the max length
@@ -271,7 +281,7 @@ hfs_dir_open_meta_cb(HFS_INFO * hfs, int8_t level_type,
         if (tsk_fs_dir_add(info->fs_dir, info->fs_name)) {
             return HFS_BTREE_CB_ERR;
         }
-        return HFS_BTREE_CB_GO;
+        return HFS_BTREE_CB_LEAF_GO;
     }
 }
 
diff --git a/tsk3/fs/tsk_hfs.h b/tsk3/fs/tsk_hfs.h
index 395e3aa7f..7a121b207 100644
--- a/tsk3/fs/tsk_hfs.h
+++ b/tsk3/fs/tsk_hfs.h
@@ -560,9 +560,11 @@ typedef uint8_t(*TSK_HFS_BTREE_CB) (HFS_INFO *, int8_t level_type,
     const void *targ_key, const hfs_btree_key_cat * cur_key,
     TSK_OFF_T key_off, void *);
 // return values for callback
-#define HFS_BTREE_CB_GO     0
-#define HFS_BTREE_CB_STOP   1
-#define HFS_BTREE_CB_ERR   2
+#define HFS_BTREE_CB_IDX_LT     1       // current key is less than target (keeps looking in node)
+#define HFS_BTREE_CB_IDX_EQGT   2       // current key is equal or greater than target (stops)
+#define HFS_BTREE_CB_LEAF_GO    3       // keep on going to the next key in the leaf node
+#define HFS_BTREE_CB_LEAF_STOP  4       // stop processing keys in the leaf node
+#define HFS_BTREE_CB_ERR        5
 
 extern uint8_t hfs_cat_traverse(HFS_INFO * hfs, const void *targ_data,
     TSK_HFS_BTREE_CB a_cb, void *ptr);
diff --git a/tsk3/img/img_io.c b/tsk3/img/img_io.c
index d3303a0ae..552b5ba03 100644
--- a/tsk3/img/img_io.c
+++ b/tsk3/img/img_io.c
@@ -61,9 +61,11 @@ tsk_img_read(TSK_IMG_INFO * a_img_info, TSK_OFF_T a_off,
                 (a_img_info->cache_off[i] + a_img_info->cache_len[i] >=
                     a_off + len2)) {
 
+                /*
                 if (tsk_verbose)
                     fprintf(stderr,
                         "tsk_img_read: Read found in cache %d\n", i);
+                 */
 
                 // We found it...
                 memcpy(a_buf,
@@ -101,10 +103,12 @@ tsk_img_read(TSK_IMG_INFO * a_img_info, TSK_OFF_T a_off,
         // round the offset down to a sector boundary
         a_img_info->cache_off[cache_next] = (a_off / 512) * 512;
 
+        /*
         if (tsk_verbose)
             fprintf(stderr,
                 "tsk_img_read: Loading data into cache %d (%" PRIuOFF
                 ")\n", cache_next, a_img_info->cache_off[cache_next]);
+         */
 
         // figure out the length to read into the cache
         rlen = TSK_IMG_INFO_CACHE_LEN;
-- 
GitLab