aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf/unicode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/udf/unicode.c')
-rw-r--r--fs/udf/unicode.c62
1 files changed, 27 insertions, 35 deletions
diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c
index e533b11703bf..9fdf8c93c58e 100644
--- a/fs/udf/unicode.c
+++ b/fs/udf/unicode.c
@@ -23,7 +23,7 @@
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/string.h> /* for memset */ 24#include <linux/string.h> /* for memset */
25#include <linux/nls.h> 25#include <linux/nls.h>
26#include <linux/udf_fs.h> 26#include <linux/crc-itu-t.h>
27 27
28#include "udf_sb.h" 28#include "udf_sb.h"
29 29
@@ -49,14 +49,16 @@ int udf_build_ustr(struct ustr *dest, dstring *ptr, int size)
49{ 49{
50 int usesize; 50 int usesize;
51 51
52 if ((!dest) || (!ptr) || (!size)) 52 if (!dest || !ptr || !size)
53 return -1; 53 return -1;
54 BUG_ON(size < 2);
54 55
55 memset(dest, 0, sizeof(struct ustr)); 56 usesize = min_t(size_t, ptr[size - 1], sizeof(dest->u_name));
56 usesize = (size > UDF_NAME_LEN) ? UDF_NAME_LEN : size; 57 usesize = min(usesize, size - 2);
57 dest->u_cmpID = ptr[0]; 58 dest->u_cmpID = ptr[0];
58 dest->u_len = ptr[size - 1]; 59 dest->u_len = usesize;
59 memcpy(dest->u_name, ptr + 1, usesize - 1); 60 memcpy(dest->u_name, ptr + 1, usesize);
61 memset(dest->u_name + usesize, 0, sizeof(dest->u_name) - usesize);
60 62
61 return 0; 63 return 0;
62} 64}
@@ -83,9 +85,6 @@ static int udf_build_ustr_exact(struct ustr *dest, dstring *ptr, int exactsize)
83 * PURPOSE 85 * PURPOSE
84 * Convert OSTA Compressed Unicode to the UTF-8 equivalent. 86 * Convert OSTA Compressed Unicode to the UTF-8 equivalent.
85 * 87 *
86 * DESCRIPTION
87 * This routine is only called by udf_filldir().
88 *
89 * PRE-CONDITIONS 88 * PRE-CONDITIONS
90 * utf Pointer to UTF-8 output buffer. 89 * utf Pointer to UTF-8 output buffer.
91 * ocu Pointer to OSTA Compressed Unicode input buffer 90 * ocu Pointer to OSTA Compressed Unicode input buffer
@@ -99,43 +98,39 @@ static int udf_build_ustr_exact(struct ustr *dest, dstring *ptr, int exactsize)
99 * November 12, 1997 - Andrew E. Mileski 98 * November 12, 1997 - Andrew E. Mileski
100 * Written, tested, and released. 99 * Written, tested, and released.
101 */ 100 */
102int udf_CS0toUTF8(struct ustr *utf_o, struct ustr *ocu_i) 101int udf_CS0toUTF8(struct ustr *utf_o, const struct ustr *ocu_i)
103{ 102{
104 uint8_t *ocu; 103 const uint8_t *ocu;
105 uint32_t c;
106 uint8_t cmp_id, ocu_len; 104 uint8_t cmp_id, ocu_len;
107 int i; 105 int i;
108 106
109 ocu = ocu_i->u_name;
110
111 ocu_len = ocu_i->u_len; 107 ocu_len = ocu_i->u_len;
112 cmp_id = ocu_i->u_cmpID;
113 utf_o->u_len = 0;
114
115 if (ocu_len == 0) { 108 if (ocu_len == 0) {
116 memset(utf_o, 0, sizeof(struct ustr)); 109 memset(utf_o, 0, sizeof(struct ustr));
117 utf_o->u_cmpID = 0;
118 utf_o->u_len = 0;
119 return 0; 110 return 0;
120 } 111 }
121 112
122 if ((cmp_id != 8) && (cmp_id != 16)) { 113 cmp_id = ocu_i->u_cmpID;
114 if (cmp_id != 8 && cmp_id != 16) {
115 memset(utf_o, 0, sizeof(struct ustr));
123 printk(KERN_ERR "udf: unknown compression code (%d) stri=%s\n", 116 printk(KERN_ERR "udf: unknown compression code (%d) stri=%s\n",
124 cmp_id, ocu_i->u_name); 117 cmp_id, ocu_i->u_name);
125 return 0; 118 return 0;
126 } 119 }
127 120
121 ocu = ocu_i->u_name;
122 utf_o->u_len = 0;
128 for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN - 3));) { 123 for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN - 3));) {
129 124
130 /* Expand OSTA compressed Unicode to Unicode */ 125 /* Expand OSTA compressed Unicode to Unicode */
131 c = ocu[i++]; 126 uint32_t c = ocu[i++];
132 if (cmp_id == 16) 127 if (cmp_id == 16)
133 c = (c << 8) | ocu[i++]; 128 c = (c << 8) | ocu[i++];
134 129
135 /* Compress Unicode to UTF-8 */ 130 /* Compress Unicode to UTF-8 */
136 if (c < 0x80U) { 131 if (c < 0x80U)
137 utf_o->u_name[utf_o->u_len++] = (uint8_t)c; 132 utf_o->u_name[utf_o->u_len++] = (uint8_t)c;
138 } else if (c < 0x800U) { 133 else if (c < 0x800U) {
139 utf_o->u_name[utf_o->u_len++] = 134 utf_o->u_name[utf_o->u_len++] =
140 (uint8_t)(0xc0 | (c >> 6)); 135 (uint8_t)(0xc0 | (c >> 6));
141 utf_o->u_name[utf_o->u_len++] = 136 utf_o->u_name[utf_o->u_len++] =
@@ -255,35 +250,32 @@ error_out:
255} 250}
256 251
257static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, 252static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o,
258 struct ustr *ocu_i) 253 const struct ustr *ocu_i)
259{ 254{
260 uint8_t *ocu; 255 const uint8_t *ocu;
261 uint32_t c;
262 uint8_t cmp_id, ocu_len; 256 uint8_t cmp_id, ocu_len;
263 int i; 257 int i;
264 258
265 ocu = ocu_i->u_name;
266 259
267 ocu_len = ocu_i->u_len; 260 ocu_len = ocu_i->u_len;
268 cmp_id = ocu_i->u_cmpID;
269 utf_o->u_len = 0;
270
271 if (ocu_len == 0) { 261 if (ocu_len == 0) {
272 memset(utf_o, 0, sizeof(struct ustr)); 262 memset(utf_o, 0, sizeof(struct ustr));
273 utf_o->u_cmpID = 0;
274 utf_o->u_len = 0;
275 return 0; 263 return 0;
276 } 264 }
277 265
278 if ((cmp_id != 8) && (cmp_id != 16)) { 266 cmp_id = ocu_i->u_cmpID;
267 if (cmp_id != 8 && cmp_id != 16) {
268 memset(utf_o, 0, sizeof(struct ustr));
279 printk(KERN_ERR "udf: unknown compression code (%d) stri=%s\n", 269 printk(KERN_ERR "udf: unknown compression code (%d) stri=%s\n",
280 cmp_id, ocu_i->u_name); 270 cmp_id, ocu_i->u_name);
281 return 0; 271 return 0;
282 } 272 }
283 273
274 ocu = ocu_i->u_name;
275 utf_o->u_len = 0;
284 for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN - 3));) { 276 for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN - 3));) {
285 /* Expand OSTA compressed Unicode to Unicode */ 277 /* Expand OSTA compressed Unicode to Unicode */
286 c = ocu[i++]; 278 uint32_t c = ocu[i++];
287 if (cmp_id == 16) 279 if (cmp_id == 16)
288 c = (c << 8) | ocu[i++]; 280 c = (c << 8) | ocu[i++];
289 281
@@ -463,7 +455,7 @@ static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName,
463 } else if (newIndex > 250) 455 } else if (newIndex > 250)
464 newIndex = 250; 456 newIndex = 250;
465 newName[newIndex++] = CRC_MARK; 457 newName[newIndex++] = CRC_MARK;
466 valueCRC = udf_crc(fidName, fidNameLen, 0); 458 valueCRC = crc_itu_t(0, fidName, fidNameLen);
467 newName[newIndex++] = hexChar[(valueCRC & 0xf000) >> 12]; 459 newName[newIndex++] = hexChar[(valueCRC & 0xf000) >> 12];
468 newName[newIndex++] = hexChar[(valueCRC & 0x0f00) >> 8]; 460 newName[newIndex++] = hexChar[(valueCRC & 0x0f00) >> 8];
469 newName[newIndex++] = hexChar[(valueCRC & 0x00f0) >> 4]; 461 newName[newIndex++] = hexChar[(valueCRC & 0x00f0) >> 4];