OSDN Git Service

Reduce the sizes of name buffers.
authorrelan <relan@users.noreply.github.com>
Mon, 26 Dec 2016 06:41:57 +0000 (09:41 +0300)
committerrelan <relan@users.noreply.github.com>
Mon, 26 Dec 2016 07:01:18 +0000 (10:01 +0300)
EXFAT_NAME_MAX is the number of 16-bit code units, not Unicode
characters. When converting to UTF-8, 3 bytes are enough to keep any
Unicode character encoded by a 16-bit code unit.

fsck/main.c
fuse/main.c
libexfat/exfat.h
libexfat/node.c
libexfat/utils.c

index c08b956..be9c683 100644 (file)
@@ -41,7 +41,7 @@ static int nodeck(struct exfat* ef, struct exfat_node* node)
        {
                if (CLUSTER_INVALID(c))
                {
-                       char name[UTF8_BYTES(EXFAT_NAME_MAX) + 1];
+                       char name[EXFAT_UTF8_NAME_BUFFER_MAX];
 
                        exfat_get_name(node, name);
                        exfat_error("file '%s' has invalid cluster 0x%x", name, c);
@@ -50,7 +50,7 @@ static int nodeck(struct exfat* ef, struct exfat_node* node)
                }
                if (BMAP_GET(ef->cmap.chunk, c - EXFAT_FIRST_DATA_CLUSTER) == 0)
                {
-                       char name[UTF8_BYTES(EXFAT_NAME_MAX) + 1];
+                       char name[EXFAT_UTF8_NAME_BUFFER_MAX];
 
                        exfat_get_name(node, name);
                        exfat_error("cluster 0x%x of file '%s' is not allocated", c, name);
@@ -81,7 +81,7 @@ static void dirck(struct exfat* ef, const char* path)
        }
 
        path_length = strlen(path);
-       entry_path = malloc(path_length + 1 + UTF8_BYTES(EXFAT_NAME_MAX) + 1);
+       entry_path = malloc(path_length + 1 + EXFAT_UTF8_NAME_BUFFER_MAX);
        if (entry_path == NULL)
        {
                exfat_put_node(ef, parent);
index 8cc2eb3..29545c9 100644 (file)
@@ -104,7 +104,7 @@ static int fuse_exfat_readdir(const char* path, void* buffer,
        struct exfat_node* node;
        struct exfat_iterator it;
        int rc;
-       char name[UTF8_BYTES(EXFAT_NAME_MAX) + 1];
+       char name[EXFAT_UTF8_NAME_BUFFER_MAX];
 
        exfat_debug("[%s] %s", __func__, path);
 
index 1748e29..a84306e 100644 (file)
 #include <sys/types.h>
 
 #define EXFAT_NAME_MAX 255
+/* UTF-16 encodes code points up to U+FFFF as single 16-bit code units.
+   UTF-8 uses up to 3 bytes (i.e. 8-bit code units) to encode code points
+   up to U+FFFF. One additional character is for null terminator. */
+#define EXFAT_UTF8_NAME_BUFFER_MAX (EXFAT_NAME_MAX * 3 + 1)
+#define EXFAT_UTF8_ENAME_BUFFER_MAX (EXFAT_ENAME_MAX * 3 + 1)
+
 #define EXFAT_ATTRIB_CONTIGUOUS 0x10000
 #define EXFAT_ATTRIB_CACHED     0x20000
 #define EXFAT_ATTRIB_DIRTY      0x40000
@@ -49,7 +55,6 @@
 #define MAX(a, b) ((a) > (b) ? (a) : (b))
 #define DIV_ROUND_UP(x, d) (((x) + (d) - 1) / (d))
 #define ROUND_UP(x, d) (DIV_ROUND_UP(x, d) * (d))
-#define UTF8_BYTES(c) ((c) * 6) /* UTF-8 character can occupy up to 6 bytes */
 
 #define BMAP_SIZE(count) (ROUND_UP(count, sizeof(bitmap_t) * 8) / 8)
 #define BMAP_BLOCK(index) ((index) / sizeof(bitmap_t) / 8)
@@ -108,7 +113,7 @@ struct exfat
                bool dirty;
        }
        cmap;
-       char label[UTF8_BYTES(EXFAT_ENAME_MAX) + 1];
+       char label[EXFAT_UTF8_ENAME_BUFFER_MAX];
        void* zero_cluster;
        int dmask, fmask;
        uid_t uid;
@@ -178,7 +183,7 @@ int exfat_find_used_sectors(const struct exfat* ef, off_t* a, off_t* b);
 void exfat_stat(const struct exfat* ef, const struct exfat_node* node,
                struct stat* stbuf);
 void exfat_get_name(const struct exfat_node* node,
-               char buffer[UTF8_BYTES(EXFAT_NAME_MAX) + 1]);
+               char buffer[EXFAT_UTF8_NAME_BUFFER_MAX]);
 uint16_t exfat_start_checksum(const struct exfat_entry_meta1* entry);
 uint16_t exfat_add_checksum(const void* entry, uint16_t sum);
 le16_t exfat_calc_checksum(const struct exfat_entry_meta1* meta1,
index 473a009..52123fd 100644 (file)
@@ -43,7 +43,7 @@ struct exfat_node* exfat_get_node(struct exfat_node* node)
 
 void exfat_put_node(struct exfat* ef, struct exfat_node* node)
 {
-       char buffer[UTF8_BYTES(EXFAT_NAME_MAX) + 1];
+       char buffer[EXFAT_UTF8_NAME_BUFFER_MAX];
 
        --node->references;
        if (node->references < 0)
@@ -94,7 +94,7 @@ static off_t co2o(struct exfat* ef, cluster_t cluster, off_t offset)
 static int opendir(struct exfat* ef, const struct exfat_node* dir,
                struct iterator* it)
 {
-       char buffer[UTF8_BYTES(EXFAT_NAME_MAX) + 1];
+       char buffer[EXFAT_UTF8_NAME_BUFFER_MAX];
 
        if (!(dir->flags & EXFAT_ATTRIB_DIR))
        {
@@ -208,7 +208,7 @@ static const struct exfat_entry* get_entry_ptr(const struct exfat* ef,
 static bool check_node(const struct exfat_node* node, uint16_t actual_checksum,
                uint16_t reference_checksum, uint64_t valid_size, int cluster_size)
 {
-       char buffer[UTF8_BYTES(EXFAT_NAME_MAX) + 1];
+       char buffer[EXFAT_UTF8_NAME_BUFFER_MAX];
        bool ret = true;
 
        /*
@@ -627,7 +627,7 @@ static void tree_detach(struct exfat_node* node)
 
 static void reset_cache(struct exfat* ef, struct exfat_node* node)
 {
-       char buffer[UTF8_BYTES(EXFAT_NAME_MAX) + 1];
+       char buffer[EXFAT_UTF8_NAME_BUFFER_MAX];
 
        while (node->child)
        {
index c939004..fd304b2 100644 (file)
@@ -47,9 +47,9 @@ void exfat_stat(const struct exfat* ef, const struct exfat_node* node,
 }
 
 void exfat_get_name(const struct exfat_node* node,
-               char buffer[UTF8_BYTES(EXFAT_NAME_MAX) + 1])
+               char buffer[EXFAT_UTF8_NAME_BUFFER_MAX])
 {
-       if (utf16_to_utf8(buffer, node->name, UTF8_BYTES(EXFAT_NAME_MAX) + 1,
+       if (utf16_to_utf8(buffer, node->name, EXFAT_UTF8_NAME_BUFFER_MAX,
                                EXFAT_NAME_MAX) != 0)
                exfat_bug("failed to convert name to UTF-8");
 }