23 #include <linux/kernel.h>
24 #include <linux/string.h>
27 #include <linux/slab.h>
35 if ((!dest) || (!src) || (!strlen) || (strlen >
UDF_NAME_LEN - 2))
53 if (!dest || !ptr || !size)
57 usesize =
min_t(
size_t, ptr[size - 1],
sizeof(dest->
u_name));
58 usesize =
min(usesize, size - 2);
60 dest->
u_len = usesize;
70 static int udf_build_ustr_exact(
struct ustr *dest,
dstring *
ptr,
int exactsize)
72 if ((!dest) || (!ptr) || (!exactsize))
77 dest->
u_len = exactsize - 1;
108 ocu_len = ocu_i->
u_len;
115 if (cmp_id != 8 && cmp_id != 16) {
117 pr_err(
"unknown compression code (%d) stri=%s\n",
129 c = (c << 8) | ocu[i++];
134 else if (c < 0x800U) {
179 unsigned c,
i, max_val, utf_char;
190 for (i = 0
U; i < utf->
u_len; i++) {
195 utf_char = (utf_char << 6) | (c & 0x3fU);
202 if ((c & 0xe0U) == 0xc0
U) {
203 utf_char = c & 0x1f
U;
205 }
else if ((c & 0xf0U) == 0xe0
U) {
206 utf_char = c & 0x0f
U;
208 }
else if ((c & 0xf8U) == 0xf0
U) {
209 utf_char = c & 0x07
U;
211 }
else if ((c & 0xfcU) == 0xf8
U) {
212 utf_char = c & 0x03
U;
214 }
else if ((c & 0xfeU) == 0xfc
U) {
215 utf_char = c & 0x01
U;
228 if (utf_char > max_val) {
229 if (max_val == 0xffU) {
237 if (max_val == 0xffffU)
248 ocu[length - 1] = (
uint8_t)u_len + 1;
253 static int udf_CS0toNLS(
struct nls_table *nls,
struct ustr *utf_o,
254 const struct ustr *ocu_i)
261 ocu_len = ocu_i->
u_len;
268 if (cmp_id != 8 && cmp_id != 16) {
270 pr_err(
"unknown compression code (%d) stri=%s\n",
281 c = (c << 8) | ocu[i++];
310 for (i = 0
U; i < uni->
u_len; i++) {
320 if (uni_char > max_val) {
326 if (max_val == 0xffffU)
332 ocu[length - 1] = (
uint8_t)u_len + 1;
350 if (udf_build_ustr_exact(unifilename, sname, flen))
355 udf_debug(
"Failed in udf_get_filename: sname = %s\n",
360 if (!udf_CS0toNLS(UDF_SB(sb)->s_nls_map, filename,
362 udf_debug(
"Failed in udf_get_filename: sname = %s\n",
369 len = udf_translate_to_linux(dname, filename->
u_name, filename->
u_len,
381 struct ustr unifilename;
384 if (!udf_char_to_ustr(&unifilename, sname, flen))
388 namelen = udf_UTF8toCS0(dname, &unifilename,
UDF_NAME_LEN);
392 namelen = udf_NLStoCS0(UDF_SB(sb)->s_nls_map, dname,
402 #define ILLEGAL_CHAR_MARK '_'
407 static int udf_translate_to_linux(
uint8_t *newName,
uint8_t *udfName,
411 int index, newIndex = 0, needsCRC = 0;
412 int extIndex = 0, newExtIndex = 0, hasExt = 0;
413 unsigned short valueCRC;
415 const uint8_t hexChar[] =
"0123456789ABCDEF";
417 if (udfName[0] ==
'.' &&
418 (udfLen == 1 || (udfLen == 2 && udfName[1] ==
'.'))) {
421 memcpy(newName, udfName, udfLen);
423 for (index = 0; index < udfLen; index++) {
424 curr = udfName[
index];
425 if (curr ==
'/' || curr == 0) {
428 while (index + 1 < udfLen &&
429 (udfName[index + 1] ==
'/' ||
430 udfName[index + 1] == 0))
435 if (udfLen == index + 1)
440 newExtIndex = newIndex;
444 newName[newIndex++] =
curr;
451 int localExtIndex = 0;
456 index <
EXT_SIZE && extIndex + index + 1 < udfLen;
458 curr = udfName[extIndex + index + 1];
460 if (curr ==
'/' || curr == 0) {
463 while (extIndex + index + 2 < udfLen &&
465 (udfName[extIndex + index + 2] ==
'/' ||
466 udfName[extIndex + index + 2] == 0)))
469 ext[localExtIndex++] =
curr;
471 maxFilenameLen = 250 - localExtIndex;
472 if (newIndex > maxFilenameLen)
473 newIndex = maxFilenameLen;
475 newIndex = newExtIndex;
476 }
else if (newIndex > 250)
479 valueCRC =
crc_itu_t(0, fidName, fidNameLen);
480 newName[newIndex++] = hexChar[(valueCRC & 0xf000) >> 12];
481 newName[newIndex++] = hexChar[(valueCRC & 0x0f00) >> 8];
482 newName[newIndex++] = hexChar[(valueCRC & 0x00f0) >> 4];
483 newName[newIndex++] = hexChar[(valueCRC & 0x000f)];
487 for (index = 0; index < localExtIndex; index++)
488 newName[newIndex++] = ext[index];