OSDN Git Service

Change output buffer size semantics for UTF functions.
authorrelan <relan@users.noreply.github.com>
Tue, 20 Dec 2016 08:26:52 +0000 (11:26 +0300)
committerrelan <relan@users.noreply.github.com>
Mon, 26 Dec 2016 07:01:18 +0000 (10:01 +0300)
Make them consistent with other string functions: now output buffer size
includes potential null terminator, i.e. this is total size. This change
also means that if output buffer isn't large enough it can be left
unterminated (indicated by the -ENAMETOOLONG return value).

libexfat/exfat.h
libexfat/lookup.c
libexfat/node.c
libexfat/utf.c
libexfat/utils.c
mkfs/main.c

index a93484c..1748e29 100644 (file)
@@ -178,7 +178,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)]);
+               char buffer[UTF8_BYTES(EXFAT_NAME_MAX) + 1]);
 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 30b6410..feb5a22 100644 (file)
@@ -86,7 +86,7 @@ static int lookup_name(struct exfat* ef, struct exfat_node* parent,
 
        *node = NULL;
 
-       rc = utf8_to_utf16(buffer, name, EXFAT_NAME_MAX, n);
+       rc = utf8_to_utf16(buffer, name, EXFAT_NAME_MAX + 1, n);
        if (rc != 0)
                return rc;
 
@@ -194,7 +194,7 @@ int exfat_split(struct exfat* ef, struct exfat_node** parent,
                                exfat_put_node(ef, *parent);
                                return -ENOENT;
                        }
-                       rc = utf8_to_utf16(name, p, EXFAT_NAME_MAX, n);
+                       rc = utf8_to_utf16(name, p, EXFAT_NAME_MAX + 1, n);
                        if (rc != 0)
                        {
                                exfat_put_node(ef, *parent);
index a413fa2..473a009 100644 (file)
@@ -523,7 +523,7 @@ static int readdir(struct exfat* ef, const struct exfat_node* parent,
                                goto error;
                        }
                        if (utf16_to_utf8(ef->label, label->name,
-                                               sizeof(ef->label) - 1, EXFAT_ENAME_MAX) != 0)
+                                               sizeof(ef->label), EXFAT_ENAME_MAX) != 0)
                                goto error;
                        break;
 
@@ -1303,7 +1303,7 @@ int exfat_set_label(struct exfat* ef, const char* label)
        struct exfat_entry_label entry;
 
        memset(label_utf16, 0, sizeof(label_utf16));
-       rc = utf8_to_utf16(label_utf16, label, EXFAT_ENAME_MAX, strlen(label));
+       rc = utf8_to_utf16(label_utf16, label, EXFAT_ENAME_MAX + 1, strlen(label));
        if (rc != 0)
                return rc;
 
index 98ae52d..f410eb6 100644 (file)
@@ -108,7 +108,7 @@ int utf16_to_utf8(char* output, const le16_t* input, size_t outsize,
        char* outp = output;
        wchar_t wc;
 
-       while (inp - input < insize && le16_to_cpu(*inp))
+       while (inp - input < insize)
        {
                inp = utf16_to_wchar(inp, &wc, insize - (inp - input));
                if (inp == NULL)
@@ -122,6 +122,13 @@ int utf16_to_utf8(char* output, const le16_t* input, size_t outsize,
                        exfat_error("name is too long");
                        return -ENAMETOOLONG;
                }
+               if (wc == 0)
+                       return 0;
+       }
+       if (outp - output >= outsize)
+       {
+               exfat_error("name is too long");
+               return -ENAMETOOLONG;
        }
        *outp = '\0';
        return 0;
@@ -202,7 +209,7 @@ int utf8_to_utf16(le16_t* output, const char* input, size_t outsize,
        le16_t* outp = output;
        wchar_t wc;
 
-       while (inp - input < insize && *inp)
+       while (inp - input < insize)
        {
                inp = utf8_to_wchar(inp, &wc, insize - (inp - input));
                if (inp == NULL)
@@ -216,6 +223,13 @@ int utf8_to_utf16(le16_t* output, const char* input, size_t outsize,
                        exfat_error("name is too long");
                        return -ENAMETOOLONG;
                }
+               if (wc == 0)
+                       break;
+       }
+       if (outp - output >= outsize)
+       {
+               exfat_error("name is too long");
+               return -ENAMETOOLONG;
        }
        *outp = cpu_to_le16(0);
        return 0;
index 3e08431..c939004 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)])
+               char buffer[UTF8_BYTES(EXFAT_NAME_MAX) + 1])
 {
-       if (utf16_to_utf8(buffer, node->name, UTF8_BYTES(EXFAT_NAME_MAX),
+       if (utf16_to_utf8(buffer, node->name, UTF8_BYTES(EXFAT_NAME_MAX) + 1,
                                EXFAT_NAME_MAX) != 0)
                exfat_bug("failed to convert name to UTF-8");
 }
index a164eeb..78cba24 100644 (file)
@@ -136,7 +136,7 @@ static int setup_volume_label(le16_t label[EXFAT_ENAME_MAX + 1], const char* s)
        memset(label, 0, (EXFAT_ENAME_MAX + 1) * sizeof(le16_t));
        if (s == NULL)
                return 0;
-       return utf8_to_utf16(label, s, EXFAT_ENAME_MAX, strlen(s));
+       return utf8_to_utf16(label, s, EXFAT_ENAME_MAX + 1, strlen(s));
 }
 
 static uint32_t setup_volume_serial(uint32_t user_defined)