[libdvdcss-devel] Patches for libdvdcss

Evgeny Grin karlson2k at kodi.tv
Mon Nov 17 21:42:43 CET 2014


Hi!

While working on Kodi/XBMC project, I discovered two bugs in libdvdcss.
First is broken positioning after partial read in libc_read()
Second is insufficient support for partial read in libc_read(). If libdvdnav/libdvdread are used without libdvdcss then libdvdread use local function for reading file_read() which is correctly handle partial reading by read() (according to POSIX, it allowed to return smaller amount of data): http://git.videolan.org/?p=libdvdread.git;a=blob;f=src/dvd_input.c;h=da4803ef91d147ac318c554a7367aee84dbfb76a;hb=HEAD#l225 .
If libdvdnav/libdvdread are used with libdvdcss then partial reading in libc_read() produce DVD read error (actually discovered on .ISO and .IFO file reading)
Here are the patches (made for 1.2.13, but applicable for latest git master):

diff --git a/lib/libdvd/libdvdcss/src/device.c b/lib/libdvd/libdvdcss/src/device.c
index 2395ab5..3de1879 100644
--- a/lib/libdvd/libdvdcss/src/device.c
+++ b/lib/libdvd/libdvdcss/src/device.c
@@ -828,10 +828,11 @@ static int libc_read ( dvdcss_t dvdcss, void *p_buffer, int i_blocks )
     /* Handle partial reads */
     if( i_ret != i_size )
     {
-        int i_seek;
+        int i_seek, i_set_pos;
 
+        i_set_pos = dvdcss->i_pos + i_ret / DVDCSS_BLOCK_SIZE;
         dvdcss->i_pos = -1;
-        i_seek = libc_seek( dvdcss, i_ret / DVDCSS_BLOCK_SIZE );
+        i_seek = libc_seek( dvdcss, i_set_pos );
         if( i_seek < 0 )
         {
             return i_seek;


diff --git a/lib/libdvd/libdvdcss/src/device.c b/lib/libdvd/libdvdcss/src/device.c
index 3de1879..53d1fdf 100644
--- a/lib/libdvd/libdvdcss/src/device.c
+++ b/lib/libdvd/libdvdcss/src/device.c
@@ -816,13 +816,21 @@ static int libc_read ( dvdcss_t dvdcss, void *p_buffer, int i_blocks )
     off_t i_size, i_ret;
 
     i_size = (off_t)i_blocks * (off_t)DVDCSS_BLOCK_SIZE;
-    i_ret = read( dvdcss->i_read_fd, p_buffer, i_size );
-
-    if( i_ret < 0 )
+    i_ret = 0;
+    while( i_ret < i_size )
     {
-        print_error( dvdcss, "read error" );
-        dvdcss->i_pos = -1;
-        return i_ret;
+        off_t i_r;
+        i_r = read( dvdcss->i_read_fd, ((char*)p_buffer) + i_ret, i_size - i_ret );
+        if( i_r < 0 )
+        {
+            print_error(dvdcss, "read error");
+            dvdcss->i_pos = -1;
+            return i_r;
+        }
+        if( i_r == 0 )
+            break;
+
+        i_ret += i_r;
     }
 
     /* Handle partial reads */


They should fix hardly reproducible errors (seems that partial read in read() occurs relatively rare).
Patches are tested and merged in Kodi master.


-- 
Best Wishes,
Evgeny Grin


More information about the libdvdcss-devel mailing list