changed handling of forbidden world writes - they are now only a
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 16 Oct 2009 15:07:57 +0000 (15:07 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 16 Oct 2009 15:07:57 +0000 (15:07 +0000)
warning, and still perform the actual write, additionally the check has
been moved from OP_ADDRESS to OP_STOREP_* and now prints what field is
being written
changed the nature of pointer fields (which are only written by
OP_ADDRESS and read by OP_STOREP_*) to use an index (like field offsets)
instead of a byte offset, this made it a little easier to print the
field offset on world write warnings

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9339 d7cf8633-e32d-0410-b094-e92efae38249

prvm_exec.c
prvm_execprogram.h

index a4f529c..f32ff3f 100644 (file)
@@ -112,6 +112,7 @@ char *prvm_opnames[] =
 
 char *PRVM_GlobalString (int ofs);
 char *PRVM_GlobalStringNoContents (int ofs);
+extern ddef_t *PRVM_ED_FieldAtOfs(int ofs);
 
 
 //=============================================================================
index 3f59776..ee091f0 100644 (file)
                        case OP_STOREP_S:
                        case OP_STOREP_FNC:             // pointers
 #if PRVMBOUNDSCHECK
-                               if (OPB->_int < 0 || OPB->_int + 4 > prog->edictareasize)
+                               if (OPB->_int < 0 || OPB->_int + 1 > prog->edictareasize)
                                {
                                        prog->xfunction->profile += (st - startst);
                                        prog->xstatement = st - prog->statements;
                                        goto cleanup;
                                }
 #endif
-                               ptr = (prvm_eval_t *)((unsigned char *)prog->edictsfields + OPB->_int);
+                               if (OPB->_int < prog->progs->entityfields && !prog->allowworldwrites)
+                                       Con_DPrintf("WARNING: assignment to world.%s (field %i) in %s\n", PRVM_GetString(PRVM_ED_FieldAtOfs(OPB->_int)->s_name), OPB->_int, PRVM_NAME);
+                               ptr = (prvm_eval_t *)((float *)prog->edictsfields + OPB->_int);
                                ptr->_int = OPA->_int;
                                break;
                        case OP_STOREP_V:
 #if PRVMBOUNDSCHECK
-                               if (OPB->_int < 0 || OPB->_int + 12 > prog->edictareasize)
+                               if (OPB->_int < 0 || OPB->_int + 3 > prog->edictareasize)
                                {
                                        prog->xfunction->profile += (st - startst);
                                        prog->xstatement = st - prog->statements;
                                        goto cleanup;
                                }
 #endif
-                               ptr = (prvm_eval_t *)((unsigned char *)prog->edictsfields + OPB->_int);
+                               if (OPB->_int < prog->progs->entityfields && !prog->allowworldwrites)
+                                       Con_DPrintf("WARNING: assignment to world.%s (field %i) in %s\n", PRVM_GetString(PRVM_ED_FieldAtOfs(OPB->_int)->s_name), OPB->_int, PRVM_NAME);
+                               ptr = (prvm_eval_t *)((float *)prog->edictsfields + OPB->_int);
                                ptr->ivector[0] = OPA->ivector[0];
                                ptr->ivector[1] = OPA->ivector[1];
                                ptr->ivector[2] = OPA->ivector[2];
                                        goto cleanup;
                                }
 #endif
+#if 0
                                if (OPA->edict == 0 && !prog->allowworldwrites)
                                {
                                        prog->xfunction->profile += (st - startst);
                                        PRVM_ERROR("forbidden assignment to null/world entity in %s", PRVM_NAME);
                                        goto cleanup;
                                }
+#endif
                                ed = PRVM_PROG_TO_EDICT(OPA->edict);
-                               OPC->_int = (unsigned char *)((int *)ed->fields.vp + OPB->_int) - (unsigned char *)prog->edictsfields;
+                               OPC->_int = (float *)((float *)ed->fields.vp + OPB->_int) - (float *)prog->edictsfields;
                                break;
 
                        case OP_LOAD_F: