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? */
