Merge branch 'for-linus-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/mason...
[deliverable/linux.git] / fs / udf / unicode.c
index ab478e62baaebf20c9a9cadc2e16baefba2527dd..e788a05aab83670de6be03dc48eb519e2d2ae5d9 100644 (file)
@@ -128,11 +128,15 @@ int udf_CS0toUTF8(struct ustr *utf_o, const struct ustr *ocu_i)
                if (c < 0x80U)
                        utf_o->u_name[utf_o->u_len++] = (uint8_t)c;
                else if (c < 0x800U) {
+                       if (utf_o->u_len > (UDF_NAME_LEN - 4))
+                               break;
                        utf_o->u_name[utf_o->u_len++] =
                                                (uint8_t)(0xc0 | (c >> 6));
                        utf_o->u_name[utf_o->u_len++] =
                                                (uint8_t)(0x80 | (c & 0x3f));
                } else {
+                       if (utf_o->u_len > (UDF_NAME_LEN - 5))
+                               break;
                        utf_o->u_name[utf_o->u_len++] =
                                                (uint8_t)(0xe0 | (c >> 12));
                        utf_o->u_name[utf_o->u_len++] =
@@ -173,17 +177,22 @@ int udf_CS0toUTF8(struct ustr *utf_o, const struct ustr *ocu_i)
 static int udf_UTF8toCS0(dstring *ocu, struct ustr *utf, int length)
 {
        unsigned c, i, max_val, utf_char;
-       int utf_cnt, u_len;
+       int utf_cnt, u_len, u_ch;
 
        memset(ocu, 0, sizeof(dstring) * length);
        ocu[0] = 8;
        max_val = 0xffU;
+       u_ch = 1;
 
 try_again:
        u_len = 0U;
        utf_char = 0U;
        utf_cnt = 0U;
        for (i = 0U; i < utf->u_len; i++) {
+               /* Name didn't fit? */
+               if (u_len + 1 + u_ch >= length)
+                       return 0;
+
                c = (uint8_t)utf->u_name[i];
 
                /* Complete a multi-byte UTF-8 character */
@@ -225,6 +234,7 @@ try_again:
                        if (max_val == 0xffU) {
                                max_val = 0xffffU;
                                ocu[0] = (uint8_t)0x10U;
+                               u_ch = 2;
                                goto try_again;
                        }
                        goto error_out;
@@ -277,7 +287,7 @@ static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o,
                        c = (c << 8) | ocu[i++];
 
                len = nls->uni2char(c, &utf_o->u_name[utf_o->u_len],
-                                   UDF_NAME_LEN - utf_o->u_len);
+                                   UDF_NAME_LEN - 2 - utf_o->u_len);
                /* Valid character? */
                if (len >= 0)
                        utf_o->u_len += len;
@@ -295,15 +305,19 @@ static int udf_NLStoCS0(struct nls_table *nls, dstring *ocu, struct ustr *uni,
        int len;
        unsigned i, max_val;
        uint16_t uni_char;
-       int u_len;
+       int u_len, u_ch;
 
        memset(ocu, 0, sizeof(dstring) * length);
        ocu[0] = 8;
        max_val = 0xffU;
+       u_ch = 1;
 
 try_again:
        u_len = 0U;
        for (i = 0U; i < uni->u_len; i++) {
+               /* Name didn't fit? */
+               if (u_len + 1 + u_ch >= length)
+                       return 0;
                len = nls->char2uni(&uni->u_name[i], uni->u_len - i, &uni_char);
                if (!len)
                        continue;
@@ -316,6 +330,7 @@ try_again:
                if (uni_char > max_val) {
                        max_val = 0xffffU;
                        ocu[0] = (uint8_t)0x10U;
+                       u_ch = 2;
                        goto try_again;
                }
 
This page took 0.026332 seconds and 5 git commands to generate.