summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThilo Schulz <arny@ats.s.bawue.de>2011-09-27 21:49:01 +0000
committerTim Angus <tim@ngus.net>2013-01-10 23:38:29 +0000
commite9d0af975a62f645d0ff3b29d49670f176b57918 (patch)
tree2de72004ec73125efd973e9b38b7b0a944e477e8
parent73d0e34b848459ed8f0221553fd4661360e489dd (diff)
Add some checks when reloading QVMs via VM_Restart()
-rw-r--r--src/qcommon/vm.c57
1 files changed, 43 insertions, 14 deletions
diff --git a/src/qcommon/vm.c b/src/qcommon/vm.c
index 7baf9321..90af748f 100644
--- a/src/qcommon/vm.c
+++ b/src/qcommon/vm.c
@@ -448,13 +448,26 @@ vmHeader_t *VM_LoadQVM( vm_t *vm, qboolean alloc ) {
}
dataLength = 1 << i;
- if( alloc ) {
+ if(alloc)
+ {
// allocate zero filled space for initialized and uninitialized data
- vm->dataBase = Hunk_Alloc( dataLength, h_high );
+ vm->dataBase = Hunk_Alloc(dataLength, h_high);
vm->dataMask = dataLength - 1;
- } else {
- // clear the data
- Com_Memset( vm->dataBase, 0, dataLength );
+ }
+ else
+ {
+ // clear the data, but make sure we're not clearing more than allocated
+ if(vm->dataMask + 1 != dataLength)
+ {
+ VM_Free(vm);
+ FS_FreeFile(header.v);
+
+ Com_Printf(S_COLOR_YELLOW "Warning: Data region size of %s not matching after"
+ "VM_Restart()\n", filename);
+ return NULL;
+ }
+
+ Com_Memset(vm->dataBase, 0, dataLength);
}
// copy the intialized data
@@ -466,18 +479,34 @@ vmHeader_t *VM_LoadQVM( vm_t *vm, qboolean alloc ) {
*(int *)(vm->dataBase + i) = LittleLong( *(int *)(vm->dataBase + i ) );
}
- if( header.h->vmMagic == VM_MAGIC_VER2 ) {
- vm->numJumpTableTargets = header.h->jtrgLength >> 2;
- Com_Printf( "Loading %d jump table targets\n", vm->numJumpTableTargets );
+ if(header.h->vmMagic == VM_MAGIC_VER2)
+ {
+ Com_Printf("Loading %d jump table targets\n", vm->numJumpTableTargets);
- if( alloc ) {
- vm->jumpTableTargets = Hunk_Alloc( header.h->jtrgLength, h_high );
- } else {
- Com_Memset( vm->jumpTableTargets, 0, header.h->jtrgLength );
+ header.h->jtrgLength &= ~0x03;
+
+ if(alloc)
+ {
+ vm->jumpTableTargets = Hunk_Alloc(header.h->jtrgLength, h_high);
+ vm->numJumpTableTargets = header.h->jtrgLength >> 2;
+ }
+ else
+ {
+ if((header.h->jtrgLength >> 2) != vm->numJumpTableTargets)
+ {
+ VM_Free(vm);
+ FS_FreeFile(header.v);
+
+ Com_Printf(S_COLOR_YELLOW "Warning: Jump table size of %s not matching after"
+ "VM_Restart()\n", filename);
+ return NULL;
+ }
+
+ Com_Memset(vm->jumpTableTargets, 0, header.h->jtrgLength);
}
- Com_Memcpy( vm->jumpTableTargets, (byte *)header.h + header.h->dataOffset +
- header.h->dataLength + header.h->litLength, header.h->jtrgLength );
+ Com_Memcpy(vm->jumpTableTargets, (byte *) header.h + header.h->dataOffset +
+ header.h->dataLength + header.h->litLength, header.h->jtrgLength);
// byte swap the longs
for ( i = 0 ; i < header.h->jtrgLength ; i += 4 ) {