Mercurial > libdvdnav.hg
changeset 412:34e632fb6a39 src
Prevent abort if a menu doesn't exist.
From John Stebbins original email on the patch:
This patch prevents an abort when a nav command tries to send you to a
menu that doesn't exist. Mac the ripper's feature title extraction
removes menus from the resulting image, but does not remove navigation
instructions that attempt to jump to those menus. This patch checks that
a menu exists before acting on such instructions. If the menu does not
exist, it puts the vm into the stopped state.
Thanks goes to John Stebbins for the original send of this patch and
noticing that I introduced a bug when attempting to streamline this
patch. Finally, he has guided this patch and many more for an
extended period of time. Thanks again John.
author | erik |
---|---|
date | Sun, 21 Nov 2010 23:59:43 +0000 |
parents | ce9b314b6e43 |
children | f30f443d3841 |
files | vm/vm.c |
diffstat | 1 files changed, 48 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/vm/vm.c Fri Jul 30 23:34:24 2010 +0000 +++ b/vm/vm.c Sun Nov 21 23:59:43 2010 +0000 @@ -609,6 +609,9 @@ switch(menuid) { case DVD_MENU_Title: case DVD_MENU_Escape: + if(vm->vmgi == NULL || vm->vmgi->pgci_ut == NULL) { + return 0; + } (vm->state).domain = VMGM_DOMAIN; break; case DVD_MENU_Root: @@ -616,12 +619,13 @@ case DVD_MENU_Audio: case DVD_MENU_Angle: case DVD_MENU_Part: + if(vm->vtsi == NULL || vm->vtsi->pgci_ut == NULL) { + return 0; + } (vm->state).domain = VTSM_DOMAIN; break; } - if(vm->vmgi == NULL || vm->vmgi->pgci_ut == NULL) - return 0; - else if(get_PGCIT(vm) && set_MENU(vm, menuid)) { + if(get_PGCIT(vm) && set_MENU(vm, menuid)) { process_command(vm, play_PGC(vm)); return 1; /* Jump */ } else { @@ -1437,8 +1441,9 @@ if(link_values.data2 != 0) (vm->state).HL_BTNN_REG = link_values.data2 << 10; if(!set_VTS_PTT(vm, (vm->state).vtsN, (vm->state).VTS_TTN_REG, link_values.data1)) - assert(0); - link_values = play_PG(vm); + link_values.command = Exit; + else + link_values = play_PG(vm); break; case LinkPGN: /* Link to Program Number:data1 */ @@ -1483,8 +1488,9 @@ /* Set SPRM1 and SPRM2 */ assert((vm->state).domain == VTSM_DOMAIN || (vm->state).domain == VTS_DOMAIN); /* ?? */ if(!set_VTS_TT(vm, (vm->state).vtsN, link_values.data1)) - assert(0); - link_values = play_PGC(vm); + link_values.command = Exit; + else + link_values = play_PGC(vm); break; case JumpVTS_PTT: /* Jump to Part:data2 of Title:data1 in same VTS Title Domain */ @@ -1494,8 +1500,9 @@ /* Set SPRM1 and SPRM2 */ assert((vm->state).domain == VTSM_DOMAIN || (vm->state).domain == VTS_DOMAIN); /* ?? */ if(!set_VTS_PTT(vm, (vm->state).vtsN, link_values.data1, link_values.data2)) - assert(0); - link_values = play_PGC_PG(vm, (vm->state).pgN); + link_values.command = Exit; + else + link_values = play_PGC_PG(vm, (vm->state).pgN); break; case JumpSS_FP: @@ -1513,6 +1520,10 @@ /* Allowed from anywhere except the VTS Title domain */ /* Stop SPRM9 Timer and any GPRM counters */ assert((vm->state).domain != VTS_DOMAIN); /* ?? */ + if(vm->vmgi == NULL || vm->vmgi->pgci_ut == NULL) { + link_values.command = Exit; + break; + } (vm->state).domain = VMGM_DOMAIN; if(!set_MENU(vm, link_values.data1)) assert(0); @@ -1529,14 +1540,22 @@ if (link_values.data1 != (vm->state).vtsN) { /* the normal case */ assert((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == FP_DOMAIN); /* ?? */ - (vm->state).domain = VTSM_DOMAIN; if (!ifoOpenNewVTSI(vm, vm->dvd, link_values.data1)) /* Also sets (vm->state).vtsN */ assert(0); + if(vm->vtsi == NULL || vm->vtsi->pgci_ut == NULL) { + link_values.command = Exit; + break; + } + (vm->state).domain = VTSM_DOMAIN; } else { /* This happens on some discs like "Captain Scarlet & the Mysterons" or * the German RC2 of "Anatomie" in VTSM. */ assert((vm->state).domain == VTSM_DOMAIN || (vm->state).domain == VMGM_DOMAIN || (vm->state).domain == FP_DOMAIN); /* ?? */ + if(vm->vtsi == NULL || vm->vtsi->pgci_ut == NULL) { + link_values.command = Exit; + break; + } (vm->state).domain = VTSM_DOMAIN; } } else { @@ -1558,6 +1577,10 @@ /* set_PGCN:data1 */ /* Stop SPRM9 Timer and any GPRM counters */ assert((vm->state).domain != VTS_DOMAIN); /* ?? */ + if(vm->vmgi == NULL || vm->vmgi->pgci_ut == NULL) { + link_values.command = Exit; + break; + } (vm->state).domain = VMGM_DOMAIN; if(!set_PGCN(vm, link_values.data1)) assert(0); @@ -1577,6 +1600,10 @@ /* set_RSMinfo:data2 */ assert((vm->state).domain == VTS_DOMAIN); /* ?? */ /* Must be called before domain is changed */ + if(vm->vmgi == NULL || vm->vmgi->pgci_ut == NULL) { + link_values.command = Exit; + break; + } set_RSMinfo(vm, link_values.data2, /* We dont have block info */ 0); (vm->state).domain = VMGM_DOMAIN; if(!set_MENU(vm, link_values.data1)) @@ -1588,6 +1615,10 @@ /* set_RSMinfo:data2 */ assert((vm->state).domain == VTS_DOMAIN); /* ?? */ /* Must be called before domain is changed */ + if(vm->vtsi == NULL || vm->vtsi->pgci_ut == NULL) { + link_values.command = Exit; + break; + } set_RSMinfo(vm, link_values.data2, /* We dont have block info */ 0); (vm->state).domain = VTSM_DOMAIN; if(!set_MENU(vm, link_values.data1)) @@ -1599,6 +1630,10 @@ /* set_RSMinfo:data2 */ assert((vm->state).domain == VTS_DOMAIN); /* ?? */ /* Must be called before domain is changed */ + if(vm->vmgi == NULL || vm->vmgi->pgci_ut == NULL) { + link_values.command = Exit; + break; + } set_RSMinfo(vm, link_values.data2, /* We dont have block info */ 0); (vm->state).domain = VMGM_DOMAIN; if(!set_PGCN(vm, link_values.data1)) @@ -1659,7 +1694,9 @@ (vm->state).TT_PGCN_REG = pgcN; (vm->state).PTTN_REG = part; (vm->state).TTN_REG = get_TT(vm, vtsN, vts_ttn); - assert( (vm->state.TTN_REG) != 0 ); + if( (vm->state.TTN_REG) == 0 ) + return 0; + (vm->state).VTS_TTN_REG = vts_ttn; (vm->state).vtsN = vtsN; /* Not sure about this one. We can get to it easily from TTN_REG */ /* Any other registers? */