]> git.sven.stormbind.net Git - sven/exfat-utils.git/blobdiff - libexfat/utf.c
releasing package exfat-utils version 1.3.0-2
[sven/exfat-utils.git] / libexfat / utf.c
index 3f0dc1971ba04368a414112c3eec81bb1c9d00d4..0d0018c0c2eb9f98b2d0b11e2ad651b607d97c9c 100644 (file)
@@ -2,11 +2,12 @@
        utf.c (13.09.09)
        exFAT file system implementation library.
 
        utf.c (13.09.09)
        exFAT file system implementation library.
 
-       Copyright (C) 2009, 2010  Andrew Nayenko
+       Free exFAT implementation.
+       Copyright (C) 2010-2018  Andrew Nayenko
 
 
-       This program is free software: you can redistribute it and/or modify
+       This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        it under the terms of the GNU General Public License as published by
-       the Free Software Foundation, either version 3 of the License, or
+       the Free Software Foundation, either version 2 of the License, or
        (at your option) any later version.
 
        This program is distributed in the hope that it will be useful,
        (at your option) any later version.
 
        This program is distributed in the hope that it will be useful,
@@ -14,8 +15,9 @@
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.
 
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.
 
-       You should have received a copy of the GNU General Public License
-       along with this program.  If not, see <http://www.gnu.org/licenses/>.
+       You should have received a copy of the GNU General Public License along
+       with this program; if not, write to the Free Software Foundation, Inc.,
+       51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
 #include "exfat.h"
 */
 
 #include "exfat.h"
@@ -89,6 +91,7 @@ static const le16_t* utf16_to_wchar(const le16_t* input, wchar_t* wc,
                        return NULL;
                *wc = ((wchar_t) (le16_to_cpu(input[0]) & 0x3ff) << 10);
                *wc |= (le16_to_cpu(input[1]) & 0x3ff);
                        return NULL;
                *wc = ((wchar_t) (le16_to_cpu(input[0]) & 0x3ff) << 10);
                *wc |= (le16_to_cpu(input[1]) & 0x3ff);
+               *wc += 0x10000;
                return input + 2;
        }
        else
                return input + 2;
        }
        else
@@ -105,7 +108,7 @@ int utf16_to_utf8(char* output, const le16_t* input, size_t outsize,
        char* outp = output;
        wchar_t wc;
 
        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)
        {
                inp = utf16_to_wchar(inp, &wc, insize - (inp - input));
                if (inp == NULL)
@@ -119,6 +122,13 @@ int utf16_to_utf8(char* output, const le16_t* input, size_t outsize,
                        exfat_error("name is too long");
                        return -ENAMETOOLONG;
                }
                        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;
        }
        *outp = '\0';
        return 0;
@@ -186,6 +196,7 @@ static le16_t* wchar_to_utf16(le16_t* output, wchar_t wc, size_t outsize)
        }
        if (outsize < 2)
                return NULL;
        }
        if (outsize < 2)
                return NULL;
+       wc -= 0x10000;
        output[0] = cpu_to_le16(0xd800 | ((wc >> 10) & 0x3ff));
        output[1] = cpu_to_le16(0xdc00 | (wc & 0x3ff));
        return output + 2;
        output[0] = cpu_to_le16(0xd800 | ((wc >> 10) & 0x3ff));
        output[1] = cpu_to_le16(0xdc00 | (wc & 0x3ff));
        return output + 2;
@@ -198,7 +209,7 @@ int utf8_to_utf16(le16_t* output, const char* input, size_t outsize,
        le16_t* outp = output;
        wchar_t wc;
 
        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)
        {
                inp = utf8_to_wchar(inp, &wc, insize - (inp - input));
                if (inp == NULL)
@@ -212,6 +223,13 @@ int utf8_to_utf16(le16_t* output, const char* input, size_t outsize,
                        exfat_error("name is too long");
                        return -ENAMETOOLONG;
                }
                        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;
        }
        *outp = cpu_to_le16(0);
        return 0;