From 70bb1e9702befcd403ebaa9c382d5755670ca4d6 Mon Sep 17 00:00:00 2001
From: John Stebbins <jstebbins.hb@gmail.com>
Date: Mon, 19 Sep 2011 15:16:51 -0700
Subject: [PATCH] Change how MSB of UTF-16 string is interpreted

Some new discs are using UTF-16 strings that have junk in the MSB. So
when translated by libdvdread, the result is filenames like
VIDEO_TS.IFO. These bogus files contain bad data.
---
 libdvdread/src/dvd_udf.c |   33 ++++++++++++++++++++++-----------
 1 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/libdvdread/src/dvd_udf.c b/libdvdread/src/dvd_udf.c
index 8fa8973..50957af 100644
--- a/libdvdread/src/dvd_udf.c
+++ b/libdvdread/src/dvd_udf.c
@@ -328,17 +328,25 @@ static int SetUDFCache(dvd_reader_t *device, UDFCacheType type,
 
 static int Unicodedecode( uint8_t *data, int len, char *target )
 {
-  int p = 1, i = 0;
-
-  if( ( data[ 0 ] == 8 ) || ( data[ 0 ] == 16 ) ) do {
-    if( data[ 0 ] == 16 ) p++;  /* Ignore MSB of unicode16 */
-    if( p < len ) {
-      target[ i++ ] = data[ p++ ];
+  int r = 0;
+  len--;
+  
+  if (data[0] == 8) {
+    memcpy(target, &data[1], len);
+    r = 1;
+  } else if (data[0] == 16) {
+    int i;
+
+    r = 1;
+    for (i = 0; i < len; i++) {
+      target[i] = data[i*2+2];
+      if (data[i*2 + 1] != 0)
+        r = 0; /* unicode string that cannot be converted to 8bit w/o loss */
     }
-  } while( p < len );
-
-  target[ i ] = '\0';
-  return 0;
+  }
+  target[len] = '\0';
+  
+  return r;
 }
 
 static int UDFDescriptor( uint8_t *data, uint16_t *TagID )
@@ -490,7 +498,10 @@ static int UDFFileIdentifier( uint8_t *data, uint8_t *FileCharacteristics,
   L_FI = GETN1(19);
   UDFLongAD(&data[20], FileICB);
   L_IU = GETN2(36);
-  if (L_FI) Unicodedecode(&data[38 + L_IU], L_FI, FileName);
+  if (L_FI) {
+    if (!Unicodedecode(&data[38 + L_IU], L_FI, FileName))
+      FileName[0] = '\0';
+  }
   else FileName[0] = '\0';
   return 4 * ((38 + L_FI + L_IU + 3) / 4);
 }
-- 
1.7.4.4

