The following diff backports various fixes for libdvdread for issues which result in crashing or issues with playback with certain DVDs.
Tested with Xine with a bunch of DVDs on amd64. Index: Makefile =================================================================== RCS file: /home/cvs/ports/devel/libdvdread/Makefile,v retrieving revision 1.20 diff -u -p -r1.20 Makefile --- Makefile 3 May 2012 06:51:07 -0000 1.20 +++ Makefile 26 Sep 2012 00:05:39 -0000 @@ -5,6 +5,7 @@ SHARED_ONLY = Yes COMMENT = accessing DVD files DISTNAME = libdvdread-4.2.0 +REVISION = 0 CATEGORIES = devel MASTER_SITES = ${HOMEPAGE}releases/ EXTRACT_SUFX = .tar.bz2 Index: patches/patch-src_dvd_reader_c =================================================================== RCS file: patches/patch-src_dvd_reader_c diff -N patches/patch-src_dvd_reader_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-src_dvd_reader_c 26 Sep 2012 00:43:04 -0000 @@ -0,0 +1,14 @@ +$OpenBSD$ + +Make sure the input device is closed on failure + +--- src/dvd_reader.c.orig Tue Sep 25 20:32:26 2012 ++++ src/dvd_reader.c Tue Sep 25 20:33:12 2012 +@@ -716,6 +716,7 @@ static dvd_file_t *DVDOpenFilePath( dvd_reader_t *dvd, + if( stat( full_path, &fileinfo ) < 0 ) { + fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename ); + free( dvd_file ); ++ dvdinput_close( dev ); + return NULL; + } + dvd_file->title_sizes[ 0 ] = fileinfo.st_size / DVD_VIDEO_LB_LEN; Index: patches/patch-src_dvd_udf_c =================================================================== RCS file: patches/patch-src_dvd_udf_c diff -N patches/patch-src_dvd_udf_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-src_dvd_udf_c 26 Sep 2012 00:43:59 -0000 @@ -0,0 +1,16 @@ +$OpenBSD$ + +Check the return value for potential errors + +--- src/dvd_udf.c.orig Tue Sep 25 20:34:13 2012 ++++ src/dvd_udf.c Tue Sep 25 20:36:25 2012 +@@ -611,7 +611,8 @@ static int UDFScanDir( dvd_reader_t *device, struct AD + memcpy(FileICB, &tmpICB, sizeof(tmpICB)); + found = 1; + } +- UDFMapICB(device, tmpICB, &tmpFiletype, partition, &tmpFile); ++ if(!UDFMapICB(device, tmpICB, &tmpFiletype, partition, &tmpFile)) ++ return 0; + } else { + if( !strcasecmp( FileName, filename ) ) { + memcpy(FileICB, &tmpICB, sizeof(tmpICB)); Index: patches/patch-src_ifo_read_c =================================================================== RCS file: patches/patch-src_ifo_read_c diff -N patches/patch-src_ifo_read_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-src_ifo_read_c 26 Sep 2012 00:55:50 -0000 @@ -0,0 +1,92 @@ +$OpenBSD$ + +- Clear pf_temp to make sure it is initialized +- Check ifoRead_VTS before continuing +- Use NULL instead of 0 +- Sanitize PTT start offsets +- Add libdvdread prefix to the error message +- Change the message output to match the severity of the condition +- Fix out of array pointer access + +--- src/ifo_read.c.orig Tue Sep 25 20:38:45 2012 ++++ src/ifo_read.c Tue Sep 25 20:39:34 2012 +@@ -475,8 +475,7 @@ ifo_handle_t *ifoOpenVTSI(dvd_reader_t *dvd, int title + return NULL; + } + +- ifoRead_VTS(ifofile); +- if(ifofile->vtsi_mat) ++ if(ifoRead_VTS(ifofile) && ifofile->vtsi_mat) + return ifofile; + + fprintf(stderr, "libdvdread: Invalid IFO for title %d (VTS_%02d_0.IFO).\n", +@@ -620,19 +619,19 @@ static int ifoRead_VTS(ifo_handle_t *ifofile) { + + if(!DVDFileSeek_(ifofile->file, 0)) { + free(ifofile->vtsi_mat); +- ifofile->vtsi_mat = 0; ++ ifofile->vtsi_mat = NULL; + return 0; + } + + if(!(DVDReadBytes(ifofile->file, vtsi_mat, sizeof(vtsi_mat_t)))) { + free(ifofile->vtsi_mat); +- ifofile->vtsi_mat = 0; ++ ifofile->vtsi_mat = NULL; + return 0; + } + + if(strncmp("DVDVIDEO-VTS", vtsi_mat->vts_identifier, 12) != 0) { + free(ifofile->vtsi_mat); +- ifofile->vtsi_mat = 0; ++ ifofile->vtsi_mat = NULL; + return 0; + } + +@@ -1082,6 +1081,12 @@ int ifoRead_TT_SRPT(ifo_handle_t *ifofile) { + return 0; + } + ++ if(tt_srpt->nr_of_srpts>info_length/sizeof(title_info_t)){ ++ fprintf(stderr,"libdvdread: data mismatch: info_length (%ld)!= nr_of_srpts (%d). Truncating.\n", ++ info_length/sizeof(title_info_t),tt_srpt->nr_of_srpts); ++ tt_srpt->nr_of_srpts=info_length/sizeof(title_info_t); ++ } ++ + for(i = 0; i < tt_srpt->nr_of_srpts; i++) { + B2N_16(tt_srpt->title[i].nr_of_ptts); + B2N_16(tt_srpt->title[i].parental_id); +@@ -1190,7 +1195,15 @@ int ifoRead_VTS_PTT_SRPT(ifo_handle_t *ifofile) { + goto fail; + } + for(i = 0; i < vts_ptt_srpt->nr_of_srpts; i++) { +- B2N_32(data[i]); ++ /* Transformers 3 has PTT start bytes that point outside the SRPT PTT */ ++ uint32_t start = data[i]; ++ B2N_32(start); ++ if(start + sizeof(ptt_info_t) > vts_ptt_srpt->last_byte + 1) { ++ /* don't mess with any bytes beyond the end of the allocation */ ++ vts_ptt_srpt->nr_of_srpts = i; ++ break; ++ } ++ data[i] = start; + /* assert(data[i] + sizeof(ptt_info_t) <= vts_ptt_srpt->last_byte + 1); + Magic Knight Rayearth Daybreak is mastered very strange and has + Titles with 0 PTTs. They all have a data[i] offsets beyond the end of +@@ -1372,6 +1385,7 @@ int ifoRead_PTL_MAIT(ifo_handle_t *ifofile) { + ifofile->ptl_mait = NULL; + return 0; + } ++ memset(pf_temp, 0, info_length); + if(!(DVDReadBytes(ifofile->file, pf_temp, info_length))) { + fprintf(stderr, "libdvdread: Unable to read PTL_MAIT table at index %d.\n",i); + free(pf_temp); +@@ -1434,7 +1448,7 @@ int ifoRead_VTS_TMAPT(ifo_handle_t *ifofile) { + + if(ifofile->vtsi_mat->vts_tmapt == 0) { /* optional(?) */ + ifofile->vts_tmapt = NULL; +- fprintf(stderr,"Please send bug report - no VTS_TMAPT ?? \n"); ++ fprintf(stderr,"libdvdread: No VTS_TMAPT available - skipping.\n"); + return 1; + } + -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.