diff -Naur libdvdnav.orig/src/vm/vm.c libdvdnav/src/vm/vm.c --- libdvdnav.orig/src/vm/vm.c 2009-10-29 09:10:44.836643320 -0700 +++ libdvdnav/src/vm/vm.c 2009-11-27 11:32:47.475322754 -0800 @@ -585,6 +585,9 @@ switch(menuid) { case DVD_MENU_Title: case DVD_MENU_Escape: + if(vm->vmgi == NULL || vm->vmgi->pgci_ut == NULL) { + goto fail; + } (vm->state).domain = VMGM_DOMAIN; break; case DVD_MENU_Root: @@ -592,6 +595,9 @@ case DVD_MENU_Audio: case DVD_MENU_Angle: case DVD_MENU_Part: + if(vm->vtsi == NULL || vm->vtsi->pgci_ut == NULL) { + goto fail; + } (vm->state).domain = VTSM_DOMAIN; break; } @@ -606,6 +612,7 @@ break; } +fail: return 0; } @@ -1412,8 +1419,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 */ @@ -1458,8 +1466,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 */ @@ -1469,8 +1478,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: @@ -1488,6 +1498,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); @@ -1504,14 +1518,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 { @@ -1533,6 +1555,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); @@ -1552,6 +1578,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)) @@ -1563,6 +1593,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)) @@ -1574,6 +1608,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)) @@ -1634,7 +1672,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? */