OSDN Git Service

Fix clusters bitmap size.
[android-x86/external-exfat.git] / libexfat / node.c
index e50bb69..b544bd9 100644 (file)
@@ -209,6 +209,8 @@ static bool check_node(const struct exfat* ef, struct exfat_node* node,
                const struct exfat_entry_meta2* meta2)
 {
        int cluster_size = CLUSTER_SIZE(*ef->sb);
+       uint64_t clusters_heap_size =
+                       (uint64_t) le32_to_cpu(ef->sb->cluster_count) * cluster_size;
        char buffer[EXFAT_UTF8_NAME_BUFFER_MAX];
        bool ret = true;
 
@@ -260,6 +262,15 @@ static bool check_node(const struct exfat* ef, struct exfat_node* node,
                ret = false;
        }
 
+       /* File or directory cannot be larger than clusters heap. */
+       if (node->size > clusters_heap_size)
+       {
+               exfat_get_name(node, buffer);
+               exfat_error("'%s' is larger than clusters heap: %"PRIu64" > %"PRIu64,
+                               buffer, node->size, clusters_heap_size);
+               ret = false;
+       }
+
        /* Empty file or directory must be marked as non-contiguous. */
        if (node->size == 0 && node->is_contiguous)
        {
@@ -281,8 +292,8 @@ static bool check_node(const struct exfat* ef, struct exfat_node* node,
        return ret;
 }
 
-static int parse_file_entries(struct exfat* ef, struct exfat_node* parent,
-               struct exfat_node* node, const struct exfat_entry* entries, int n)
+static int parse_file_entries(struct exfat* ef, struct exfat_node* node,
+               const struct exfat_entry* entries, int n)
 {
        const struct exfat_entry_meta1* meta1;
        const struct exfat_entry_meta2* meta2;
@@ -337,7 +348,7 @@ static int parse_file_entry(struct exfat* ef, struct exfat_node* parent,
                return -ENOMEM;
        (*node)->entry_offset = *offset;
 
-       rc = parse_file_entries(ef, parent, *node, entries, n);
+       rc = parse_file_entries(ef, *node, entries, n);
        if (rc != 0)
        {
                free(*node);
@@ -458,8 +469,7 @@ static int readdir(struct exfat* ef, struct exfat_node* parent,
                                                ef->cmap.start_cluster);
                                return -EIO;
                        }
-                       ef->cmap.size = le32_to_cpu(ef->sb->cluster_count) -
-                               EXFAT_FIRST_DATA_CLUSTER;
+                       ef->cmap.size = le32_to_cpu(ef->sb->cluster_count);
                        if (le64_to_cpu(bitmap->size) < DIV_ROUND_UP(ef->cmap.size, 8))
                        {
                                exfat_error("invalid clusters bitmap size: %"PRIu64
@@ -865,7 +875,7 @@ static int find_slot(struct exfat* ef, struct exfat_node* dir,
 }
 
 static int commit_entry(struct exfat* ef, struct exfat_node* dir,
-               const le16_t* name, cluster_t cluster, off_t offset, uint16_t attrib)
+               const le16_t* name, off_t offset, uint16_t attrib)
 {
        struct exfat_node* node;
        const size_t name_length = utf16_length(name);
@@ -925,7 +935,6 @@ static int create(struct exfat* ef, const char* path, uint16_t attrib)
 {
        struct exfat_node* dir;
        struct exfat_node* existing;
-       cluster_t cluster = EXFAT_CLUSTER_BAD;
        off_t offset = -1;
        le16_t name[EXFAT_NAME_MAX + 1];
        int rc;
@@ -947,7 +956,7 @@ static int create(struct exfat* ef, const char* path, uint16_t attrib)
                exfat_put_node(ef, dir);
                return rc;
        }
-       rc = commit_entry(ef, dir, name, cluster, offset, attrib);
+       rc = commit_entry(ef, dir, name, offset, attrib);
        if (rc != 0)
        {
                exfat_put_node(ef, dir);
@@ -995,8 +1004,7 @@ int exfat_mkdir(struct exfat* ef, const char* path)
 }
 
 static int rename_entry(struct exfat* ef, struct exfat_node* dir,
-               struct exfat_node* node, const le16_t* name, cluster_t new_cluster,
-               off_t new_offset)
+               struct exfat_node* node, const le16_t* name, off_t new_offset)
 {
        const size_t name_length = utf16_length(name);
        const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX);
@@ -1048,7 +1056,6 @@ int exfat_rename(struct exfat* ef, const char* old_path, const char* new_path)
        struct exfat_node* node;
        struct exfat_node* existing;
        struct exfat_node* dir;
-       cluster_t cluster = EXFAT_CLUSTER_BAD;
        off_t offset = -1;
        le16_t name[EXFAT_NAME_MAX + 1];
        int rc;
@@ -1129,7 +1136,7 @@ int exfat_rename(struct exfat* ef, const char* old_path, const char* new_path)
                exfat_put_node(ef, node);
                return rc;
        }
-       rc = rename_entry(ef, dir, node, name, cluster, offset);
+       rc = rename_entry(ef, dir, node, name, offset);
        if (rc != 0)
        {
                exfat_put_node(ef, dir);