[libdvdnav-devel] [Git][videolan/libdvdread][master] 8 commits: dvd_reader: fix partial-block size accounting

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Wed Apr 1 17:56:27 UTC 2026



Jean-Baptiste Kempf pushed to branch master at VideoLAN / libdvdread


Commits:
b6e81ceb by Saifelden Mohamed Ismail at 2026-04-01T19:49:59+02:00
dvd_reader: fix partial-block size accounting

- - - - -
6d5cc320 by Saifelden Mohamed Ismail at 2026-04-01T19:49:59+02:00
dvd-vr: handle missing RTAV_VMGI safely

- - - - -
0ac90cdc by Saifelden Mohamed Ismail at 2026-04-01T19:49:59+02:00
dvd-vr: allow title index zero

- - - - -
12d400db by Saifelden Mohamed Ismail at 2026-04-01T19:49:59+02:00
dvd-vr: return ifo handle on success

- - - - -
b7636607 by Saifelden Mohamed Ismail at 2026-04-01T19:49:59+02:00
dvd-vr: remove false zero padding VR_MANGR

- - - - -
442d90b5 by Saifelden Mohamed Ismail at 2026-04-01T19:49:59+02:00
dvd-vr: fix faulty zero check

- - - - -
8b6da123 by Saifelden Mohamed Ismail at 2026-04-01T19:49:59+02:00
ifo_read: remove unreachable ifop->file check

- - - - -
e4d9a039 by Saifelden Mohamed Ismail at 2026-04-01T19:49:59+02:00
dvd-vr: fail on undefined pgc_gi

- - - - -


3 changed files:

- src/dvd_reader.c
- src/dvdread/ifo_types.h
- src/ifo_read.c


Changes:

=====================================
src/dvd_reader.c
=====================================
@@ -58,6 +58,9 @@
 #include "md5.h"
 #include "dvdread/ifo_read.h"
 
+#define BYTES_TO_DVD_BLOCKS_CEIL(bytes) \
+  (((uint64_t)(bytes) + DVD_VIDEO_LB_LEN - 1) / DVD_VIDEO_LB_LEN)
+
 #if defined(_WIN32)
 # include <windows.h>
 # include "msvc/contrib/win32_cs.h"
@@ -464,6 +467,12 @@ static int cpxm_init_condition( dvd_reader_t* ctx, dvd_type_t type, int have_css
   } else if ( type == DVD_VR && have_css ) {
     /* open ifo to supply decryption context */
     ifo_handle_t* ifo = ifoOpen( ctx, 0 );
+    if( !ifo )
+      return 0;
+    if( !ifo->rtav_vmgi ) {
+      ifoClose(ifo);
+      return 0;
+    }
     rtav_vmgi_t* rtav_vmgi = ifo->rtav_vmgi;
     /* pass the cprm title key to libdvdcss for decryption */
     int ret = dvdinput_init( ctx->rd->dev, rtav_vmgi->cprm_info.title_key );
@@ -900,14 +909,15 @@ static dvd_file_t *DVDOpenFileUDF( dvd_reader_t *ctx, const char *filename,
   }
   dvd_file->ctx = ctx;
   dvd_file->lb_start = start;
-  dvd_file->filesize = len / DVD_VIDEO_LB_LEN;
+  dvd_file->filesize = BYTES_TO_DVD_BLOCKS_CEIL(len);
 
   /* Read the whole file in cache (unencrypted) if asked and if it doesn't
    * exceed 128KB */
   if( do_cache && len < 64 * DVD_VIDEO_LB_LEN ) {
     int ret;
+    size_t cache_bytes = (size_t)dvd_file->filesize * DVD_VIDEO_LB_LEN;
 
-    dvd_file->cache = malloc( len );
+    dvd_file->cache = malloc( cache_bytes );
     if( !dvd_file->cache )
         return dvd_file;
 
@@ -1034,7 +1044,7 @@ static dvd_file_t *DVDOpenFilePath( dvd_reader_t *ctx, const char *filename )
     dvdinput_close( dev );
     return NULL;
   }
-  dvd_file->title_sizes[ 0 ] = fileinfo.st_size / DVD_VIDEO_LB_LEN;
+  dvd_file->title_sizes[ 0 ] = BYTES_TO_DVD_BLOCKS_CEIL(fileinfo.st_size);
   dvd_file->title_devs[ 0 ] = dev;
   dvd_file->filesize = dvd_file->title_sizes[ 0 ];
 
@@ -1134,7 +1144,7 @@ static dvd_file_t *DVDOpenVOBUDF( dvd_reader_t *ctx, int title, int menu )
       /*Hack*/ dvd_file->css_title = title << 1 | menu;
 
   dvd_file->lb_start = start;
-  dvd_file->filesize = len / DVD_VIDEO_LB_LEN;
+  dvd_file->filesize = BYTES_TO_DVD_BLOCKS_CEIL(len);
 
   /* Calculate the complete file size for every file in the VOBS, AOBS */
   /* DVD-VR uses UDF 2.0 which allows for larger file sizes, 1GB limit does not exist */
@@ -1145,7 +1155,7 @@ static dvd_file_t *DVDOpenVOBUDF( dvd_reader_t *ctx, int title, int menu )
       sprintf( filename, "/%s_TS/%cTS_%02d_%d.%cOB", DVD_TYPE_STRING( ctx->dvd_type ), 
               STREAM_TYPE_STRING( ctx->dvd_type ), title, cur, STREAM_TYPE_STRING( ctx->dvd_type ) );
       if( !UDFFindFile( ctx, filename, &len ) ) break;
-      dvd_file->filesize += len / DVD_VIDEO_LB_LEN;
+      dvd_file->filesize += BYTES_TO_DVD_BLOCKS_CEIL(len);
     }
   }
 
@@ -1222,7 +1232,7 @@ static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *ctx, int title, int menu )
       free( dvd_file );
       return NULL;
     }
-    dvd_file->title_sizes[ 0 ] = fileinfo.st_size / DVD_VIDEO_LB_LEN;
+    dvd_file->title_sizes[ 0 ] = BYTES_TO_DVD_BLOCKS_CEIL(fileinfo.st_size);
     dvd_file->title_devs[ 0 ] = dev;
     dvdinput_title( dvd_file->title_devs[0], 0);
     dvd_file->filesize = dvd_file->title_sizes[ 0 ];
@@ -1245,7 +1255,7 @@ static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *ctx, int title, int menu )
         return NULL;
       }
 
-      dvd_file->title_sizes[ 0 ] = fileinfo.st_size / DVD_VIDEO_LB_LEN;
+      dvd_file->title_sizes[ 0 ] = BYTES_TO_DVD_BLOCKS_CEIL(fileinfo.st_size);
       dvd_file->title_devs[ 0 ] = dvdinput_open( ctx->priv, &ctx->logcb, full_path, NULL );
 
       if( !dvd_file->title_devs[ 0 ] ) {
@@ -1278,7 +1288,7 @@ static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *ctx, int title, int menu )
           break;
         }
 
-        dvd_file->title_sizes[ i ] = fileinfo.st_size / DVD_VIDEO_LB_LEN;
+        dvd_file->title_sizes[ i ] = BYTES_TO_DVD_BLOCKS_CEIL(fileinfo.st_size);
         dvd_file->title_devs[ i ] = dvdinput_open( ctx->priv, &ctx->logcb, full_path, NULL );
         /* setting type of stream will determine what decryption to use */
         dvdinput_set_stream( dvd_file->title_devs[ i ], stream_type );
@@ -1355,7 +1365,7 @@ dvd_file_t *DVDOpenFile( dvd_reader_t *ctx, int titlenum,
     }
     break;
   case DVD_READ_TITLE_VOBS:
-    if( titlenum == 0 ) return NULL;
+    if( titlenum == 0 && ctx->dvd_type != DVD_VR ) return NULL;
     if( dvd->isImageFile ) {
       return DVDOpenVOBUDF( ctx, titlenum, 0 );
     } else {


=====================================
src/dvdread/ifo_types.h
=====================================
@@ -1125,7 +1125,7 @@ typedef struct {
   /* 256 */
   uint32_t org_pgci_sa;    /* original program chain start address */
   uint32_t org_pgci_ea;    /* end address for the org_pgci */
-  uint8_t  zero_264[7];
+  uint8_t  unknown_264[7];
   cprm_info_t cprm_info;
   uint8_t  zero_280[24];
   /* 304 */


=====================================
src/ifo_read.c
=====================================
@@ -423,12 +423,6 @@ static ifo_handle_t *ifoOpenFileOrBackup(dvd_reader_t *ctx, int title,
   else
     snprintf(ifo_filename, 13, "%s_TS.%s", DVD_TYPE_STRING( ctx->dvd_type ), backup ? "BUP" : "IFO" );
 
-  if(!ifop->file) {
-    Log1(ctx, "Can't open file %s.", ifo_filename);
-    free(ifop);
-    return NULL;
-  }
- 
   ifo_handle_t *ifofile = &ifop->handle;
   /* First check if this is a VMGI file. */
   if(ifoRead_VMG(ifofile)) {
@@ -519,6 +513,10 @@ static ifo_handle_t *ifoOpenFileOrBackup(dvd_reader_t *ctx, int title,
     if(!ifoRead_PGC_GI(ifofile))
       goto ifoOpen_fail;
 
+    if(!ifofile->pgc_gi)
+      goto ifoOpen_fail;
+
+    return ifofile;
   }
 
 ifoOpen_fail:
@@ -1372,7 +1370,6 @@ static int ifoRead_RTAV_VMGI(ifo_handle_t *ifofile) {
   CHECK_ZERO(ifofile->rtav_vmgi->zero_16);
   CHECK_ZERO(ifofile->rtav_vmgi->zero_34);
   CHECK_ZERO(ifofile->rtav_vmgi->zero_226);
-  CHECK_ZERO(ifofile->rtav_vmgi->zero_264);
   CHECK_ZERO(ifofile->rtav_vmgi->zero_280);
   CHECK_ZERO(ifofile->rtav_vmgi->zero_320);
   CHECK_ZERO(ifofile->rtav_vmgi->zero_360);



View it on GitLab: https://code.videolan.org/videolan/libdvdread/-/compare/a66aec4dd722dbfed0be3e26eb36270cea5d2df6...e4d9a039d300069e61918b5ec58322c1b5ba8663

-- 
View it on GitLab: https://code.videolan.org/videolan/libdvdread/-/compare/a66aec4dd722dbfed0be3e26eb36270cea5d2df6...e4d9a039d300069e61918b5ec58322c1b5ba8663
You're receiving this email because of your account on code.videolan.org.




More information about the libdvdnav-devel mailing list